Commit 84801c90 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

specs: Move to dedicated repo (#9121)

parent 082d075d
......@@ -665,51 +665,6 @@ jobs:
command: ./ops/scripts/todo-checker.sh --verbose
- notify-failures-on-develop
bedrock-markdown:
machine:
image: <<pipeline.parameters.base_image>>
steps:
- checkout
- check-changed:
patterns: specs/(.*)\.md$
- run:
name: Install pnpm package manager
command: |
npm i pnpm --global
- run:
name: pnpm dev deps
command: pnpm install:ci
- run:
name: specs toc
command: pnpm lint:specs:toc && git diff --exit-code ./specs
- run:
name: markdown lint
command: pnpm lint:specs:check
bedrock-markdown-links:
machine:
image: <<pipeline.parameters.base_image>>
steps:
- checkout
- run:
name: Install pnpm package manager
command: |
npm i pnpm --global
- run:
name: Install node_modules
command: |
pnpm install:ci
- run:
name: Lint check
command: |
pnpm lint:specs:check
- run:
name: link lint
command: |
make bedrock-markdown-links
- notify-failures-on-develop:
channel: C055R639XT9 #notify-link-check
fuzz-golang:
parameters:
package_name:
......@@ -1461,7 +1416,6 @@ workflows:
requires:
- "go-mod-tidy"
- l1-geth-version-check
- bedrock-markdown
- go-lint: # we combine most of the go-lint work for two reasons: (1) warm up the Go build cache, (2) reduce sum of lint time
name: op-stack-go-lint
requires: [ "go-mod-tidy" ]
......@@ -1879,13 +1833,6 @@ workflows:
- slack
- oplabs-fpp-nodes
scheduled-link-check:
when:
equal: [ build_daily, <<pipeline.schedule.name>> ]
jobs:
- bedrock-markdown-links:
context: slack
scheduled-docker-publish:
when:
equal: [ build_hourly, <<pipeline.schedule.name>> ]
......
{
"line_length": {
"line_length": 120,
"strict": false,
"stern": true,
"code_blocks": false,
"tables": false,
},
"no-blanks-blockquote": false,
"single-title": false,
"no-emphasis-as-heading": false,
}
......@@ -17,7 +17,10 @@ In this repository, you'll find numerous core components of the OP Stack, the de
- If you want to build on top of OP Mainnet, refer to the [Optimism Documentation](https://docs.optimism.io)
- If you want to build your own OP Stack based blockchain, refer to the [OP Stack Guide](https://docs.optimism.io/stack/getting-started)
- If you want to contribute to the OP Stack, check out the [Protocol Specs](./specs)
## Specification
If you're interested in the technical details of how Optimism works, refer to the [Optimism Protocol Specification](https://github.com/ethereum-optimism/specs).
## Community
......@@ -62,8 +65,7 @@ The Optimism Immunefi program offers up to $2,000,042 for in-scope critical vuln
│ ├── <a href="./packages/contracts-bedrock">contracts-bedrock</a>: Bedrock smart contracts
│ ├── <a href="./packages/core-utils">core-utils</a>: Low-level utilities that make building Optimism easier
│ └── <a href="./packages/sdk">sdk</a>: provides a set of tools for interacting with Optimism
├── <a href="./proxyd">proxyd</a>: Configurable RPC request router and proxy
└── <a href="./specs">specs</a>: Specs of the rollup starting at the Bedrock upgrade
└── <a href="./proxyd">proxyd</a>: Configurable RPC request router and proxy
</pre>
## Branching Model
......
......@@ -53,7 +53,7 @@
},
"targetDefaults": {
"lint": {
"inputs": ["{workspaceRoot}/.markdownlint.json", "default"]
"inputs": ["default"]
},
"test": {
"inputs": ["default", "testing", "^production"],
......
......@@ -21,9 +21,6 @@
"lint:ts:check": "npx nx run-many --target=lint:ts:check",
"lint:check": "npx nx run-many --target=lint:check",
"lint:fix": "npx nx run-many --target=lint:fix",
"lint:specs:fix": "npx markdownlint-cli2-fix \"./specs/**/*.md\"",
"lint:specs:check": "npx markdownlint-cli2 \"./specs/**/*.md\"",
"lint:specs:toc": "npx doctoc '--title=**Table of Contents**' ./specs",
"preinstall": "npx only-allow pnpm",
"ready": "pnpm lint && pnpm test",
"prepare": "husky install",
......@@ -67,8 +64,6 @@
"eslint-plugin-unicorn": "^50.0.1",
"husky": "^8.0.3",
"lint-staged": "15.2.0",
"markdownlint": "^0.33.0",
"markdownlint-cli2": "0.4.0",
"mocha": "^10.2.0",
"nx": "17.2.8",
"nyc": "^15.1.0",
......
......@@ -84,12 +84,6 @@ importers:
lint-staged:
specifier: 15.2.0
version: 15.2.0
markdownlint:
specifier: ^0.33.0
version: 0.33.0
markdownlint-cli2:
specifier: 0.4.0
version: 0.4.0
mocha:
specifier: ^10.2.0
version: 10.2.0
......@@ -7245,11 +7239,6 @@ packages:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
/array-union@3.0.1:
resolution: {integrity: sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==}
engines: {node: '>=12'}
dev: true
/array.prototype.findlastindex@1.2.3:
resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==}
engines: {node: '>= 0.4'}
......@@ -9106,10 +9095,6 @@ packages:
dependencies:
ansi-colors: 4.1.3
/entities@2.1.0:
resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==}
dev: true
/entities@2.2.0:
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
dev: true
......@@ -10759,18 +10744,6 @@ packages:
merge2: 1.4.1
slash: 3.0.0
/globby@12.1.0:
resolution: {integrity: sha512-YULDaNwsoUZkRy9TWSY/M7Obh0abamTKoKzTfOI3uU+hfpX2FZqOq8LFDxsjYheF1RH7ITdArgbQnsNBFgcdBA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
array-union: 3.0.1
dir-glob: 3.0.1
fast-glob: 3.3.1
ignore: 5.2.4
merge2: 1.4.1
slash: 4.0.0
dev: true
/globby@13.2.2:
resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
......@@ -12409,18 +12382,6 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/linkify-it@3.0.3:
resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==}
dependencies:
uc.micro: 1.0.6
dev: true
/linkify-it@5.0.0:
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
dependencies:
uc.micro: 2.0.0
dev: true
/lint-staged@15.2.0:
resolution: {integrity: sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==}
engines: {node: '>=18.12.0'}
......@@ -12773,81 +12734,12 @@ packages:
engines: {node: '>=8'}
dev: false
/markdown-it@12.3.2:
resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==}
hasBin: true
dependencies:
argparse: 2.0.1
entities: 2.1.0
linkify-it: 3.0.3
mdurl: 1.0.1
uc.micro: 1.0.6
dev: true
/markdown-it@14.0.0:
resolution: {integrity: sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==}
hasBin: true
dependencies:
argparse: 2.0.1
entities: 4.5.0
linkify-it: 5.0.0
mdurl: 2.0.0
punycode.js: 2.3.1
uc.micro: 2.0.0
dev: true
/markdown-table@2.0.0:
resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==}
dependencies:
repeat-string: 1.6.1
dev: true
/markdownlint-cli2-formatter-default@0.0.3(markdownlint-cli2@0.4.0):
resolution: {integrity: sha512-QEAJitT5eqX1SNboOD+SO/LNBpu4P4je8JlR02ug2cLQAqmIhh8IJnSK7AcaHBHhNADqdGydnPpQOpsNcEEqCw==}
peerDependencies:
markdownlint-cli2: '>=0.0.4'
dependencies:
markdownlint-cli2: 0.4.0
dev: true
/markdownlint-cli2@0.4.0:
resolution: {integrity: sha512-EcwP5tAbyzzL3ACI0L16LqbNctmh8wNX56T+aVvIxWyTAkwbYNx2V7IheRkXS3mE7R/pnaApZ/RSXcXuzRVPjg==}
engines: {node: '>=12'}
hasBin: true
dependencies:
globby: 12.1.0
markdownlint: 0.25.1
markdownlint-cli2-formatter-default: 0.0.3(markdownlint-cli2@0.4.0)
markdownlint-rule-helpers: 0.16.0
micromatch: 4.0.4
strip-json-comments: 4.0.0
yaml: 1.10.2
dev: true
/markdownlint-micromark@0.1.8:
resolution: {integrity: sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==}
engines: {node: '>=16'}
dev: true
/markdownlint-rule-helpers@0.16.0:
resolution: {integrity: sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==}
dev: true
/markdownlint@0.25.1:
resolution: {integrity: sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==}
engines: {node: '>=12'}
dependencies:
markdown-it: 12.3.2
dev: true
/markdownlint@0.33.0:
resolution: {integrity: sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==}
engines: {node: '>=18'}
dependencies:
markdown-it: 14.0.0
markdownlint-micromark: 0.1.8
dev: true
/marked@4.3.0:
resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
engines: {node: '>= 12'}
......@@ -12972,14 +12864,6 @@ packages:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
dev: true
/mdurl@1.0.1:
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
dev: true
/mdurl@2.0.0:
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
dev: true
/media-typer@0.3.0:
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
......@@ -13363,14 +13247,6 @@ packages:
- supports-color
dev: true
/micromatch@4.0.4:
resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==}
engines: {node: '>=8.6'}
dependencies:
braces: 3.0.2
picomatch: 2.3.1
dev: true
/micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
......@@ -14818,11 +14694,6 @@ packages:
pump: 3.0.0
dev: false
/punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
dev: true
/punycode@1.4.1:
resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==}
dev: true
......@@ -16348,11 +16219,6 @@ packages:
engines: {node: '>=8'}
dev: true
/strip-json-comments@4.0.0:
resolution: {integrity: sha512-LzWcbfMbAsEDTRmhjWIioe8GcDRl0fa35YMXFoJKDdiD/quGFmjJjdgPjFJJNwCMaLyQqFIDqCdHD2V4HfLgYA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/strip-literal@1.3.0:
resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
dependencies:
......@@ -17038,14 +16904,6 @@ packages:
engines: {node: '>=8'}
dev: true
/uc.micro@1.0.6:
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
dev: true
/uc.micro@2.0.0:
resolution: {integrity: sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==}
dev: true
/ufo@1.3.2:
resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==}
dev: true
......
CC0 1.0 Universal
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.
For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in
a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or
other defects, accuracy, or the present or absence of errors, whether or not
discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer
disclaims responsibility for obtaining any necessary consents, permissions
or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to this
CC0 or use of the Work.
For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>
<!-- DOCTOC SKIP -->
# Optimism Bedrock specs
# Specs Have Moved
This directory contains the plain english specs for Optimism, a minimal optimistic rollup protocol
that maintains 1:1 compatibility with Ethereum.
## Specification Contents
- [Introduction](introduction.md)
- [Overview](overview.md)
- [Deposits](deposits.md)
- [Withdrawals](withdrawals.md)
- [Execution Engine](exec-engine.md)
- [L2 Output Root Proposals](proposals.md)
- [Rollup Node](rollup-node.md)
- [Rollup Node P2p](rollup-node-p2p.md)
- [L2 Chain Derivation](derivation.md)
- [Superchain Upgrades](superchain-upgrades.md)
- [System Config](system_config.md)
- [Batch Submitter](batcher.md)
- [Guaranteed Gas Market](guaranteed-gas-market.md)
- [Messengers](messengers.md)
- [Bridges](bridges.md)
- [Predeploys](predeploys.md)
- [Glossary](glossary.md)
### Experimental
Specifications of new features in active development.
- [Fault Proof](./fault-proof.md)
- [Dispute Game Interface](./dispute-game-interface.md)
- [Fault Dispute Game](./fault-dispute-game.md)
- [Cannon VM](./cannon-fault-proof-vm.md)
## Design Goals
Our aim is to design a protocol specification that is:
- **Fast:** When users send transactions, they get reliable confirmations with low-latency.
For example when swapping on Uniswap you should see that your transaction succeed in less than 2
seconds.
- **Scalable:** It should be possible to handle an enormous number of transactions
per second which will enable the system to charge low fees.
V1.0 will enable Optimism to scale up to and even past the gas limit on L1.
Later iterations should scale much further.
- **Modular:** Our designs will use modularity to reduce complexity and enable parallel
contributions. Coming up with good conceptual frameworks & composable atoms of software enables us
to build extremely complex software even when any one person cannot hold that much in their brain.
- **Minimal:** Rollups should be minimal to best take advantage of the battle-tested infrastructure
(like Geth) that already runs Ethereum. An ideal optimistic rollup design should be representable
as a *diff* against Ethereum client software.
- **Developer Driven:** Our designs will be developer driven to ensure we are actually building
something that people want to use. We must constantly engage with the developers who will be using
our software to avoid creating a system no one wants to use.
- **Clear and Readable:** The specs we write are written to be read. So tight feedback loop with the
systems team consuming the spec is also key!
- **Secure:** This is self-evident.
User’s assets are at stake. Every component of the system must be incredibly secure.
- **Decentralizable:** Optimism must be designed to avail itself of the security and
censorship-resistant guarantees achieved by a decentralized system.
Currently centralized components of the system should have a clear path towards decentralization.
Already decentralized components of the system should be protected and preserved.
Specs have moved to a [dedicated repository](https://github.com/ethereum-optimism/specs).
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="10662px" height="6124px" viewBox="-0.5 -0.5 10662 6124">
<defs>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-75acff-1-ff66b3-1-e-0">
<stop offset="0%" style="stop-color: rgb(117, 172, 255); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(255, 102, 179); stop-opacity: 1;" />
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-ffe563-1-8cffb6-1-e-0">
<stop offset="0%" style="stop-color: rgb(255, 229, 99); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(140, 255, 182); stop-opacity: 1;" />
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-75acff-1-c683d2-1-e-0">
<stop offset="0%" style="stop-color: rgb(117, 172, 255); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(198, 131, 210); stop-opacity: 1;" />
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-ffe563-1-d8ea7c-1-e-0">
<stop offset="0%" style="stop-color: rgb(255, 229, 99); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(216, 234, 124); stop-opacity: 1;" />
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-d8ea7c-1-b0f79c-1-e-0">
<stop offset="0%" style="stop-color: rgb(216, 234, 124); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(176, 247, 156); stop-opacity: 1;" />
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-c683d2-1-ff66b3-1-e-0">
<stop offset="0%" style="stop-color: rgb(198, 131, 210); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(255, 102, 179); stop-opacity: 1;" />
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-b0f79c-1-8cffb6-1-e-0">
<stop offset="0%" style="stop-color: rgb(176, 247, 156); stop-opacity: 1;" />
<stop offset="100%" style="stop-color: rgb(140, 255, 182); stop-opacity: 1;" />
</linearGradient>
</defs>
<rect fill="#fff" width="100%" height="100%" />
<g>
<path d="M 3900 20 L 4300 20 L 4380 100 L 4380 500 L 3980 500 L 3900 420 L 3900 20 Z" fill="#ff0080" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 3900 20 L 4300 20 L 4380 100 L 3980 100 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 3900 20 L 3980 100 L 3980 500 L 3900 420 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 3980 500 L 3980 100 L 3900 20 M 3980 100 L 4380 100" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 111px; margin-left: 1006px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="1082" y="111" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">100</text>
</switch>
</g>
<path d="M 7420 20 L 7820 20 L 7900 100 L 7900 500 L 7500 500 L 7420 420 L 7420 20 Z" fill="#ccffff" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 7420 20 L 7820 20 L 7900 100 L 7500 100 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 7420 20 L 7500 100 L 7500 500 L 7420 420 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 7500 500 L 7500 100 L 7420 20 M 7500 100 L 7900 100" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 111px; margin-left: 1886px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">102</div>
</div>
</div>
</foreignObject><text x="1962" y="111" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">102</text>
</switch>
</g>
<path d="M 5540 20 L 5940 20 L 6020 100 L 6020 500 L 5620 500 L 5540 420 L 5540 20 Z" fill="#ffff66" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 5540 20 L 5940 20 L 6020 100 L 5620 100 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 5540 20 L 5620 100 L 5620 500 L 5540 420 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 5620 500 L 5620 100 L 5540 20 M 5620 100 L 6020 100" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 111px; margin-left: 1416px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">101</div>
</div>
</div>
</foreignObject><text x="1492" y="111" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">101</text>
</switch>
</g>
<path d="M 3600 4420 L 4000 4420 L 4080 4500 L 4080 4900 L 3680 4900 L 3600 4820 L 3600 4420 Z" fill="#ccccff" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 3600 4420 L 4000 4420 L 4080 4500 L 3680 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 3600 4420 L 3680 4500 L 3680 4900 L 3600 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 3680 4900 L 3680 4500 L 3600 4420 M 3680 4500 L 4080 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 931px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">3</div>
</div>
</div>
</foreignObject><text x="1007" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">3</text>
</switch>
</g>
<path d="M 4240 4420 L 4640 4420 L 4720 4500 L 4720 4900 L 4320 4900 L 4240 4820 L 4240 4420 Z" fill="#75acff" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 4240 4420 L 4640 4420 L 4720 4500 L 4320 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 4240 4420 L 4320 4500 L 4320 4900 L 4240 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 4320 4900 L 4320 4500 L 4240 4420 M 4320 4500 L 4720 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 1091px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">4</div>
</div>
</div>
</foreignObject><text x="1167" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">4</text>
</switch>
</g>
<path d="M 4880 4420 L 5280 4420 L 5360 4500 L 5360 4900 L 4960 4900 L 4880 4820 L 4880 4420 Z" fill="#c882d1" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 4880 4420 L 5280 4420 L 5360 4500 L 4960 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 4880 4420 L 4960 4500 L 4960 4900 L 4880 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 4960 4900 L 4960 4500 L 4880 4420 M 4960 4500 L 5360 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 1251px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">5</div>
</div>
</div>
</foreignObject><text x="1327" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">5</text>
</switch>
</g>
<path d="M 5520 4420 L 5920 4420 L 6000 4500 L 6000 4900 L 5600 4900 L 5520 4820 L 5520 4420 Z" fill="#ff66b3" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 5520 4420 L 5920 4420 L 6000 4500 L 5600 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 5520 4420 L 5600 4500 L 5600 4900 L 5520 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 5600 4900 L 5600 4500 L 5520 4420 M 5600 4500 L 6000 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 1411px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">6</div>
</div>
</div>
</foreignObject><text x="1487" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">6</text>
</switch>
</g>
<path d="M 6160 4420 L 6560 4420 L 6640 4500 L 6640 4900 L 6240 4900 L 6160 4820 L 6160 4420 Z" fill="#ffae52" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 6160 4420 L 6560 4420 L 6640 4500 L 6240 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 6160 4420 L 6240 4500 L 6240 4900 L 6160 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 6240 4900 L 6240 4500 L 6160 4420 M 6240 4500 L 6640 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 1571px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">7</div>
</div>
</div>
</foreignObject><text x="1647" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">7</text>
</switch>
</g>
<path d="M 6800 4420 L 7200 4420 L 7280 4500 L 7280 4900 L 6880 4900 L 6800 4820 L 6800 4420 Z" fill="#ffffa1" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 6800 4420 L 7200 4420 L 7280 4500 L 6880 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 6800 4420 L 6880 4500 L 6880 4900 L 6800 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 6880 4900 L 6880 4500 L 6800 4420 M 6880 4500 L 7280 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 1731px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">8</div>
</div>
</div>
</foreignObject><text x="1807" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">8</text>
</switch>
</g>
<rect x="3600" y="3940" width="480" height="240" rx="36" ry="36" fill="#ccccff" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="4240" y="3940" width="480" height="240" rx="36" ry="36" fill="#75acff" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="4880" y="3940" width="480" height="240" rx="36" ry="36" fill="#c882d1" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="5520" y="3940" width="480" height="240" rx="36" ry="36" fill="#ff66b3" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="6160" y="3940" width="480" height="240" rx="36" ry="36" fill="#ffae52" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="6800" y="3940" width="480" height="240" rx="36" ry="36" fill="#ffffa1" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="3600" y="3500" width="2400" height="240" fill="url(#mx-gradient-75acff-1-ff66b3-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 598px; height: 1px; padding-top: 905px; margin-left: 901px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 25px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: normal; overflow-wrap: normal;">Compressed &amp; encoded batch data</div>
</div>
</div>
</foreignObject><text x="1200" y="912" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="25px" text-anchor="middle" font-style="italic">Compressed &amp; encoded batch data</text>
</switch>
</g>
<rect x="6080" y="3500" width="3040" height="240" fill="url(#mx-gradient-ffe563-1-8cffb6-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="3600" y="3060" width="1440" height="240" fill="url(#mx-gradient-75acff-1-c683d2-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 332px; height: 1px; padding-top: 815px; margin-left: 907px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">A0</div>
</div>
</div>
</foreignObject><text x="1239" y="815" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">A0</text>
</switch>
</g>
<rect x="6080" y="3060" width="480" height="240" fill="url(#mx-gradient-ffe563-1-d8ea7c-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 92px; height: 1px; padding-top: 815px; margin-left: 1527px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">B0</div>
</div>
</div>
</foreignObject><text x="1619" y="815" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">B0</text>
</switch>
</g>
<rect x="6640" y="3060" width="1440" height="240" fill="url(#mx-gradient-d8ea7c-1-b0f79c-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 332px; height: 1px; padding-top: 815px; margin-left: 1667px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">B1</div>
</div>
</div>
</foreignObject><text x="1999" y="815" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">B1</text>
</switch>
</g>
<rect x="9280" y="3060" width="320" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<path d="M 7440 4420 L 7840 4420 L 7920 4500 L 7920 4900 L 7520 4900 L 7440 4820 L 7440 4420 Z" fill="#c3ffa1" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 7440 4420 L 7840 4420 L 7920 4500 L 7520 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 7440 4420 L 7520 4500 L 7520 4900 L 7440 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 7520 4900 L 7520 4500 L 7440 4420 M 7520 4500 L 7920 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 1891px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">9</div>
</div>
</div>
</foreignObject><text x="1967" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">9</text>
</switch>
</g>
<path d="M 8080 4420 L 8480 4420 L 8560 4500 L 8560 4900 L 8160 4900 L 8080 4820 L 8080 4420 Z" fill="#97ff63" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 8080 4420 L 8480 4420 L 8560 4500 L 8160 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 8080 4420 L 8160 4500 L 8160 4900 L 8080 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 8160 4900 L 8160 4500 L 8080 4420 M 8160 4500 L 8560 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 2051px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">10</div>
</div>
</div>
</foreignObject><text x="2127" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">10</text>
</switch>
</g>
<path d="M 8720 4420 L 9120 4420 L 9200 4500 L 9200 4900 L 8800 4900 L 8720 4820 L 8720 4420 Z" fill="#8cffb6" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 8720 4420 L 9120 4420 L 9200 4500 L 8800 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 8720 4420 L 8800 4500 L 8800 4900 L 8720 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 8800 4900 L 8800 4500 L 8720 4420 M 8800 4500 L 9200 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 1211px; margin-left: 2211px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">11</div>
</div>
</div>
</foreignObject><text x="2287" y="1211" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">11</text>
</switch>
</g>
<path d="M 9360 4420 L 9760 4420 L 9840 4500 L 9840 4900 L 9440 4900 L 9360 4820 L 9360 4420 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 9360 4420 L 9760 4420 L 9840 4500 L 9440 4500 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 9360 4420 L 9440 4500 L 9440 4900 L 9360 4820 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 9440 4900 L 9440 4500 L 9360 4420 M 9440 4500 L 9840 4500" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<rect x="7440" y="3940" width="480" height="240" rx="36" ry="36" fill="#c3ffa1" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="8080" y="3940" width="480" height="240" rx="36" ry="36" fill="#97ff63" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="8720" y="3940" width="480" height="240" rx="36" ry="36" fill="#8cffb6" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="9360" y="3940" width="480" height="240" rx="36" ry="36" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="5120" y="3060" width="960" height="240" fill="url(#mx-gradient-c683d2-1-ff66b3-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 212px; height: 1px; padding-top: 815px; margin-left: 1287px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">A1</div>
</div>
</div>
</foreignObject><text x="1499" y="815" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">A1</text>
</switch>
</g>
<rect x="8160" y="3060" width="1120" height="240" fill="url(#mx-gradient-b0f79c-1-8cffb6-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 252px; height: 1px; padding-top: 815px; margin-left: 2047px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">B2</div>
</div>
</div>
</foreignObject><text x="2299" y="815" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">B2</text>
</switch>
</g>
<rect x="9200" y="3500" width="760" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="9840" y="3140" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10010" y="3140" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10170" y="3140" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10090" y="3580" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10260" y="3580" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10420" y="3580" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10010" y="4020" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10180" y="4020" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10340" y="4020" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="9960" y="4620" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10130" y="4620" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="10290" y="4620" width="60" height="80" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="2600" y="3060" width="760" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 795px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">L1 Transactions,<br /> ~128 KB each</div>
</div>
</div>
</foreignObject><text x="838" y="801" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">L1 Transactions,...</text>
</switch>
</g>
<rect x="2760" y="3500" width="600" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 905px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Channels,<br />with timeout</div>
</div>
</div>
</foreignObject><text x="838" y="911" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">Channels,...</text>
</switch>
</g>
<rect x="2240" y="3940" width="1120" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 1015px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Batches,<br />1 batch = 1 L2 block tx list</div>
</div>
</div>
</foreignObject><text x="838" y="1021" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">Batches,...</text>
</switch>
</g>
<rect x="2240" y="4520" width="1120" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 1160px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">L2 Blocks<br />(a.k.a. execution payloads)</div>
</div>
</div>
</foreignObject><text x="838" y="1166" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">L2 Blocks...</text>
</switch>
</g>
<rect x="3920" y="2860" width="800" height="120" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 730px; margin-left: 1080px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Channel A, Frame 0</div>
</div>
</div>
</foreignObject><text x="1080" y="736" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="middle">Channel A, Frame 0</text>
</switch>
</g>
<rect x="5140" y="2860" width="800" height="120" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 730px; margin-left: 1385px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Channel A, Frame 1</div>
</div>
</div>
</foreignObject><text x="1385" y="736" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="middle">Channel A, Frame 1</text>
</switch>
</g>
<rect x="6100" y="2740" width="480" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 715px; margin-left: 1585px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Channel B,<br /> Frame 0</div>
</div>
</div>
</foreignObject><text x="1585" y="721" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="middle">Channel B,...</text>
</switch>
</g>
<rect x="6960" y="2860" width="800" height="120" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 730px; margin-left: 1840px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Channel B, Frame 1</div>
</div>
</div>
</foreignObject><text x="1840" y="736" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="middle">Channel B, Frame 1</text>
</switch>
</g>
<rect x="8300" y="2860" width="800" height="120" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 730px; margin-left: 2175px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Channel B, Frame 2</div>
</div>
</div>
</foreignObject><text x="2175" y="736" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="middle">Channel B, Frame 2</text>
</switch>
</g>
<rect x="9410" y="2860" width="680" height="120" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 730px; margin-left: 2438px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Channel C, etc...</div>
</div>
</div>
</foreignObject><text x="2438" y="736" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="middle">Channel C, etc...</text>
</switch>
</g>
<rect x="8700" y="40" width="880" height="440" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 65px; margin-left: 2177px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">L1 Blocks,<br />These may not be as<br />frequent/consistent<br /> as L2 blocks.</div>
</div>
</div>
</foreignObject><text x="2177" y="71" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" font-weight="bold">L1 Blocks,...</text>
</switch>
</g>
<rect x="8700" y="660" width="1000" height="320" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 205px; margin-left: 2177px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Actual inclusion on L1:<br />channels are valid<br />within a timeout</div>
</div>
</div>
</foreignObject><text x="2177" y="211" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" font-weight="bold">Actual inclusion on L1:...</text>
</switch>
</g>
<rect x="8700" y="1180" width="1600" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 325px; margin-left: 2177px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Channel B was seen first,<br />and will be decoded into batches first.</div>
</div>
</div>
</foreignObject><text x="2177" y="331" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" font-weight="bold">Channel B was seen first,...</text>
</switch>
</g>
<rect x="3600" y="2020" width="480" height="240" rx="36" ry="36" fill="#ffae52" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="4240" y="2020" width="480" height="240" rx="36" ry="36" fill="#ffffa1" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="4880" y="2020" width="480" height="240" rx="36" ry="36" fill="#c3ffa1" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="5520" y="2020" width="480" height="240" rx="36" ry="36" fill="#97ff63" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="6160" y="2020" width="480" height="240" rx="36" ry="36" fill="#8cffb6" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="6800" y="2020" width="480" height="240" rx="36" ry="36" fill="#ccccff" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="7440" y="2020" width="480" height="240" rx="36" ry="36" fill="#75acff" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="8080" y="2020" width="480" height="240" rx="36" ry="36" fill="#c882d1" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="8720" y="2020" width="480" height="240" rx="36" ry="36" fill="#ff66b3" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="1920" y="1980" width="1440" height="440" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 550px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Batches can be buffered<br />for up to a full sequencing window<br />worth of L1 blocks<br />to get the L2 ordering back.</div>
</div>
</div>
</foreignObject><text x="838" y="556" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">Batches can be buffered...</text>
</switch>
</g>
<rect x="9220" y="5660" width="520" height="280" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 1450px; margin-left: 2433px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 50px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Time</div>
</div>
</div>
</foreignObject><text x="2433" y="1465" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="50px" text-anchor="end" font-weight="bold">Time</text>
</switch>
</g>
<path d="M 9842 5800 L 9842 5760 L 10490 5760 L 10490 5648.91 L 10638 5780 L 10490 5911.09 L 10490 5800 Z" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<rect x="3540" y="700" width="1440" height="240" fill="#bfbfbf" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 205px; margin-left: 886px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: normal; overflow-wrap: normal;">older L2 data</div>
</div>
</div>
</foreignObject><text x="1065" y="214" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle" font-style="italic">older L2 data</text>
</switch>
</g>
<rect x="5260" y="700" width="1440" height="240" fill="url(#mx-gradient-d8ea7c-1-b0f79c-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 332px; height: 1px; padding-top: 225px; margin-left: 1322px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">B1</div>
</div>
</div>
</foreignObject><text x="1654" y="225" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">B1</text>
</switch>
</g>
<rect x="6220" y="1060" width="480" height="240" fill="url(#mx-gradient-ffe563-1-d8ea7c-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 92px; height: 1px; padding-top: 315px; margin-left: 1562px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">B0</div>
</div>
</div>
</foreignObject><text x="1654" y="315" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">B0</text>
</switch>
</g>
<rect x="5260" y="1060" width="960" height="240" fill="url(#mx-gradient-c683d2-1-ff66b3-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 212px; height: 1px; padding-top: 315px; margin-left: 1322px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">A1</div>
</div>
</div>
</foreignObject><text x="1534" y="315" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">A1</text>
</switch>
</g>
<rect x="8060" y="700" width="320" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<rect x="6940" y="700" width="1120" height="240" fill="url(#mx-gradient-b0f79c-1-8cffb6-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 252px; height: 1px; padding-top: 225px; margin-left: 1742px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">B2</div>
</div>
</div>
</foreignObject><text x="1994" y="225" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">B2</text>
</switch>
</g>
<rect x="6940" y="1060" width="1440" height="240" fill="url(#mx-gradient-75acff-1-c683d2-1-e-0)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 332px; height: 1px; padding-top: 315px; margin-left: 1742px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">A0</div>
</div>
</div>
</foreignObject><text x="2074" y="315" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="end">A0</text>
</switch>
</g>
<path d="M 6160 5420 L 6240 5180 L 6640 5180 L 6560 5420 Z" fill="#ff0080" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 1551px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100-0</div>
</div>
</div>
</foreignObject><text x="1647" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">100-0</text>
</switch>
</g>
<path d="M 6800 5420 L 6880 5180 L 7280 5180 L 7200 5420 Z" fill="#ff0080" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 1711px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100-1</div>
</div>
</div>
</foreignObject><text x="1807" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">100-1</text>
</switch>
</g>
<path d="M 7440 5420 L 7520 5180 L 7920 5180 L 7840 5420 Z" fill="#ff0080" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 1871px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100-2</div>
</div>
</div>
</foreignObject><text x="1967" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">100-2</text>
</switch>
</g>
<path d="M 8080 5420 L 8160 5180 L 8560 5180 L 8480 5420 Z" fill="#ff0080" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 2031px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100-3</div>
</div>
</div>
</foreignObject><text x="2127" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">100-3</text>
</switch>
</g>
<path d="M 8720 5420 L 8800 5180 L 9200 5180 L 9120 5420 Z" fill="#ff0080" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 2191px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100-4</div>
</div>
</div>
</foreignObject><text x="2287" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">100-4</text>
</switch>
</g>
<path d="M 9360 5420 L 9440 5180 L 9840 5180 L 9760 5420 Z" fill="#ffff66" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 2351px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">101-0</div>
</div>
</div>
</foreignObject><text x="2447" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">101-0</text>
</switch>
</g>
<path d="M 5520 5420 L 5600 5180 L 6000 5180 L 5920 5420 Z" fill="#e0e0e0" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 1391px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">99-5</div>
</div>
</div>
</foreignObject><text x="1487" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">99-5</text>
</switch>
</g>
<path d="M 4880 5420 L 4960 5180 L 5360 5180 L 5280 5420 Z" fill="#e0e0e0" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 1231px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">99-4</div>
</div>
</div>
</foreignObject><text x="1327" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">99-4</text>
</switch>
</g>
<path d="M 4240 5420 L 4320 5180 L 4720 5180 L 4640 5420 Z" fill="#e0e0e0" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 1071px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">99-3</div>
</div>
</div>
</foreignObject><text x="1167" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">99-3</text>
</switch>
</g>
<path d="M 3600 5420 L 3680 5180 L 4080 5180 L 4000 5420 Z" fill="#e0e0e0" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 96px; height: 1px; padding-top: 1341px; margin-left: 911px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">99-2</div>
</div>
</div>
</foreignObject><text x="1007" y="1341" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">99-2</text>
</switch>
</g>
<path d="M 2400 40 L 2800 40 L 2880 120 L 2880 520 L 2480 520 L 2400 440 L 2400 40 Z" fill="#e0e0e0" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<path d="M 2400 40 L 2800 40 L 2880 120 L 2480 120 Z" fill-opacity="0.05" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 2400 40 L 2480 120 L 2480 520 L 2400 440 Z" fill-opacity="0.1" fill="#000000" stroke="none" pointer-events="all" />
<path d="M 2480 520 L 2480 120 L 2400 40 M 2480 120 L 2880 120" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-end; width: 76px; height: 1px; padding-top: 116px; margin-left: 631px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">99</div>
</div>
</div>
</foreignObject><text x="707" y="116" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="end">99</text>
</switch>
</g>
<rect x="2040" y="5180" width="1320" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 1325px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Each L2 block has a tx with info<br />about the "origin" L1 block</div>
</div>
</div>
</foreignObject><text x="838" y="1331" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">Each L2 block has a tx with info...</text>
</switch>
</g>
<rect x="2040" y="5580" width="1320" height="320" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 1435px; margin-left: 838px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">The "sequence number" <br />helps differentiate between <br />L2 blocks with the same origin.</div>
</div>
</div>
</foreignObject><text x="838" y="1441" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">The "sequence number"...</text>
</switch>
</g>
<path d="M 3900 1100 Q 4080 1172 4260 1100 Q 4440 1028 4620 1100 L 4620 1300 Q 4440 1228 4260 1300 Q 4080 1372 3900 1300 L 3900 1100 Z" fill="#fff2cc" stroke="#d6b656" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 300px; margin-left: 976px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">deposit</div>
</div>
</div>
</foreignObject><text x="1065" y="309" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">deposit</text>
</switch>
</g>
<path d="M 3920 1380 Q 4100 1452 4280 1380 Q 4460 1308 4640 1380 L 4640 1580 Q 4460 1508 4280 1580 Q 4100 1652 3920 1580 L 3920 1380 Z" fill="#fff2cc" stroke="#d6b656" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 370px; margin-left: 981px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">deposit</div>
</div>
</div>
</foreignObject><text x="1070" y="379" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">deposit</text>
</switch>
</g>
<rect x="2180" y="1180" width="1160" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 325px; margin-left: 833px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Deposits are L1 log events,<br />parsed from EVM receipts</div>
</div>
</div>
</foreignObject><text x="833" y="331" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">Deposits are L1 log events,...</text>
</switch>
</g>
<path d="M 6100 5560 Q 6280 5632 6460 5560 Q 6640 5488 6820 5560 L 6820 5760 Q 6640 5688 6460 5760 Q 6280 5832 6100 5760 L 6100 5560 Z" fill="#fff2cc" stroke="#d6b656" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 1415px; margin-left: 1526px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">deposit</div>
</div>
</div>
</foreignObject><text x="1615" y="1424" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">deposit</text>
</switch>
</g>
<path d="M 6120 5840 Q 6300 5912 6480 5840 Q 6660 5768 6840 5840 L 6840 6040 Q 6660 5968 6480 6040 Q 6300 6112 6120 6040 L 6120 5840 Z" fill="#fff2cc" stroke="#d6b656" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 1485px; margin-left: 1531px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">deposit</div>
</div>
</div>
</foreignObject><text x="1620" y="1494" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">deposit</text>
</switch>
</g>
<rect x="4980" y="5660" width="1000" height="440" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 1470px; margin-left: 1493px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 21px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">Deposits get included<br />the first L2 block that<br />adopts the L1 origin the<br />deposits were made in.</div>
</div>
</div>
</foreignObject><text x="1493" y="1476" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="21px" text-anchor="end" font-weight="bold">Deposits get included...</text>
</switch>
</g>
<rect x="20" y="2300" width="2560" height="640" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 655px; margin-left: 7px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Security types on L2:<br />- "unsafe": not submitted on L1<br />- "safe": is confirmed on L1<br />- "finalized": fully derived from finalized L1 data</div>
</div>
</div>
</foreignObject><text x="7" y="664" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px">Security types on L2:...</text>
</switch>
</g>
<rect x="60" y="3140" width="2000" height="640" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 865px; margin-left: 17px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">Security types on L1:<br />- "unsafe": very new<br />- "safe": decent attestation ratio<br />- "finalized": with FFG finality gadget</div>
</div>
</div>
</foreignObject><text x="17" y="874" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px">Security types on L1:...</text>
</switch>
</g>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" /><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a>
</switch>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="11984px" height="4564px" viewBox="-0.5 -0.5 11984 4564">
<rect width="100%" height="100%" fill="#fff" />
<defs />
<g>
<path d="M 4820 2900 L 5820 2900 L 5900 3000 L 5820 3100 L 4820 3100 L 4900 3000 Z" fill="#99ffcc" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 772px; margin-left: 1206px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="1338" y="772" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 6900 2900 L 7900 2900 L 7980 3000 L 7900 3100 L 6900 3100 L 6980 3000 Z" fill="#a8fff6" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 772px; margin-left: 1726px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="1858" y="772" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 5860 2900 L 6860 2900 L 6940 3000 L 6860 3100 L 5860 3100 L 5940 3000 Z" fill="#96ffe3" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 772px; margin-left: 1466px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="1598" y="772" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 4100 3000 L 4900 3000" fill="none" stroke="rgb(0, 0, 0)" stroke-width="28" stroke-miterlimit="10" stroke-dasharray="84 84" pointer-events="stroke" />
<path d="M 3780 2900 L 4020 2900 L 4100 3000 L 4020 3100 L 3780 3100 L 3860 3000 Z" fill="#99ff99" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 74px; height: 1px; padding-top: 772px; margin-left: 946px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="983" y="772" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">100</text>
</switch>
</g>
<rect x="5860" y="1340" width="1000" height="560" fill="#96ffe3" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 1466px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Batch Queue</div>
</div>
</div>
</foreignObject><text x="1590" y="414" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">Batch Queue</text>
</switch>
</g>
<rect x="7940" y="1340" width="1000" height="560" fill="#9ceeff" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 1986px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Engine Queue</div>
</div>
</div>
</foreignObject><text x="2110" y="414" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">Engine Queue</text>
</switch>
</g>
<rect x="6900" y="1340" width="1000" height="560" fill="#a8fff6" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 1726px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<div>PayloadAttributes</div>
<div>Queue<br /></div>
</div>
</div>
</div>
</foreignObject><text x="1850" y="414" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">PayloadAttributes...</text>
</switch>
</g>
<rect x="4820" y="1340" width="1000" height="560" fill="#99ffcc" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 1206px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<div>Channel</div>
<div>Input-reader<br /></div>
</div>
</div>
</div>
</foreignObject><text x="1330" y="414" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">Channel...</text>
</switch>
</g>
<rect x="3780" y="1340" width="1000" height="560" fill="#99ff99" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 946px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<div>Channel</div>
<div>Bank<br /></div>
</div>
</div>
</div>
</foreignObject><text x="1070" y="414" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">Channel...</text>
</switch>
</g>
<rect x="1700" y="1340" width="1000" height="560" fill="#e3ff96" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 426px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Traversal</div>
</div>
</div>
</foreignObject><text x="550" y="414" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">L1 Traversal</text>
</switch>
</g>
<path d="M 1700 2900 L 2700 2900 L 2780 3000 L 2700 3100 L 1700 3100 L 1780 3000 Z" fill="#e3ff96" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 772px; margin-left: 426px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="558" y="772" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">100</text>
</switch>
</g>
<path d="M 8340 3000 L 8980 3000" fill="none" stroke="rgb(0, 0, 0)" stroke-width="28" stroke-miterlimit="10" stroke-dasharray="84 84" pointer-events="stroke" />
<path d="M 7940 2900 L 8260 2900 L 8340 3000 L 8260 3100 L 7940 3100 L 8020 3000 Z" fill="#9ceeff" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 772px; margin-left: 1986px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="2033" y="772" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 7120 540 C 6912 540 6860 700 7026.4 732 C 6860 802.4 7047.2 956 7182.4 892 C 7276 1020 7588 1020 7692 892 C 7900 892 7900 764 7770 700 C 7900 572 7692 444 7510 508 C 7380 412 7172 412 7120 540 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 258px; height: 1px; padding-top: 175px; margin-left: 1716px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Deposits</div>
</div>
</div>
</foreignObject><text x="1845" y="184" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">L1 Deposits</text>
</switch>
</g>
<path d="M 8660 1980 L 8940 1980 L 9020 2080 L 8940 2180 L 8660 2180 L 8740 2080 Z" fill="#9ceeff" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 84px; height: 1px; padding-top: 542px; margin-left: 2166px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="2208" y="542" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 5860 2460 L 6900 2460 L 6980 2560 L 6900 2660 L 5860 2660 L 5940 2560 Z" fill="#96ffe3" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 274px; height: 1px; padding-top: 662px; margin-left: 1466px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="1603" y="662" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 4820 2460 L 5820 2460 L 5900 2560 L 5820 2660 L 4820 2660 L 4900 2560 Z" fill="#99ffcc" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 662px; margin-left: 1206px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="1338" y="662" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 4540 2460 L 4780 2460 L 4860 2560 L 4780 2660 L 4540 2660 L 4620 2560 Z" fill="#99ff99" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 74px; height: 1px; padding-top: 662px; margin-left: 1136px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="1173" y="662" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 1700 2660 L 2700 2660 L 2780 2760 L 2700 2860 L 1700 2860 L 1780 2760 Z" fill="#e3ff96" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 712px; margin-left: 426px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="558" y="712" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">100</text>
</switch>
</g>
<path d="M 3780 2660 L 4020 2660 L 4100 2760 L 4020 2860 L 3780 2860 L 3860 2760 Z" fill="#99ff99" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 74px; height: 1px; padding-top: 712px; margin-left: 946px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="983" y="712" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">100</text>
</switch>
</g>
<path d="M 4820 3300 L 5820 3300 L 5900 3400 L 5820 3500 L 4820 3500 L 4900 3400 Z" fill="#99ffcc" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 1206px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="1338" y="872" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 6900 3300 L 7900 3300 L 7980 3400 L 7900 3500 L 6900 3500 L 6980 3400 Z" fill="#a8fff6" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 1726px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="1858" y="872" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 5860 3300 L 6860 3300 L 6940 3400 L 6860 3500 L 5860 3500 L 5940 3400 Z" fill="#96ffe3" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 1466px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="1598" y="872" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 3780 3300 L 4780 3300 L 4860 3400 L 4780 3500 L 3780 3500 L 3860 3400 Z" fill="#99ff99" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 946px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="1078" y="872" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 1700 3300 L 2700 3300 L 2780 3400 L 2700 3500 L 1700 3500 L 1780 3400 Z" fill="#e3ff96" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 426px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="558" y="872" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 7940 3300 L 8940 3300 L 9020 3400 L 8940 3500 L 7940 3500 L 8020 3400 Z" fill="#9ceeff" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 1986px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="2118" y="872" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<rect x="9720" y="1152" width="2160" height="520" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 353px; margin-left: 2432px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 50px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">1) find safe L2 block<br />with canonical L1 origin</div>
</div>
</div>
</foreignObject><text x="2432" y="368" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="50px">1) find safe L2 block...</text>
</switch>
</g>
<rect x="9720" y="2472" width="2240" height="520" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 683px; margin-left: 2432px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 50px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">3) reset all stage origins,<br />traverse chain back</div>
</div>
</div>
</foreignObject><text x="2432" y="698" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="50px">3) reset all stage orig...</text>
</switch>
</g>
<rect x="9720" y="3112" width="1880" height="520" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 843px; margin-left: 2432px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 50px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">4) dry-run pipeline<br />to heal stage buffers</div>
</div>
</div>
</foreignObject><text x="2432" y="858" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="50px">4) dry-run pipeline...</text>
</switch>
</g>
<rect x="9720" y="3752" width="2120" height="520" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 1003px; margin-left: 2432px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 50px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">5) new L1 data<br />can now stream into L2</div>
</div>
</div>
</foreignObject><text x="2432" y="1018" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="50px">5) new L1 data...</text>
</switch>
</g>
<rect x="9720" y="1832" width="2160" height="520" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 523px; margin-left: 2432px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 50px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">2) Stages with gaps will<br /> reconstruct buffer data</div>
</div>
</div>
</foreignObject><text x="2432" y="538" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="50px">2) Stages with gaps wi...</text>
</switch>
</g>
<path d="M 2055.29 1022 L 2304.71 1022 L 2304.71 1116.35 L 2600.82 1116.35 L 2180 1258 L 1759.18 1116.35 L 2055.29 1116.35 Z" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" pointer-events="all" />
<path d="M 8609.69 1258 L 8360.28 1258 L 8360.28 1163.65 L 8064.16 1163.65 L 8484.99 1022 L 8905.81 1163.65 L 8609.69 1163.65 Z" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" pointer-events="all" />
<rect x="460" y="4140" width="1160" height="400" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 1085px; margin-left: 260px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 26px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: nowrap;">Numbers for illustration,<br /> referring to L1 origin<br />block numbers</div>
</div>
</div>
</foreignObject><text x="260" y="1093" fill="#000000" font-family="Helvetica" font-size="26px" text-anchor="middle" font-style="italic">Numbers for illustrati...</text>
</switch>
</g>
<rect x="60" y="1900" width="1360" height="600" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 550px; margin-left: 185px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 40px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">"<b>ResetStep</b>":<br style="font-size: 40px" />reset stage with<br style="font-size: 40px" />distance from next</div>
</div>
</div>
</foreignObject><text x="185" y="562" fill="#000000" font-family="Helvetica" font-size="40px" text-anchor="middle">"ResetStep":...</text>
</switch>
</g>
<rect x="20" y="2940" width="1440" height="1000" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 860px; margin-left: 185px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 40px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">"<b>Step</b>":<br style="font-size: 40px" />progress pipeline.<br />Start closest to L2,<br />visit previous stage<br />for more input data.</div>
</div>
</div>
</foreignObject><text x="185" y="872" fill="#000000" font-family="Helvetica" font-size="40px" text-anchor="middle">"Step":...</text>
</switch>
</g>
<rect x="1760" y="3860" width="7080" height="240" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 995px; margin-left: 1325px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 36px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;">L1 block hash &gt; Data TXs &gt; Channel Frames &gt; Batches &gt; Ordered batches &gt; PayloadAttributes &gt; L2 payloads</div>
</div>
</div>
</foreignObject><text x="1325" y="1006" fill="#000000" font-family="Helvetica" font-size="36px" text-anchor="middle">L1 block hash &gt; Data TXs &gt; Channel Frames &gt; Batches &gt; Ordered batches &gt; PayloadAttributes &gt; L2 payl...</text>
</switch>
</g>
<rect x="3800" y="2100" width="680" height="560" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 595px; margin-left: 1118px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 36px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: nowrap;">Resets<br /><b>Channel</b><br /><b>timeout</b></div>
</div>
</div>
</foreignObject><text x="1118" y="606" fill="#000000" font-family="Helvetica" font-size="36px" text-anchor="end" font-style="italic">Resets...</text>
</switch>
</g>
<rect x="7620" y="1900" width="920" height="560" fill="none" stroke="none" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-end; width: 1px; height: 1px; padding-top: 545px; margin-left: 2133px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: right;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 36px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: nowrap;">
<div>Resets</div><b>Sequencing</b><br /><b>window</b>
</div>
</div>
</div>
</foreignObject><text x="2133" y="556" fill="#000000" font-family="Helvetica" font-size="36px" text-anchor="end" font-style="italic">ResetsSequenc...</text>
</switch>
</g>
<rect x="2740" y="1340" width="1000" height="560" fill="#c9f783" stroke="#000000" stroke-width="4" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 405px; margin-left: 686px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Retrieval</div>
</div>
</div>
</foreignObject><text x="810" y="414" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">L1 Retrieval</text>
</switch>
</g>
<path d="M 2740 2900 L 3740 2900 L 3820 3000 L 3740 3100 L 2740 3100 L 2820 3000 Z" fill="#c9f783" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 772px; margin-left: 686px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="818" y="772" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">100</text>
</switch>
</g>
<path d="M 2740 2660 L 3740 2660 L 3820 2760 L 3740 2860 L 2740 2860 L 2820 2760 Z" fill="#c9f783" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 712px; margin-left: 686px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100</div>
</div>
</div>
</foreignObject><text x="818" y="712" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">100</text>
</switch>
</g>
<path d="M 2740 3300 L 3740 3300 L 3820 3400 L 3740 3500 L 2740 3500 L 2820 3400 Z" fill="#c9f783" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 264px; height: 1px; padding-top: 872px; margin-left: 686px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">130</div>
</div>
</div>
</foreignObject><text x="818" y="872" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">130</text>
</switch>
</g>
<path d="M 3152.45 1022 L 3401.87 1022 L 3401.87 1116.35 L 3697.98 1116.35 L 3277.16 1258 L 2856.34 1116.35 L 3152.45 1116.35 Z" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" pointer-events="all" />
<path d="M 7295.29 1062 L 7544.71 1062 L 7544.71 1156.35 L 7840.82 1156.35 L 7420 1298 L 6999.18 1156.35 L 7295.29 1156.35 Z" fill="#000000" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" pointer-events="all" />
<path d="M 3020 500 C 2812 500 2760 660 2926.4 692 C 2760 762.4 2947.2 916 3082.4 852 C 3176 980 3488 980 3592 852 C 3800 852 3800 724 3670 660 C 3800 532 3592 404 3410 468 C 3280 372 3072 372 3020 500 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 258px; height: 1px; padding-top: 165px; margin-left: 691px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Data</div>
</div>
</div>
</foreignObject><text x="820" y="174" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">L1 Data</text>
</switch>
</g>
<path d="M 1940 500 C 1732 500 1680 660 1846.4 692 C 1680 762.4 1867.2 916 2002.4 852 C 2096 980 2408 980 2512 852 C 2720 852 2720 724 2590 660 C 2720 532 2512 404 2330 468 C 2200 372 1992 372 1940 500 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 258px; height: 1px; padding-top: 165px; margin-left: 421px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Chain</div>
</div>
</div>
</foreignObject><text x="550" y="174" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">L1 Chain</text>
</switch>
</g>
<rect x="8220" y="220" width="520" height="520" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="12" pointer-events="none" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 120px; margin-left: 2056px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">L2 Exec<br style="font-size: 30px;" />Engine</div>
</div>
</div>
</foreignObject><text x="2120" y="129" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="30px" text-anchor="middle">L2 Exec...</text>
</switch>
</g>
<rect x="8020" y="220" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8100" y="300" width="80" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8020" y="380" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8100" y="460" width="80" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8020" y="540" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8100" y="620" width="80" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8020" y="700" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="220" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="300" width="80" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="380" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="460" width="80" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="540" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="620" width="80" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8780" y="700" width="160" height="40" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8300" y="780" width="40" height="80" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8220" y="780" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8460" y="780" width="40" height="80" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8380" y="780" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8620" y="780" width="40" height="80" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8540" y="780" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8700" y="780" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8300" y="100" width="40" height="80" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8220" y="20" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8460" y="100" width="40" height="80" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8380" y="20" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8620" y="100" width="40" height="80" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8540" y="20" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<rect x="8700" y="20" width="40" height="160" fill="#000000" stroke="none" pointer-events="none" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 233px; margin-left: 2535px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); ">
<div style="display: inline-block; font-size: 70px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;">Reset:</div>
</div>
</div>
</foreignObject><text x="2535" y="254" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="70px" text-anchor="middle">Reset:</text>
</switch>
</g>
<path d="M 6940 2460 L 7900 2460 L 7980 2560 L 7900 2660 L 6940 2660 L 7020 2560 Z" fill="#a8fff6" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="none" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 254px; height: 1px; padding-top: 662px; margin-left: 1736px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">
<div>110</div>
</div>
</div>
</div>
</foreignObject><text x="1863" y="662" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
<path d="M 7940 2460 L 8260 2460 L 8340 2560 L 8260 2660 L 7940 2660 L 8020 2560 Z" fill="#9ceeff" stroke="#000000" stroke-width="4" stroke-miterlimit="10" pointer-events="none" />
<g transform="translate(-0.5 -0.5)scale(4)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 94px; height: 1px; padding-top: 662px; margin-left: 1986px;">
<div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #000000; ">
<div style="display: inline-block; font-size: 30px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">110</div>
</div>
</div>
</foreignObject><text x="2033" y="662" fill="#000000" font-family="Helvetica" font-size="30px" text-anchor="middle">110</text>
</switch>
</g>
</g>
<switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" /><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a>
</switch>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="441px" height="351px" viewBox="-0.5 -0.5 441 351" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2023-03-20T08:57:38.419Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.8.16 Chrome/106.0.5249.199 Electron/21.4.0 Safari/537.36&quot; etag=&quot;naeFneXxkMTGqgBSgGby&quot; version=&quot;20.8.16&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;tywBRjScRQLhh2Yu3ye-&quot; name=&quot;Page-1&quot;&gt;5Zlfb5swEMA/TaTtZQIMhDw2adZNytZqkbb20YEDvAFmjmnIPv1MMAFiWkULlG57in3+g/278/nOmaBFnN8wnIafqAfRxNC8fIKuJ4ah67opfgrJvpQ4MykIGPFkp1qwJr9ACjUpzYgH21ZHTmnESdoWujRJwOUtGWaM7trdfBq1v5riABTB2sWRKv1GPB7KXVhaLf8AJAirL+uabIlx1VkKtiH26K4hQssJWjBKeVmK8wVEBbyKSznu/ROtx4UxSPg5A4xywCOOMrk3uS6+rzbLaJZ4UPTXJmi+CwmHdYrdonUn1CtkIY8jUdNF0SdRtKARZYexyPd9w3WFfMsZ/QGNFs/e2JYtWtQVy008AuOQN0RyBzdAY+BsL7rIViRh7ttWsqtVY5pSFrbVIk1CmkNwnLkmJgoSWjdApAC8TTmJyTa+o4zj6DKcPcAx23AMFY5udMCxe2BjKmxWxm3G04zfMuwKIGOzQdp4cKxhT55ngeOZXSfPMTbIHujkdQDsPHpHq7yEoK0AA0+4aVkVpy+kAU1wtKyl8zbSus+K0lSC/A6c7+WdgzNOz7S6Lc2YK9cxk3cSZgFUvaR6iyU+S5ZBhDl5bN80l2CajoEJcsLvG+WHYqp3wujL6nUupz5U9lUlEVu7b1bKYVZVrYcdatW4P9aJPpZOnNejk+kr08l0LJ3MFIf8hUZRlk4Kp2ZHYn3zDROloCh9FjHtZf46YNgjAs41YSJEJTQRcsBb3hFEOS50B1EbxzItrTFZo226vLKXz2rifDc/PXHzturm7YGuySpGe4VevnIfLfNFY5lvtZqG/c4xd0MhWmebmHAOrNcI4wyz7MH0jjHZM7and4UYqA/jU9OjVVFf5uBmhzMryklAElA9xJtDzxvg4dv/x1GcJhvOCwbUupqKHQ7Ax2RD88tU0AMZfTpeqqF3JGL66ETMk+RhphJBXalDH0DU5Gt1Yfo1ABCEXpDI602m+o8I5dA7SsRn61x21sbvnGAtr3k5qCZ7xRjeN7qlRYft+Z8xNKs53bnLqvVaLqDW8pHIeYqfKkehfKL51+KGDvcyXNzgqP4FAki80X2MYZ1Yn6VicYaiomZYa/iZQeL+nRZ2irIj2BkKZWXcDZRfgRGf9EzSw+D4nSRt14GNPwxJ1PGCPxhJNRB6iaeY46tK/ZDyMGm+o1zwqiLj4GZaOuv7Cn0Cr6jW/12Vt1H9DyBa/gY=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs><linearGradient x1="0%" y1="0%" x2="100%" y2="0%" id="mx-gradient-f8cecc-1-7ea6e0-1-e-0"><stop offset="0%" style="stop-color: rgb(248, 206, 204); stop-opacity: 1;"/><stop offset="100%" style="stop-color: rgb(126, 166, 224); stop-opacity: 1;"/></linearGradient></defs><g><rect x="0" y="0" width="440" height="110" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><rect x="10" y="10" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 40px; margin-left: 11px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">OptimismPortal</div></div></div></foreignObject><text x="70" y="44" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">OptimismPortal</text></switch></g><rect x="270" y="10" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 40px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2OutputOracle</div></div></div></foreignObject><text x="330" y="44" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2OutputOracle</text></switch></g><rect x="0" y="110" width="440" height="240" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><path d="M 70 210 L 70 263.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 70 268.88 L 66.5 261.88 L 70 263.63 L 73.5 261.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 100 165 L 183.63 165" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 188.88 165 L 181.88 168.5 L 183.63 165 L 181.88 161.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 100 195 L 183.63 195" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 188.88 195 L 181.88 198.5 L 183.63 195 L 181.88 191.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="40" y="150" width="60" height="60" fill="url(#mx-gradient-f8cecc-1-7ea6e0-1-e-0)" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 180px; margin-left: 41px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Rollup <br />Node</div></div></div></foreignObject><text x="70" y="184" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup...</text></switch></g><path d="M 260 150 L 260 110 L 200 110 L 200 76.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 200 71.12 L 203.5 78.12 L 200 76.37 L 196.5 78.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="190" y="150" width="140" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 165px; margin-left: 191px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Batch Submitter</div></div></div></foreignObject><text x="260" y="169" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Batch Submitter</text></switch></g><rect x="10" y="270" width="120" height="60" fill="url(#mx-gradient-f8cecc-1-7ea6e0-1-e-0)" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 300px; margin-left: 11px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2 Execution Engine<br />(L2 Geth)</div></div></div></foreignObject><text x="70" y="304" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Execution Engine...</text></switch></g><rect x="140" y="10" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 40px; margin-left: 141px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">BatchInbox</div></div></div></foreignObject><text x="200" y="44" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">BatchInbox</text></switch></g><rect x="400" y="80" width="30" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 90px; margin-left: 401px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1</div></div></div></foreignObject><text x="415" y="94" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1</text></switch></g><rect x="400" y="320" width="30" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 330px; margin-left: 401px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2</div></div></div></foreignObject><text x="415" y="334" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2</text></switch></g><path d="M 330 195 L 360 195 L 360 76.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 360 71.12 L 363.5 78.12 L 360 76.37 L 356.5 78.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="190" y="180" width="140" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 195px; margin-left: 191px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Output Submitter</div></div></div></foreignObject><text x="260" y="199" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Output Submitter</text></switch></g><rect x="220" y="240" width="80" height="30" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 255px; margin-left: 221px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Legend</div></div></div></foreignObject><text x="260" y="259" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Legend</text></switch></g><rect x="220" y="270" width="80" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 285px; margin-left: 221px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencer</div></div></div></foreignObject><text x="260" y="289" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencer</text></switch></g><rect x="220" y="300" width="80" height="30" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 315px; margin-left: 221px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Verifier</div></div></div></foreignObject><text x="260" y="319" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Verifier</text></switch></g><path d="M 70 70 L 70 143.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 70 148.88 L 66.5 141.88 L 70 143.63 L 73.5 141.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="531px" height="141px" viewBox="-0.5 -0.5 531 141" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-25T04:07:17.281Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; version=&quot;17.2.2&quot; etag=&quot;S-USrjD2jP5lhtU_zkIV&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;-Oad3u7U5KLW3JGQjOOA&quot;&gt;3ZhNc5swEIZ/DTPtpQPIfPhYO257SE8+pD3K0gJqZeTKIrb76yvCYmDkTJyxU+pePOyrRR+PXhZhj8zX+8+aboqvioP0Qp/vPXLnhWGSxva3Fg6NEAQkbJRcC45aJyzFb0DRR7USHLaDRKOUNGIzFJkqS2BmoFGt1W6Ylik5HHVDc3CEJaPSVR8EN0WjppHf6V9A5EU7cuBjy5q2yShsC8rVrieRhUfmWinTXK33c5A1vJZLc9+nZ1qPE9NQmnNuQO6PVFa4NpyXObSL1aoqOdT5vkdmu0IYWG4oq1t3dnutVpi1tFFgL7dGq58wV1Jpq5SqtGkzHAO0gf2z8wyOq7e2AbUGow82BW+YIC90TNLGuw5/RFAr+ujbRIpbnh+77qjYCwRzGhJxIAWXUcqElC0jLyRZloWMOfRsC49XcRRfB+HRhMgwDVyG8QmE8RUIThxewO0ThaHSplC5KqlcdOpsSLTLuVdqgxx/gDEHLA+0MmpIuRmzHmi4aarSDKUIiwfVOZjBZp/BVYOkRjwOe7+EUuT47MKncRSfhSP6LB7DZ5aLPnzrB9/rzj5EbXi3x86b6IDRGf5MXH9G4/kzcfxJbtCfZER/pv+ZP6euP5Px/Dl1/Om+d/59f05G9Gc7VA/hEn5VUDJR5lZ/EGV9XA39d4uNYoW9CN5fFTGPIOWTU4jTcEXiNzoKJamLmJxiHF6DsXt4vO0iEIRuFZiOVwXa6fQ8HN1gGYjGLAPuF88LZSC8chmgkGYnEccshVX2NifVJPqbZWDiML53K4NdnDnjC7uPDyUqRV7akFkYYPVZjUowKj9iw1pw/lRbTm3NcPOu8lYburl9Jl9wM3k9aRt2/588tfX+hSKLPw==&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="0" y="0" width="530" height="140" fill="rgb(255, 255, 255)" stroke="none" pointer-events="all"/><rect x="60" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1</div></div></div></foreignObject><text x="90" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1</text></switch></g><path d="M 160 100 L 126.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 121.12 100 L 128.12 96.5 L 126.37 100 L 128.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="160" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">2</div></div></div></foreignObject><text x="190" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">2</text></switch></g><path d="M 260 100 L 226.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 221.12 100 L 228.12 96.5 L 226.37 100 L 228.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="260" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">3</div></div></div></foreignObject><text x="290" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">3</text></switch></g><path d="M 360 100 L 326.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 321.12 100 L 328.12 96.5 L 326.37 100 L 328.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="360" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 361px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">4</div></div></div></foreignObject><text x="390" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">4</text></switch></g><rect x="60" y="40" width="360" height="20" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 50px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencing Window (Epoch 1)</div></div></div></foreignObject><text x="240" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencing Window (Epoch 1)</text></switch></g><path d="M 460 100 L 426.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 421.12 100 L 428.12 96.5 L 426.37 100 L 428.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">5</div></div></div></foreignObject><text x="490" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">5</text></switch></g><rect x="160" y="10" width="360" height="20" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 20px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencing Window (Epoch 2)</div></div></div></foreignObject><text x="340" y="24" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencing Window (Epoch 2)</text></switch></g><rect x="0" y="85" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1</div></div></div></foreignObject><text x="30" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="531px" height="231px" viewBox="-0.5 -0.5 531 231" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-25T05:19:49.466Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; version=&quot;17.2.2&quot; etag=&quot;Irh5zdWZ108PS-1D0fT9&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;WQkJvLcG5yU01wDlPyWO&quot;&gt;5ZnLcpswFIafhpl20+FiMF7Wl7aLtIu6M2mXMjqAWhlRWcR2n74iFgZyyNRJiInTjUf6JSH49OtwhC1vtt59lCRPPwsK3HJturO8ueW64zDQv6WwPwiOHYQHJZGMGq0WluwPVB2NWjAKm1ZHJQRXLG+LkcgyiFRLI1KKbbtbLHh71pwkgIRlRDhWrxlV6UENfbvWPwFL0mpmxzYta1J1NsImJVRsG5K3sLyZFEIdSuvdDHgJr+JyGPfhntbjjUnI1CkD3MOAG8IL82zmvtS+elgpioxC2d+2vOk2ZQqWOYnK1q1eXq2las11zdHFjZLiF8wEF1Irmch0t6mZA6SC3b336RyfXtsGxBqU3OsuZoBneB0dMzbCtubvV53SBvvjSGLWPDleu8aiC4ZMNyUPUXKehilmnFeQLNeL49iNIoRPt9BgFfhBPwwndxg6I8ww6EAY9EBwhHgB1VvKVIVUqUhERviiVqdtonWfKyFyw/EnKLU38YEUSrQpH+YsJ2ovmihkZCQTiRSRCajWYp/AVQInit20r/4USv4QlPRTyv33cvw7v6r+MJe7rcx3rdre1B5H1wmHwxugbfzEaDfINnaG3MfjQR3qtPxZ2/XxDp1ghwbDGTR8Zfu/g64zGQ7vBO1/7wL3/6Dv8SoDfzUBwKnODw2PDmjR6nYaHsWp08v3qDeoR/GhZgm/C8giliVav2ZZeeZy7TeLXESpLjhve2VMfQjpqItx6K684LnSeQcj9roYu30wxpHzwuOA3/GuOn1N+g8Eg5yYnjEX6AL8ANP3D9hHUQIfv15+pB0NGmnxieofkdbtOdISCONOxkEUwip+phOXHZ4z1I4R5Cv8+Uk/nTrhU1yTn5EIZ0mmq5GmAVqflqxYRPh707BmlN6Gl661aa9eH6nDXT/7/kl+7uM7X/VxooF6DrnYMNVvZAgj6I4Mq9Af+T2BRK49IjoHSXzW+rbT9SlRZRy4uGQLZVvnhFlFkdcCEzszOCNMfMK6aJgoATirM/FR66Jh4m1+Tmfiv5m+Cs6L3HIDXr7cV1KXkrL0RVDA6pwo8v8kBu6Jie7o4Uujq/VfsLdtjT+yvcVf&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="0" y="0" width="530" height="230" fill="rgb(255, 255, 255)" stroke="none" pointer-events="all"/><rect x="60" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1</div></div></div></foreignObject><text x="90" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1</text></switch></g><path d="M 160 100 L 126.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 121.12 100 L 128.12 96.5 L 126.37 100 L 128.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 190 130 L 190 150 L 190 140 L 190 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 190 158.88 L 186.5 151.88 L 190 153.63 L 193.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="160" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">2</div></div></div></foreignObject><text x="190" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">2</text></switch></g><path d="M 260 100 L 226.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 221.12 100 L 228.12 96.5 L 226.37 100 L 228.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 290 130 L 290 150 L 290 140 L 290 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 290 158.88 L 286.5 151.88 L 290 153.63 L 293.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="260" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">3</div></div></div></foreignObject><text x="290" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">3</text></switch></g><path d="M 360 100 L 326.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 321.12 100 L 328.12 96.5 L 326.37 100 L 328.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="360" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 361px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">4</div></div></div></foreignObject><text x="390" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">4</text></switch></g><rect x="60" y="40" width="360" height="20" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 50px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencing Window (Epoch 1)</div></div></div></foreignObject><text x="240" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencing Window (Epoch 1)</text></switch></g><path d="M 460 100 L 426.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 421.12 100 L 428.12 96.5 L 426.37 100 L 428.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 490 130 L 490 150 L 490 140 L 490 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 490 158.88 L 486.5 151.88 L 490 153.63 L 493.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">5</div></div></div></foreignObject><text x="490" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">5</text></switch></g><rect x="160" y="10" width="360" height="20" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 20px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencing Window (Epoch 2)</div></div></div></foreignObject><text x="340" y="24" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencing Window (Epoch 2)</text></switch></g><rect x="0" y="85" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1</div></div></div></foreignObject><text x="30" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1</text></switch></g><rect x="160" y="160" width="60" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Deposit</div></div></div></foreignObject><text x="190" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Deposit</text></switch></g><rect x="260" y="160" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="290" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><rect x="160" y="190" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 205px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="190" y="209" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><rect x="460" y="160" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="490" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><rect x="260" y="190" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 205px; margin-left: 261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="290" y="209" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><rect x="0" y="170" width="60" height="40" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 190px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Rollup<br />Node<br />Data</div></div></div></foreignObject><text x="30" y="194" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="531px" height="391px" viewBox="-0.5 -0.5 531 391" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-25T05:14:41.897Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; version=&quot;17.2.2&quot; etag=&quot;dInki-2_90z9NK9_0WDB&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;X8y4w2VaB_uOahkx5CP3&quot;&gt;3Vvbjps6FP2aSD0vFdiBwGMzM71I06rqHKntowMO0DqYOk6TnK8/ZjABsqmazhhc8jKyF+a2vPZmLzszwzebwxtBivQ9jymbISc+zPDtDKFF4Ku/JXCsANfFqEISkcUaa4CH7D+qQUejuyym285AyTmTWdEFI57nNJIdjAjB991ha866dy1IQgHwEBEG0c9ZLNMKDTynwd/SLEnrO7uOPrIh9WANbFMS830LwnczfCM4l1Vrc7ihrCSv5qU67/Uvjp4eTNBcXnKC5v0nYTv9bvq55LF+WcF3eUzL8c4ML/dpJulDQaLy6F5Nr8JSuWGq56rmVgr+nd5wxoVCcp6rYUt9DyokPfzyOd3T2yvZUL6hUhzVkFozc6865SSZmsF9MwEe1ljaIh+HGiR60pPTxRteVENT008TBjS5z+NpnTFWszRDeL1eoygC/Kkjsb/yPd8MiYFzTmIISfR7OPQNUDgHhNFYBZXuciFTnvCcsLsGXXYpbcbcc15oIr9RKY86Q5Cd5F2aq3uWN+rOGt+JSEM6F0kiEio7s30BsYIyIrOf3as/hyXPBkvqLcXxS3n+S6/uftWXe+zcHjq9o+49jV03tEevD+L4mfnOShyHNuN4YVWhbkefjVyfrtAQKtS3J9DgyuK/h90/0LtxekMQ/3iC8a/KSYsJoC7CryYDuLWFaInU4jeqfpyWSGHtNAGRulZFCo3NA/2xo3mU5YnCP2d56buQ8+Ku4FGqGu4/RkmOPRrE8z6SA7TC/mAVvQ85xn0kIxMkw+Q58UzgwUzgWvxcuVZM04DlQB/BteexQrAH0gR0YBPItchqroWu6je5FhnOtYQG616S/Sigq/VQrguPmWsXgOR7uAal3k5esCDX5k9DhGVJrrqRYoMqfFlylUWEvdIHNlkcP+aXvrnpzp4BssF630nhvxE0NsH1tbkwt8+GDVDiPp76SghybA0oeJbLbevKH0ugVcPUqeo01aF3NlvVJZu5Oz3bZdMJXd8tLfg2k2ZTfRDR/lS/Cry5ZygwQBZSNeBogYHsWj/zgYF6rB8eoOB7UmCEwflUGw4MBJ3mvwfVXxJZfqYn54bgusiowYEsB8fCeHTgcT4bFzMMt+EmrVeQy7E7olzteMtDJr/UelTtlnVXvUaqZedPlNrjK/HColKhr5y0UqHBHDWz+lMqO4aS+KJH4hZ3qhE0pNOW+OlHOlYkHgA2P3HGdsUM+ay09CuhWknZ+sBjCtFbIglg/YqXAy5c3/JMzA30j7DU+/sXCQP/TN9zZ7w1QmzXOZrfKsA9ztFmbYyhl5vi1nbonQX6qCK16+AGEGmPgRtieeNigqGBm+TWtuPZTKW2NwWR6XUG3LcraDOXQvdW7rU47/I1NyrXcTauwI8ExixssV3vNkBO/ct8GIY+bJJb2O55iT9qToX26x4WA9drp+buYLurqtv8O0u1SdH8UxC++x8=&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="0" y="0" width="530" height="390" fill="rgb(255, 255, 255)" stroke="none" pointer-events="all"/><rect x="60" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1</div></div></div></foreignObject><text x="90" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1</text></switch></g><path d="M 160 100 L 126.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 121.12 100 L 128.12 96.5 L 126.37 100 L 128.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 190 130 L 190 150 L 190 140 L 190 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 190 158.88 L 186.5 151.88 L 190 153.63 L 193.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="160" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">2</div></div></div></foreignObject><text x="190" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">2</text></switch></g><path d="M 260 100 L 226.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 221.12 100 L 228.12 96.5 L 226.37 100 L 228.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 290 130 L 290 150 L 290 140 L 290 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 290 158.88 L 286.5 151.88 L 290 153.63 L 293.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="260" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">3</div></div></div></foreignObject><text x="290" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">3</text></switch></g><path d="M 360 100 L 326.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 321.12 100 L 328.12 96.5 L 326.37 100 L 328.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="360" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 361px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">4</div></div></div></foreignObject><text x="390" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">4</text></switch></g><rect x="60" y="40" width="360" height="20" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 50px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencing Window (Epoch 1)</div></div></div></foreignObject><text x="240" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencing Window (Epoch 1)</text></switch></g><path d="M 460 100 L 426.37 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 421.12 100 L 428.12 96.5 L 426.37 100 L 428.12 103.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 490 130 L 490 150 L 490 140 L 490 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 490 158.88 L 486.5 151.88 L 490 153.63 L 493.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="70" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">5</div></div></div></foreignObject><text x="490" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">5</text></switch></g><rect x="160" y="10" width="360" height="20" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 358px; height: 1px; padding-top: 20px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencing Window (Epoch 2)</div></div></div></foreignObject><text x="340" y="24" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencing Window (Epoch 2)</text></switch></g><rect x="0" y="85" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 100px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1</div></div></div></foreignObject><text x="30" y="104" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1</text></switch></g><path d="M 160 175 L 145 175 L 145 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 145 278.88 L 141.5 271.88 L 145 273.63 L 148.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="160" y="160" width="60" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Deposit</div></div></div></foreignObject><text x="190" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Deposit</text></switch></g><path d="M 260 175 L 240 175 L 240 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 240 278.88 L 236.5 271.88 L 240 273.63 L 243.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="260" y="160" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="290" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><path d="M 190 220 L 190 250 L 160 250 L 160 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 160 278.88 L 156.5 271.88 L 160 273.63 L 163.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="160" y="190" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 205px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="190" y="209" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><path d="M 460 175 L 430 175 L 430 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 430 278.88 L 426.5 271.88 L 430 273.63 L 433.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="460" y="160" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="490" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><path d="M 355 175 L 335 175 L 335 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 335 278.88 L 331.5 271.88 L 335 273.63 L 338.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="355" y="160" width="60" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 356px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tx Batch</div></div></div></foreignObject><text x="385" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tx Batch</text></switch></g><rect x="0" y="170" width="60" height="50" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 195px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Rollup<br />Node<br />Data</div></div></div></foreignObject><text x="30" y="199" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup...</text></switch></g><rect x="115" y="280" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 310px; margin-left: 116px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">2</div></div></div></foreignObject><text x="145" y="314" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">2</text></switch></g><path d="M 210 310 L 190 310 L 195 310 L 181.37 310" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 176.12 310 L 183.12 306.5 L 181.37 310 L 183.12 313.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="210" y="280" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 310px; margin-left: 211px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">3</div></div></div></foreignObject><text x="240" y="314" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">3</text></switch></g><path d="M 305 310 L 285 310 L 290 310 L 276.37 310" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 271.12 310 L 278.12 306.5 L 276.37 310 L 278.12 313.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="305" y="280" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 310px; margin-left: 306px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">4</div></div></div></foreignObject><text x="335" y="314" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">4</text></switch></g><path d="M 90 190 L 90 235 L 130 235 L 130 273.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 130 278.88 L 126.5 271.88 L 130 273.63 L 133.5 271.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="60" y="160" width="60" height="30" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 175px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Info</div></div></div></foreignObject><text x="90" y="179" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1 Info</text></switch></g><path d="M 400 310 L 380 310 L 385 310 L 371.37 310" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 366.12 310 L 373.12 306.5 L 371.37 310 L 373.12 313.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="400" y="280" width="60" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 310px; margin-left: 401px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">5</div></div></div></foreignObject><text x="430" y="314" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">5</text></switch></g><rect x="0" y="295" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 310px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2</div></div></div></foreignObject><text x="30" y="314" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="601px" height="429px" viewBox="-0.5 -0.5 601 429" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-04-04T03:32:26.727Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36&quot; version=&quot;17.2.5&quot; etag=&quot;mDLUNmfDK830O24fIwir&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;2atPNEeVetM65dO3bovw&quot;&gt;3Vtbb+I4FP41SLsPrexcIDxS2u5UmpWqQXuZp5VJDPE2xMgxU5hfv07ihNgOJEAa6L6g+OTYTs75ztVhYE9X298YWoe/0wBHAwsE24H9OLCskTcUvylhlxMgtGFOWTISSNqeMCM/sSQCSd2QACcKI6c04mStEn0ax9jnCg0xRt9VtgWN1F3XaIkNwsxHkUn9iwQ8zKmeC/b0L5gsw2JnCOSdFSqYJSEJUUDfKyT7aWBPGaU8v1ptpzhKhVfIJZ/3fOBu+WAMx7zNBCuf8ANFG/lu8rn4rnhZHAeTVGZiFNNYEB9CvorECIpLRjdxgNPFgBiJTdnu73Rw7xbD75IzGzxuq5yPOzlKOGJc2yR/DhxomhCcSyxfzTbfFpYyFODDdIXFNoLlfa+lQklhRUEFjeEIcfJD3RFJsCzL5codXikRG1tAAntsu/kUiWvHBuoSCd0wH8tZVa1oC0HoAGUle6itlIvBWElcVN57T8q0Xo8A20DANxpFm7WgPTIhC2YAQtX5e0g4nq2Rn959F/auAkSujhnH24MYPaA1OcEbaWKVsqgoFVo1WrXAYQUqAjsiHceQzlO8JAKgFpi8vlxdNBB44GqycZt9R9/yGFsqVDxTHHXSsGEH4hh+Zlfq3JgrNTxgd750/GGudHR7BiFSK/Xt+7QIr0Yew0js8DAXF8v04hXtIoqCCeeMzDdcJHWSQ6xdMpWz2GHKXQpossIC/6t1/W2G4oCu6u8lm+VSzMXBM8bfsE/WJBVw/S5inQT5nNA4uUy/qWaJyConEVnGgsZpyoDkKMKLdMsFiaIpjSjLNrADF3uBkxk6o2+4csez5vZw2BFsrKEKmzKIVANLnf2Xqe4lwBk3A+eZsrdpSImPZxxxfAlsQoyCh4j6b19QEh6AB1rgBpYFiYXmfuLqUpeAQ9c7wt7Cr9P70PfwfNEWTh8BjiLoNiUdXgfQKPxSBRvP01nfou4iVRk3W5jrmkLsInOD0BDi66RbGfbjpoDjXk+IZu28zqPZy6MhyzT5mskhZTykSyrcxdOeqqV/e56vNDXjTMb/Ys53shuCNpyqGsBbwvOEEbhy+D0bpvVTPt7njOmgSBkrqebYqeaa4N4eew35ZjZ6xUyEXo5ZZXmdNqhPQvM0TpJkLVpNTE8AReuUs7WGzdr4BhI6LZ0tA25DRtdJYIZmPfwSE06yCAzmaeQzo+Oa0WCT5UvXNAuo2IR13CROAGt71QnDtF1ZI1xcHun5mR5bD1Q1ojJEuwrbOmVIjmxkAT1MudX1WkzwlA6kuMifQZu+q5UEXSwSfGlZBs1GBc6aOP8syiTyj3UgMBz8WSi6X4iWDlj1vhC653pfE/HAhUchf6bPrmsmnGAal3ZcXQ1sRVBu6BKcgyKzvyPD/VWDvaLjtoEeqjgbgbNw1sZJjm4sot9ki0aL6GWN0xDR9TOBswRi9mikb0yjR47v1CnqMf2XMtX99ZY8ptUI5MI33gNLMR13aB23nQ7d46g396gjq6jUP8A91vVsbs6yWnY/uygPLbNRIS0Lb7G/4biFdd2UbZ1gWo5afw57s6xxb5alt8D0U4X2xxNaCmPZmo12dz5RvOYt2ah+Zt62nO3GRs0WzueoDJpssY391DVb3O7tp7UubrDZooPTtnuMH841AFd3fJzRnkn6pBJq5Sm2H6EkIX5OlCwqbtXTa9ABbt0a3Hp9+X1Pyyg+rO2iRQXb0b7japoAj/N7jn0Ju3Okp3NOYLrBT0nMb7D6NH6z2fD/OOWyXVOIZcjvXIqjzxSzO3K9bVyoZ7rQoudwldBvNiGmG5Y9hwW+pnfMEkmeNYDw4oP2DlDuQc351nRwhjXHkE4XIDcLb1k93s8PfonQ63HkWD2OHIHjnZbOU5DTy9iOytHCi7cH0h2411LOu2J8WuJyasIxhuq2luscTQh0/uID5YZTnkvOdcRw/118zr7/d4H99B8=&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 125 427 L 125 57" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><rect x="65" y="37" width="120" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 47px; margin-left: 66px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Rollup Driver</div></div></div></foreignObject><text x="125" y="51" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup Driver</text></switch></g><rect x="270" y="37" width="120" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 47px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Engine API</div></div></div></foreignObject><text x="330" y="51" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Engine API</text></switch></g><rect x="115" y="77" width="20" height="310" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 330 427 L 330 57" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><rect x="320" y="77" width="20" height="310" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="450" y="117" width="150" height="100" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 148px; height: 1px; padding-top: 124px; margin-left: 452px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>PayloadAttributes</b><br /><br />- timestamp<br />- random<br />- suggestedFeeRecipient<br />- transactions</div></div></div></foreignObject><text x="452" y="136" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">PayloadAttributes...</text></switch></g><rect x="450" y="22" width="120" height="80" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 118px; height: 1px; padding-top: 29px; margin-left: 452px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>ForkChoiceState</b><br /><br />- headBlockHash<br />- safeBlockHash<br />- finalizedBlockHash</div></div></div></foreignObject><text x="452" y="41" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">ForkChoiceState...</text></switch></g><rect x="180" y="117" width="55" height="20" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 53px; height: 1px; padding-top: 127px; margin-left: 181px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">FCS</div></div></div></foreignObject><text x="208" y="131" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">FCS</text></switch></g><rect x="235" y="117" width="55" height="20" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 53px; height: 1px; padding-top: 127px; margin-left: 236px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">PA</div></div></div></foreignObject><text x="263" y="131" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">PA</text></switch></g><path d="M 331 184.5 L 237.5 184.5 L 150.17 184.56" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 144.92 184.56 L 151.92 181.05 L 150.17 184.56 L 151.92 188.05 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 185px; margin-left: 237px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">payloadID</div></div></div></foreignObject><text x="237" y="188" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">payloadID</text></switch></g><rect x="330" y="97" width="20" height="100" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 350 122 L 390 122 L 390 177 L 356.37 177" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 351.12 177 L 358.12 173.5 L 356.37 177 L 358.12 180.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 153px; margin-left: 390px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">Initiate block<br />production</div></div></div></foreignObject><text x="390" y="156" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">Initiate block...</text></switch></g><path d="M 145 108.22 L 237.5 108.2 L 323.63 108.48" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 328.88 108.5 L 321.87 111.97 L 323.63 108.48 L 321.89 104.97 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 109px; margin-left: 238px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">engine_forkchoiceUpdated[V2|V3]</div></div></div></foreignObject><text x="238" y="112" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">engine_forkchoiceUpdated[V2|V3]</text></switch></g><path d="M 330 252 L 237.5 252 L 151.37 252.09" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 146.12 252.1 L 153.11 248.59 L 151.37 252.09 L 153.12 255.59 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 252px; margin-left: 237px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">payload</div></div></div></foreignObject><text x="237" y="255" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">payload</text></switch></g><rect x="330" y="207" width="20" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 145.4 220.64 L 237.5 220.6 L 237.5 222 L 323.63 222" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 328.88 222 L 321.88 225.5 L 323.63 222 L 321.88 218.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 221px; margin-left: 238px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">engine_getPayload[V2|V3]<br />(payloadID)</div></div></div></foreignObject><text x="238" y="225" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">engine_getPayload[V2|V3]...</text></switch></g><rect x="330" y="277" width="20" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 145.8 286.2 L 237.5 286.2 L 323.63 286.94" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 328.88 286.99 L 321.85 290.43 L 323.63 286.94 L 321.91 283.43 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 287px; margin-left: 238px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">engine_newPayload[V2|V3]<br />(payload)</div></div></div></foreignObject><text x="238" y="290" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">engine_newPayload[V2|V3]...</text></switch></g><rect x="125" y="97" width="20" height="220" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 145 337 L 323.63 337" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 328.88 337 L 321.88 340.5 L 323.63 337 L 321.88 333.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 337px; margin-left: 238px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">engine_forkchoiceUpdated[V2|V3]</div></div></div></foreignObject><text x="238" y="340" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">engine_forkchoiceUpdated[V2|V3]</text></switch></g><rect x="125" y="327" width="20" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 350 337 L 440 337 L 440 7 L 33 7 L 33 37 L 32.55 100.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 32.51 105.88 L 29.06 98.86 L 32.55 100.63 L 36.06 98.91 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="330" y="327" width="20" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="180" y="347" width="100" height="20" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 357px; margin-left: 181px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">FCS</div></div></div></foreignObject><text x="230" y="361" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">FCS</text></switch></g><path d="M 65 127 L 173.63 127" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 127 L 171.88 130.5 L 173.63 127 L 171.88 123.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="0" y="107" width="65" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 63px; height: 1px; padding-top: 127px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Current L2 <br />block hash</div></div></div></foreignObject><text x="33" y="131" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Current L2...</text></switch></g><path d="M 144 251.44 L 105 251.4 L 105 357 L 173.63 357" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 178.88 357 L 171.88 360.5 L 173.63 357 L 171.88 353.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 283px; margin-left: 70px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">payload.blockHash</div></div></div></foreignObject><text x="70" y="287" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">payload.blockHash</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="3562px" height="3884px" viewBox="-0.5 -0.5 3562 3884" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2023-04-11T15:13:26.154Z&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0&quot; etag=&quot;vDBsOIw1GRsWubY4oKHH&quot; version=&quot;21.1.5&quot; type=&quot;google&quot;&gt;&lt;diagram name=&quot;Page-1&quot; id=&quot;5oXVfdM0MUB0GZk8333n&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 22 3760 L 22 3720 L 3142 3720 L 3142 3678 L 3218 3740 L 3142 3802 L 3142 3760 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1200 3620 L 1340 3620 L 1340 3460 L 980 3460 L 980 3365.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 980 3344.47 L 994 3372.47 L 980 3365.47 L 966 3372.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1560 3620 L 1560 3480 L 1940 3480 L 1940 3365.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1940 3344.47 L 1954 3372.47 L 1940 3365.47 L 1926 3372.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 2060 1820 L 2060 1740 L 1180 1740 L 1180 1605.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1180 1584.47 L 1194 1612.47 L 1180 1605.47 L 1166 1612.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 2300 1820 Q 2300 1700 2140 1700 Q 1980 1700 1980 1605.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1980 1584.47 L 1994 1612.47 L 1980 1605.47 L 1966 1612.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1940" y="1820" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 485px; margin-left: 486px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2 Oracle</div></div></div></foreignObject><text x="545" y="489" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Oracle</text></switch></g><path d="M 2260 2700 L 2260 2565.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 2260 2544.47 L 2274 2572.47 L 2260 2565.47 L 2246 2572.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="2060" y="2700" width="400" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 705px; margin-left: 516px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2 Engine API</div></div></div></foreignObject><text x="565" y="709" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Engine API</text></switch></g><path d="M 1940 3100 L 1940 2565.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1940 2544.47 L 1954 2572.47 L 1940 2565.47 L 1926 2572.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 2260 3100 L 2260 2965.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 2260 2944.47 L 2274 2972.47 L 2260 2965.47 L 2246 2972.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1780" y="3100" width="640" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 805px; margin-left: 446px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2 OracleEngine</div></div></div></foreignObject><text x="525" y="809" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 OracleEngine</text></switch></g><path d="M 2100 2300 L 2100 2180 L 2180 2180 L 2180 2085.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 2180 2064.47 L 2194 2092.47 L 2180 2085.47 L 2166 2092.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1940 2300 L 1940 2180 L 1580 2180 L 1580 2085.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1580 2064.47 L 1594 2092.47 L 1580 2085.47 L 1566 2092.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1780" y="2300" width="640" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 605px; margin-left: 446px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">OracleBackedL2Chain</div></div></div></foreignObject><text x="525" y="609" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">OracleBackedL2Chain</text></switch></g><rect x="1900" y="20" width="435" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-dasharray="12 12" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 107px; height: 1px; padding-top: 35px; margin-left: 476px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2 pre-image<br />fetcher</div></div></div></foreignObject><text x="529" y="39" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 pre-image...</text></switch></g><rect x="1220" y="1820" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 485px; margin-left: 306px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Main configuration: chain and rollup configs</div></div></div></foreignObject><text x="365" y="489" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Main configuration:...</text></switch></g><path d="M 1060 860 L 1060 914.53" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1060 935.53 L 1046 907.53 L 1060 914.53 L 1074 907.53 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="820" y="620" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 185px; margin-left: 206px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Preimage KV Store</div></div></div></foreignObject><text x="265" y="189" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Preimage KV Store</text></switch></g><path d="M 980 3100 L 980 2180 L 1340 2180 L 1340 2085.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1340 2064.47 L 1354 2092.47 L 1340 2085.47 L 1326 2092.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 660 3100 L 660 2085.14" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 660 2064.14 L 674 2092.14 L 660 2085.14 L 646 2092.14 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="500" y="3100" width="640" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 805px; margin-left: 126px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 OracleEthClient</div></div></div></foreignObject><text x="205" y="809" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1 OracleEthClient</text></switch></g><path d="M 420 3620 L 420 1460 L 794.53 1460" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 815.53 1460 L 787.53 1474 L 794.53 1460 L 787.53 1446 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 660 3620 L 660 3365.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 660 3344.47 L 674 3372.47 L 660 3365.47 L 646 3372.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="300" y="3620" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 935px; margin-left: 76px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">prologue:<br />dispute and<br />L1 lookup</div></div></div></foreignObject><text x="135" y="939" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">prologue:...</text></switch></g><path d="M 1180 1340 L 1180 1205.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1180 1184.47 L 1194 1212.47 L 1180 1205.47 L 1166 1212.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="820" y="1340" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 365px; margin-left: 206px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Pre-image Oracle<br />Client</div></div></div></foreignObject><text x="265" y="369" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Pre-image Oracle...</text></switch></g><path d="M 740 1820 L 740 1740 L 940 1740 L 940 1605.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 940 1584.47 L 954 1612.47 L 940 1605.47 L 926 1612.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 860 1820 Q 860 1780 1300 1780 Q 1740 1780 1740 1605.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1740 1584.47 L 1754 1612.47 L 1740 1605.47 L 1726 1612.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="500" y="1820" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 485px; margin-left: 126px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 Oracle</div></div></div></foreignObject><text x="185" y="489" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1 Oracle</text></switch></g><path d="M 2180 3620 L 2180 3480 L 2260 3480 L 2260 3365.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 2260 3344.47 L 2274 3372.47 L 2260 3365.47 L 2246 3372.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1900" y="3620" width="560" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 935px; margin-left: 476px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">epilogue:<br />output root construction<br />&amp; claim check</div></div></div></foreignObject><text x="545" y="939" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">epilogue:...</text></switch></g><rect x="2620" y="1340" width="880" height="720" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 218px; height: 1px; padding-top: 342px; margin-left: 657px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 18px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><div style="font-size: 18px;"><b>Program Client</b>:</div><div style="font-size: 18px;">- stateless<br /></div><div style="font-size: 18px;">- no temp errors</div><div style="font-size: 18px;">- no environment access<br />- onchain<br style="font-size: 18px;" /></div></div></div></div></foreignObject><text x="657" y="360" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="18px">Program Client:...</text></switch></g><rect x="2620" y="580" width="920" height="600" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 228px; height: 1px; padding-top: 220px; margin-left: 657px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 18px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><div style="font-size: 18px;"><b>Program Host / VM:</b><br /></div><div style="font-size: 18px;">- stateful</div><div>- pre-image store on disk<br />- offchain<br /></div></div></div></div></foreignObject><text x="657" y="225" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="18px">Program Host / VM:...</text></switch></g><rect x="2550" y="3500" width="760" height="160" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 895px; margin-left: 733px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 23px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: nowrap;">execution trace</div></div></div></foreignObject><text x="733" y="902" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="23px" text-anchor="middle" font-weight="bold">execution trace</text></switch></g><path d="M 180 1260 L 3380 1260" fill="none" stroke="#ff0000" stroke-width="12" stroke-miterlimit="10" stroke-dasharray="36 36" pointer-events="stroke"/><path d="M 1860 1340 L 1860 1085.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" stroke-dasharray="12 12" pointer-events="stroke"/><path d="M 1860 1064.47 L 1874 1092.47 L 1860 1085.47 L 1846 1092.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1620" y="1340" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 365px; margin-left: 406px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Pre-image Hint<br />Writer</div></div></div></foreignObject><text x="465" y="369" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Pre-image Hint...</text></switch></g><rect x="1020" y="3620" width="720" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 935px; margin-left: 256px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">derivation loop</div></div></div></foreignObject><text x="345" y="939" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">derivation loop</text></switch></g><path d="M 1860 820 L 1860 485.47" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" stroke-dasharray="12 12" pointer-events="stroke"/><path d="M 1860 464.47 L 1874 492.47 L 1860 485.47 L 1846 492.47 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1620" y="820" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-dasharray="12 12" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 235px; margin-left: 406px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Pre-image Hint<br />Reader</div></div></div></foreignObject><text x="465" y="239" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Pre-image Hint...</text></switch></g><path d="M 940 1180 L 940 1314.53" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 940 1335.53 L 926 1307.53 L 940 1314.53 L 954 1307.53 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="820" y="940" width="480" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 265px; margin-left: 206px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Pre-image Oracle<br />Server</div></div></div></foreignObject><text x="265" y="269" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Pre-image Oracle...</text></switch></g><rect x="2620" y="100" width="690" height="340" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 171px; height: 1px; padding-top: 107px; margin-left: 657px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 18px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>Program tools:</b><br />- pre-image fetching<br />- retry on fetch errors</div></div></div></foreignObject><text x="657" y="107" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="18px">Program tools:...</text></switch></g><rect x="1385" y="20" width="395" height="240" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-dasharray="12 12" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 97px; height: 1px; padding-top: 35px; margin-left: 347px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1 pre-image<br />fetcher</div></div></div></foreignObject><text x="396" y="39" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1 pre-image...</text></switch></g><path d="M 1622.5 460 L 1622.33 740 L 1325.47 740" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" stroke-dasharray="12 12" pointer-events="stroke"/><path d="M 1304.47 740 L 1332.47 726 L 1325.47 740 L 1332.47 754 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 1622.5 360 L 1623.3 285.71" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" stroke-dasharray="12 12" pointer-events="stroke"/><path d="M 1623.53 264.71 L 1637.23 292.86 L 1623.3 285.71 L 1609.23 292.56 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><path d="M 2097.5 360 L 2098.13 292.19" fill="none" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" stroke-dasharray="12 12" pointer-events="stroke"/><path d="M 2098.32 271.19 L 2112.06 299.32 L 2098.13 292.19 L 2084.06 299.06 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-miterlimit="10" pointer-events="all"/><rect x="1385" y="360" width="950" height="100" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-width="4" stroke-dasharray="12 12" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 236px; height: 1px; padding-top: 103px; margin-left: 347px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Pre-image hint router</div></div></div></foreignObject><text x="465" y="106" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Pre-image hint router</text></switch></g><path d="M 180 540 L 3380 540" fill="none" stroke="#ff0000" stroke-width="12" stroke-miterlimit="10" stroke-dasharray="36 36" pointer-events="stroke"/><rect x="1880" y="1020" width="760" height="320" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)scale(4)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 188px; height: 1px; padding-top: 295px; margin-left: 472px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; font-style: italic; white-space: normal; overflow-wrap: normal;">No-op when onchain / readonly</div></div></div></foreignObject><text x="472" y="299" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="14px" font-style="italic">No-op when onchain / readon...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="681px" height="288px" viewBox="-0.5 -0.5 681 288" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2021-10-26T23:04:31.251Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36&quot; etag=&quot;3pV1yNZio6qA20qfroQ8&quot; version=&quot;15.5.9&quot; type=&quot;device&quot; pages=&quot;5&quot;&gt;&lt;diagram id=&quot;pa5Zq7vvImeQUXFm5tUZ&quot; name=&quot;Verifier&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;6hN7fcHnLs0WyHn6UafR&quot; name=&quot;Sequencer&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;-hkjP0EtaJXZYg540UFq&quot; name=&quot;Withdrawal&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;YIQN2cyMAm-IvyV_td1r&quot; name=&quot;Network High Level&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;DTTy1wCJd32_-uvfoNST&quot; name=&quot;Pluggable Proof&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="0" y="48" width="570" height="40" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 568px; height: 1px; padding-top: 68px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Ethereum L1 Chain</div></div></div></foreignObject><text x="285" y="72" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Ethereum L1 Chain</text></switch></g><path d="M 35 68 L 25 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="35" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 55 68 L 45 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="55" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 75 68 L 65 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="75" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 95 68 L 85 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="95" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 115 68 L 105 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="115" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 135 68 L 125 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="135" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 155 68 L 145 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="155" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 175 68 L 165 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="175" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 387.5 68 L 377.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="387.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 407.5 68 L 397.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="407.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 427.5 68 L 417.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="427.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 447.5 68 L 437.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="447.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 467.5 68 L 457.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="467.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 487.5 68 L 477.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="487.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 507.5 68 L 497.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="507.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 527.5 68 L 517.5 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><rect x="527.5" y="63" width="10" height="10" fill="#ffffff" stroke="#000000" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 678px; height: 1px; padding-top: 30px; margin-left: 2px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><h1>Network Participants Overview</h1></div></div></div></foreignObject><text x="2" y="34" fill="#000000" font-family="Helvetica" font-size="12px">Network Participants Overview</text></switch></g><path d="M 256 197 L 178.5 197 L 178.5 198 L 107.37 198" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 102.12 198 L 109.12 194.5 L 107.37 198 L 109.12 201.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 204px; margin-left: 178px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">Query data<br />(eg. block explorers)</div></div></div></foreignObject><text x="178" y="208" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Query data...</text></switch></g><path d="M 314 197 L 382 197 L 382 198 L 443.63 198" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 448.88 198 L 441.88 201.5 L 443.63 198 L 441.88 194.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 197px; margin-left: 378px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">Submit transactions</div></div></div></foreignObject><text x="378" y="201" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Submit transactions</text></switch></g><path d="M 285 168 L 285 94.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 285 89.12 L 288.5 96.12 L 285 94.37 L 281.5 96.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 128px; margin-left: 287px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">Submit deposits</div></div></div></foreignObject><text x="287" y="131" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Submit deposits</text></switch></g><path d="M 291.12 177.6 C 291.12 173.76 294.3 170.64 298.21 170.64 C 302.12 170.64 305.3 173.76 305.3 177.6 C 305.3 181.45 302.12 184.57 298.21 184.57 C 294.3 184.57 291.12 181.45 291.12 177.6 Z M 306.31 186.89 C 305.45 186.36 304.55 185.93 303.62 185.58 C 306.22 183.85 307.93 180.92 307.93 177.6 C 307.93 172.31 303.57 168 298.21 168 C 292.84 168 288.48 172.31 288.48 177.6 C 288.48 180.91 290.18 183.84 292.77 185.56 C 291.08 186.2 289.49 187.13 288.1 188.33 L 289.81 190.33 C 292.16 188.32 295.14 187.21 298.18 187.21 C 300.56 187.21 302.89 187.87 304.92 189.13 C 308.53 191.38 310.9 195.32 311.3 199.64 L 298.18 199.64 L 298.18 202.27 L 312.68 202.27 C 313.41 202.27 314 201.68 314 200.95 C 314 195.23 311.05 189.84 306.31 186.89 Z M 264.75 177.6 C 264.75 173.76 267.93 170.64 271.84 170.64 C 275.75 170.64 278.93 173.76 278.93 177.6 C 278.93 181.45 275.75 184.57 271.84 184.57 C 267.93 184.57 264.75 181.45 264.75 177.6 Z M 271.82 199.64 L 258.7 199.64 C 259.34 192.67 264.98 187.21 271.82 187.21 C 274.19 187.21 276.52 187.87 278.55 189.13 C 279.12 189.49 279.67 189.89 280.19 190.33 L 281.9 188.33 C 281.29 187.8 280.63 187.32 279.94 186.89 C 279.09 186.36 278.19 185.93 277.26 185.58 C 279.86 183.85 281.57 180.92 281.57 177.6 C 281.57 172.31 277.21 168 271.84 168 C 266.48 168 262.12 172.31 262.12 177.6 C 262.12 180.92 263.83 183.85 266.42 185.57 C 260.35 187.87 256 193.89 256 200.95 C 256 201.68 256.59 202.27 257.32 202.27 L 271.82 202.27 Z M 271.88 223.36 C 272.52 216.4 278.16 210.94 285 210.94 C 287.38 210.94 289.7 211.6 291.73 212.86 C 295.35 215.11 297.72 219.05 298.12 223.36 Z M 277.93 201.33 C 277.93 197.49 281.11 194.36 285.03 194.36 C 288.93 194.36 292.11 197.49 292.11 201.33 C 292.11 205.17 288.93 208.3 285.03 208.3 C 281.11 208.3 277.93 205.17 277.93 201.33 Z M 293.12 210.62 C 292.27 210.09 291.37 209.65 290.44 209.3 C 293.04 207.58 294.75 204.65 294.75 201.33 C 294.75 196.04 290.39 191.73 285.03 191.73 C 279.66 191.73 275.3 196.04 275.3 201.33 C 275.3 204.65 277.01 207.58 279.6 209.3 C 273.53 211.59 269.18 217.61 269.18 224.68 C 269.18 225.41 269.77 226 270.5 226 L 299.5 226 C 300.23 226 300.82 225.41 300.82 224.68 C 300.82 218.96 297.87 213.57 293.12 210.62 Z" fill="#232f3e" stroke="none" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 233px; margin-left: 285px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(35, 47, 62); line-height: 1.2; pointer-events: none; white-space: nowrap;">Users</div></div></div></foreignObject><text x="285" y="245" fill="#232F3E" font-family="Helvetica" font-size="12px" text-anchor="middle">Users</text></switch></g><path d="M 480 153 L 480 120.5 L 480.41 94.89" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 480.49 89.64 L 483.88 96.69 L 480.41 94.89 L 476.88 96.58 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 121px; margin-left: 481px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">Submit batches and assertions</div></div></div></foreignObject><text x="481" y="124" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Submit batches and assertions</text></switch></g><path d="M 53.77 177.99 C 52.57 177.97 51.37 178 50.18 178.09 C 49.39 178.15 48.6 178.29 47.83 178.52 L 47.83 178.88 L 44.82 178.88 C 44.84 178.44 44.89 178 44.97 177.56 C 45.26 176.65 45.9 175.92 46.72 175.57 C 48.03 175.04 49.42 174.77 50.81 174.77 L 50.81 172.15 L 40 172.15 L 40 153 L 64.85 153 L 64.85 165.31 L 61.87 165.31 L 61.87 156.35 L 43.01 156.35 L 43.01 168.86 L 53.77 168.86 Z M 54.97 183 L 54.97 167.3 L 66.84 167.3 L 66.84 168.93 L 56.45 168.93 L 56.45 181.34 L 67.65 181.34 L 67.65 175.83 L 69.13 175.83 L 69.13 183 Z M 63.19 179.35 L 58.4 174.4 L 59.94 172.61 L 63.04 175.77 L 68.28 168.9 L 70 170.46 Z" fill="#505050" stroke="none" pointer-events="none"/><path d="M 96.29 178.99 C 94.96 178.97 93.64 179 92.31 179.09 C 91.43 179.15 90.55 179.29 89.7 179.52 L 89.7 179.88 L 86.35 179.88 C 86.38 179.44 86.44 179 86.52 178.56 C 86.84 177.65 87.55 176.92 88.46 176.57 C 89.92 176.04 91.46 175.77 93.01 175.77 L 93.01 173.15 L 81 173.15 L 81 154 L 108.61 154 L 108.61 166.31 L 105.29 166.31 L 105.29 157.35 L 84.35 157.35 L 84.35 169.86 L 96.29 169.86 Z M 97.63 184 L 97.63 168.3 L 110.82 168.3 L 110.82 169.93 L 99.27 169.93 L 99.27 182.34 L 111.72 182.34 L 111.72 176.83 L 113.36 176.83 L 113.36 184 Z M 106.77 180.35 L 101.45 175.4 L 103.15 173.61 L 106.6 176.77 L 112.42 169.9 L 114.33 171.46 Z" fill="#505050" stroke="none" pointer-events="none"/><path d="M 78 254.37 L 78 278 L 480 278 L 480 254.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 78 249.12 L 81.5 256.12 L 78 254.37 L 74.5 256.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 249.12 L 483.5 256.12 L 480 254.37 L 476.5 256.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 280px; margin-left: 285px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">P2P Realtime Updates</div></div></div></foreignObject><text x="285" y="284" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">P2P Realtime Updates</text></switch></g><path d="M 76.29 211.99 C 74.96 211.97 73.64 212 72.31 212.09 C 71.43 212.15 70.55 212.29 69.7 212.52 L 69.7 212.88 L 66.35 212.88 C 66.38 212.44 66.44 212 66.52 211.56 C 66.84 210.65 67.55 209.92 68.46 209.57 C 69.92 209.04 71.46 208.77 73.01 208.77 L 73.01 206.15 L 61 206.15 L 61 187 L 88.61 187 L 88.61 199.31 L 85.29 199.31 L 85.29 190.35 L 64.35 190.35 L 64.35 202.86 L 76.29 202.86 Z M 77.63 217 L 77.63 201.3 L 90.82 201.3 L 90.82 202.93 L 79.27 202.93 L 79.27 215.34 L 91.72 215.34 L 91.72 209.83 L 93.36 209.83 L 93.36 217 Z M 86.77 213.35 L 81.45 208.4 L 83.15 206.61 L 86.6 209.77 L 92.42 202.9 L 94.33 204.46 Z" fill="#505050" stroke="none" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 224px; margin-left: 78px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;">Verifiers</div></div></div></foreignObject><text x="78" y="235" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Verifi...</text></switch></g><path d="M 76 155 L 76.86 96.53" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 76.93 91.28 L 80.33 98.33 L 76.86 96.53 L 73.33 98.23 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 124px; margin-left: 77px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">Verify block hash assertions &amp;<br />submit fault proofs</div></div></div></foreignObject><text x="77" y="127" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">Verify block hash assertions &amp;...</text></switch></g><g fill="#000000" font-family="Helvetica" pointer-events="none" text-anchor="middle" font-size="12px"><text x="479.5" y="226.5">Sequencers</text></g><rect x="450" y="153" width="60" height="60" fill="#ffffff" stroke="#000000" pointer-events="none"/><image x="456.5" y="156.5" width="18.73" height="17" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjYuOTk4NDEzMDg1OTM3NSIgaGVpZ2h0PSI0NzguMjEyNzk5MDcyMjY1NiIgdmlld0JveD0iMC42MTA1OTYwNjA3NTI4Njg3IDAuNjEzMTgwMDQxMzEzMTcxNCA1MjYuOTk4NDEzMDg1OTM3NSA0NzguMjEyNzk5MDcyMjY1NiIgZmlsbD0ibm9uZSI+JiN4YTs8cGF0aCBkPSJNNTE0LjE2NSAyNzcuMTczSDE0LjQzODZWMzQyLjQ2NkMxNC40Mzg2IDM1MS42OTMgMTguMjc4NiAzNjAuNTIgMjQuNDI1MiAzNjYuNjY2QzMwLjU3MDYgMzcyLjgxMyAzOS4wMjEyIDM3Ni42NTMgNDguMjM5OSAzNzYuNjUzSDIyMi4yNDFIMzA1Ljk3N0g0NzkuOTc5QzQ4OS4xOTcgMzc2LjY1MyA0OTguMDMyIDM3Mi44MTMgNTA0LjE3OSAzNjYuNjY2QzUxMC4zMjQgMzYwLjUyIDUxNC4xNjUgMzUxLjY5MyA1MTQuMTY1IDM0Mi40NjZWMjc3LjE3M1pNMTQuNDM4NiAyNjMuNzMzSDUxNC4xNjVWNDcuODUyOEM1MTQuMTY1IDM4LjYzOTQgNTEwLjMyNCAzMC4xODY0IDUwNC4xNzkgMjQuMDM5N0M0OTguMDMyIDE3Ljg5MzEgNDg5LjE5NyAxNC4wNTI4IDQ3OS45NzkgMTQuMDUyOEg0OC4yMzk5QzM5LjAyMTIgMTQuMDUyOCAzMC41NzA2IDE3Ljg5MzEgMjQuNDI1MiAyNC4wMzk3QzE4LjI3ODYgMzAuMTg2NCAxNC40Mzg2IDM4LjYzOTQgMTQuNDM4NiA0Ny44NTI4VjI2My43MzNaTTIyOS4xNTYgNDY1LjM4NkgyOTkuNDQ4VjM5MC4wOTNIMjI5LjE1NlY0NjUuMzg2Wk0yNzEuNzkyIDMyMC41NzNDMjY5Ljg3MSAzMTguNjUzIDI2Ny4xODMgMzE3LjUwNiAyNjQuMTExIDMxNy41MDZDMjYxLjAzNyAzMTcuNTA2IDI1OC4zNDggMzE4LjY1MyAyNTYuNDI4IDMyMC41NzNDMjU0LjUwNyAzMjIuNDkzIDI1My4zNTUgMzI1LjE4NiAyNTMuMzU1IDMyOC4yNTNDMjUzLjM1NSAzMzEuMzMzIDI1NC41MDcgMzM0LjAxMyAyNTYuNDI4IDMzNS45NDZDMjU4LjM0OCAzMzguMjQgMjYxLjAzNyAzMzkuNCAyNjQuMTExIDMzOS40QzI2Ny4xODMgMzM5LjQgMjY5Ljg3MSAzMzguMjQgMjcxLjc5MiAzMzUuOTQ2QzI3NC4wOTYgMzM0LjAxMyAyNzUuMjQ5IDMzMS4zMzMgMjc1LjI0OSAzMjguMjUzQzI3NS4yNDkgMzI1LjE4NiAyNzQuMDk2IDMyMi40OTMgMjcxLjc5MiAzMjAuNTczWk0yNjQuMTExIDMwMy42OEMyNzEuMDI0IDMwMy42OCAyNzcuMTY5IDMwNi4zNiAyODEuMzk1IDMxMC45NzNDMjg2LjAwNCAzMTUuNTg2IDI4OC42OTMgMzIxLjczMyAyODguNjkzIDMyOC4yNTNDMjg4LjY5MyAzMzUuMTczIDI4Ni4wMDQgMzQxLjMyIDI4MS4zOTUgMzQ1LjU0NkMyNzcuMTY5IDM1MC4xNDYgMjcxLjAyNCAzNTIuODQgMjY0LjExMSAzNTIuODRDMjU3LjU4IDM1Mi44NCAyNTEuNDM1IDM1MC4xNDYgMjQ2LjgyNSAzNDUuNTQ2QzI0Mi4yMTYgMzQxLjMyIDIzOS41MjcgMzM1LjE3MyAyMzkuNTI3IDMyOC4yNTNDMjM5LjUyNyAzMjEuNzMzIDI0Mi4yMTYgMzE1LjU4NiAyNDYuODI1IDMxMC45NzNDMjUxLjQzNSAzMDYuMzYgMjU3LjU4IDMwMy42OCAyNjQuMTExIDMwMy42OFpNNDguMjM5OSAwLjYxMzE4SDQ3OS45NzlDNDkzLjAzOSAwLjYxMzE4IDUwNC45NDcgNS45ODY0MSA1MTMuMzk3IDE0LjQzOTdDNTIyLjIzMiAyMy4yNzk3IDUyNy42MDkgMzQuNzk5NCA1MjcuNjA5IDQ3Ljg1MjhWMjcwLjI1M1YzNDIuNDY2QzUyNy42MDkgMzU1LjUzMyA1MjIuMjMyIDM2Ny40NCA1MTMuNzgxIDM3Ni4yNjZDNTA0Ljk0NyAzODQuNzIgNDkzLjAzOSAzOTAuMDkzIDQ3OS45NzkgMzkwLjA5M0gzMTIuODkyVjQ2NS4zODZIMzcyLjQyOEMzNzYuMjY5IDQ2NS4zODYgMzc5LjM0MyA0NjguNDUzIDM3OS4zNDMgNDcxLjkyQzM3OS4zNDMgNDc1Ljc2IDM3Ni4yNjkgNDc4LjgyNiAzNzIuNDI4IDQ3OC44MjZIMzA2LjM2MUgzMDUuOTc3SDIyMi4yNDFIMjIxLjg1N0gxNTUuNzkxQzE1Mi4zMzMgNDc4LjgyNiAxNDkuMjYxIDQ3NS43NiAxNDkuMjYxIDQ3MS45MkMxNDkuMjYxIDQ2OC40NTMgMTUyLjMzMyA0NjUuMzg2IDE1NS43OTEgNDY1LjM4NkgyMTUuMzI4VjM5MC4wOTNINDguMjM5OUMzNS4xNzk5IDM5MC4wOTMgMjMuMjczMiAzODQuNzIgMTQuODIyNiAzNzYuMjY2QzUuOTg3OTEgMzY3LjQ0IDAuNjEwNTk2IDM1NS41MzMgMC42MTA1OTYgMzQyLjQ2NlYyNzAuMjUzVjQ3Ljg1MjhDMC42MTA1OTYgMzQuNzk5NCA1Ljk4NzkxIDIzLjI3OTcgMTQuODIyNiAxNC40Mzk3QzIzLjI3MzIgNS45ODY0MSAzNS4xNzk5IDAuNjEzMTggNDguMjM5OSAwLjYxMzE4IiBmaWxsPSIjMkUyRDJEIi8+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><path d="M 487 165.5 L 475.73 165.5" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><image x="486.5" y="156.5" width="18.73" height="17" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjYuOTk4NDEzMDg1OTM3NSIgaGVpZ2h0PSI0NzguMjEyNzk5MDcyMjY1NiIgdmlld0JveD0iMC42MTA1OTYwNjA3NTI4Njg3IDAuNjEzMTgwMDQxMzEzMTcxNCA1MjYuOTk4NDEzMDg1OTM3NSA0NzguMjEyNzk5MDcyMjY1NiIgZmlsbD0ibm9uZSI+JiN4YTs8cGF0aCBkPSJNNTE0LjE2NSAyNzcuMTczSDE0LjQzODZWMzQyLjQ2NkMxNC40Mzg2IDM1MS42OTMgMTguMjc4NiAzNjAuNTIgMjQuNDI1MiAzNjYuNjY2QzMwLjU3MDYgMzcyLjgxMyAzOS4wMjEyIDM3Ni42NTMgNDguMjM5OSAzNzYuNjUzSDIyMi4yNDFIMzA1Ljk3N0g0NzkuOTc5QzQ4OS4xOTcgMzc2LjY1MyA0OTguMDMyIDM3Mi44MTMgNTA0LjE3OSAzNjYuNjY2QzUxMC4zMjQgMzYwLjUyIDUxNC4xNjUgMzUxLjY5MyA1MTQuMTY1IDM0Mi40NjZWMjc3LjE3M1pNMTQuNDM4NiAyNjMuNzMzSDUxNC4xNjVWNDcuODUyOEM1MTQuMTY1IDM4LjYzOTQgNTEwLjMyNCAzMC4xODY0IDUwNC4xNzkgMjQuMDM5N0M0OTguMDMyIDE3Ljg5MzEgNDg5LjE5NyAxNC4wNTI4IDQ3OS45NzkgMTQuMDUyOEg0OC4yMzk5QzM5LjAyMTIgMTQuMDUyOCAzMC41NzA2IDE3Ljg5MzEgMjQuNDI1MiAyNC4wMzk3QzE4LjI3ODYgMzAuMTg2NCAxNC40Mzg2IDM4LjYzOTQgMTQuNDM4NiA0Ny44NTI4VjI2My43MzNaTTIyOS4xNTYgNDY1LjM4NkgyOTkuNDQ4VjM5MC4wOTNIMjI5LjE1NlY0NjUuMzg2Wk0yNzEuNzkyIDMyMC41NzNDMjY5Ljg3MSAzMTguNjUzIDI2Ny4xODMgMzE3LjUwNiAyNjQuMTExIDMxNy41MDZDMjYxLjAzNyAzMTcuNTA2IDI1OC4zNDggMzE4LjY1MyAyNTYuNDI4IDMyMC41NzNDMjU0LjUwNyAzMjIuNDkzIDI1My4zNTUgMzI1LjE4NiAyNTMuMzU1IDMyOC4yNTNDMjUzLjM1NSAzMzEuMzMzIDI1NC41MDcgMzM0LjAxMyAyNTYuNDI4IDMzNS45NDZDMjU4LjM0OCAzMzguMjQgMjYxLjAzNyAzMzkuNCAyNjQuMTExIDMzOS40QzI2Ny4xODMgMzM5LjQgMjY5Ljg3MSAzMzguMjQgMjcxLjc5MiAzMzUuOTQ2QzI3NC4wOTYgMzM0LjAxMyAyNzUuMjQ5IDMzMS4zMzMgMjc1LjI0OSAzMjguMjUzQzI3NS4yNDkgMzI1LjE4NiAyNzQuMDk2IDMyMi40OTMgMjcxLjc5MiAzMjAuNTczWk0yNjQuMTExIDMwMy42OEMyNzEuMDI0IDMwMy42OCAyNzcuMTY5IDMwNi4zNiAyODEuMzk1IDMxMC45NzNDMjg2LjAwNCAzMTUuNTg2IDI4OC42OTMgMzIxLjczMyAyODguNjkzIDMyOC4yNTNDMjg4LjY5MyAzMzUuMTczIDI4Ni4wMDQgMzQxLjMyIDI4MS4zOTUgMzQ1LjU0NkMyNzcuMTY5IDM1MC4xNDYgMjcxLjAyNCAzNTIuODQgMjY0LjExMSAzNTIuODRDMjU3LjU4IDM1Mi44NCAyNTEuNDM1IDM1MC4xNDYgMjQ2LjgyNSAzNDUuNTQ2QzI0Mi4yMTYgMzQxLjMyIDIzOS41MjcgMzM1LjE3MyAyMzkuNTI3IDMyOC4yNTNDMjM5LjUyNyAzMjEuNzMzIDI0Mi4yMTYgMzE1LjU4NiAyNDYuODI1IDMxMC45NzNDMjUxLjQzNSAzMDYuMzYgMjU3LjU4IDMwMy42OCAyNjQuMTExIDMwMy42OFpNNDguMjM5OSAwLjYxMzE4SDQ3OS45NzlDNDkzLjAzOSAwLjYxMzE4IDUwNC45NDcgNS45ODY0MSA1MTMuMzk3IDE0LjQzOTdDNTIyLjIzMiAyMy4yNzk3IDUyNy42MDkgMzQuNzk5NCA1MjcuNjA5IDQ3Ljg1MjhWMjcwLjI1M1YzNDIuNDY2QzUyNy42MDkgMzU1LjUzMyA1MjIuMjMyIDM2Ny40NCA1MTMuNzgxIDM3Ni4yNjZDNTA0Ljk0NyAzODQuNzIgNDkzLjAzOSAzOTAuMDkzIDQ3OS45NzkgMzkwLjA5M0gzMTIuODkyVjQ2NS4zODZIMzcyLjQyOEMzNzYuMjY5IDQ2NS4zODYgMzc5LjM0MyA0NjguNDUzIDM3OS4zNDMgNDcxLjkyQzM3OS4zNDMgNDc1Ljc2IDM3Ni4yNjkgNDc4LjgyNiAzNzIuNDI4IDQ3OC44MjZIMzA2LjM2MUgzMDUuOTc3SDIyMi4yNDFIMjIxLjg1N0gxNTUuNzkxQzE1Mi4zMzMgNDc4LjgyNiAxNDkuMjYxIDQ3NS43NiAxNDkuMjYxIDQ3MS45MkMxNDkuMjYxIDQ2OC40NTMgMTUyLjMzMyA0NjUuMzg2IDE1NS43OTEgNDY1LjM4NkgyMTUuMzI4VjM5MC4wOTNINDguMjM5OUMzNS4xNzk5IDM5MC4wOTMgMjMuMjczMiAzODQuNzIgMTQuODIyNiAzNzYuMjY2QzUuOTg3OTEgMzY3LjQ0IDAuNjEwNTk2IDM1NS41MzMgMC42MTA1OTYgMzQyLjQ2NlYyNzAuMjUzVjQ3Ljg1MjhDMC42MTA1OTYgMzQuNzk5NCA1Ljk4NzkxIDIzLjI3OTcgMTQuODIyNiAxNC40Mzk3QzIzLjI3MzIgNS45ODY0MSAzNS4xNzk5IDAuNjEzMTggNDguMjM5OSAwLjYxMzE4IiBmaWxsPSIjMkUyRDJEIi8+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><path d="M 471.52 182.22 L 466.37 174" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><path d="M 491.19 182.9 L 496.37 174" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><image x="462.54" y="181.72" width="33.92" height="30.78" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjYuOTk4NDEzMDg1OTM3NSIgaGVpZ2h0PSI0NzguMjEyNzk5MDcyMjY1NiIgdmlld0JveD0iMC42MTA1OTYwNjA3NTI4Njg3IDAuNjEzMTgwMDQxMzEzMTcxNCA1MjYuOTk4NDEzMDg1OTM3NSA0NzguMjEyNzk5MDcyMjY1NiIgZmlsbD0ibm9uZSI+JiN4YTs8cGF0aCBkPSJNNTE0LjE2NSAyNzcuMTczSDE0LjQzODZWMzQyLjQ2NkMxNC40Mzg2IDM1MS42OTMgMTguMjc4NiAzNjAuNTIgMjQuNDI1MiAzNjYuNjY2QzMwLjU3MDYgMzcyLjgxMyAzOS4wMjEyIDM3Ni42NTMgNDguMjM5OSAzNzYuNjUzSDIyMi4yNDFIMzA1Ljk3N0g0NzkuOTc5QzQ4OS4xOTcgMzc2LjY1MyA0OTguMDMyIDM3Mi44MTMgNTA0LjE3OSAzNjYuNjY2QzUxMC4zMjQgMzYwLjUyIDUxNC4xNjUgMzUxLjY5MyA1MTQuMTY1IDM0Mi40NjZWMjc3LjE3M1pNMTQuNDM4NiAyNjMuNzMzSDUxNC4xNjVWNDcuODUyOEM1MTQuMTY1IDM4LjYzOTQgNTEwLjMyNCAzMC4xODY0IDUwNC4xNzkgMjQuMDM5N0M0OTguMDMyIDE3Ljg5MzEgNDg5LjE5NyAxNC4wNTI4IDQ3OS45NzkgMTQuMDUyOEg0OC4yMzk5QzM5LjAyMTIgMTQuMDUyOCAzMC41NzA2IDE3Ljg5MzEgMjQuNDI1MiAyNC4wMzk3QzE4LjI3ODYgMzAuMTg2NCAxNC40Mzg2IDM4LjYzOTQgMTQuNDM4NiA0Ny44NTI4VjI2My43MzNaTTIyOS4xNTYgNDY1LjM4NkgyOTkuNDQ4VjM5MC4wOTNIMjI5LjE1NlY0NjUuMzg2Wk0yNzEuNzkyIDMyMC41NzNDMjY5Ljg3MSAzMTguNjUzIDI2Ny4xODMgMzE3LjUwNiAyNjQuMTExIDMxNy41MDZDMjYxLjAzNyAzMTcuNTA2IDI1OC4zNDggMzE4LjY1MyAyNTYuNDI4IDMyMC41NzNDMjU0LjUwNyAzMjIuNDkzIDI1My4zNTUgMzI1LjE4NiAyNTMuMzU1IDMyOC4yNTNDMjUzLjM1NSAzMzEuMzMzIDI1NC41MDcgMzM0LjAxMyAyNTYuNDI4IDMzNS45NDZDMjU4LjM0OCAzMzguMjQgMjYxLjAzNyAzMzkuNCAyNjQuMTExIDMzOS40QzI2Ny4xODMgMzM5LjQgMjY5Ljg3MSAzMzguMjQgMjcxLjc5MiAzMzUuOTQ2QzI3NC4wOTYgMzM0LjAxMyAyNzUuMjQ5IDMzMS4zMzMgMjc1LjI0OSAzMjguMjUzQzI3NS4yNDkgMzI1LjE4NiAyNzQuMDk2IDMyMi40OTMgMjcxLjc5MiAzMjAuNTczWk0yNjQuMTExIDMwMy42OEMyNzEuMDI0IDMwMy42OCAyNzcuMTY5IDMwNi4zNiAyODEuMzk1IDMxMC45NzNDMjg2LjAwNCAzMTUuNTg2IDI4OC42OTMgMzIxLjczMyAyODguNjkzIDMyOC4yNTNDMjg4LjY5MyAzMzUuMTczIDI4Ni4wMDQgMzQxLjMyIDI4MS4zOTUgMzQ1LjU0NkMyNzcuMTY5IDM1MC4xNDYgMjcxLjAyNCAzNTIuODQgMjY0LjExMSAzNTIuODRDMjU3LjU4IDM1Mi44NCAyNTEuNDM1IDM1MC4xNDYgMjQ2LjgyNSAzNDUuNTQ2QzI0Mi4yMTYgMzQxLjMyIDIzOS41MjcgMzM1LjE3MyAyMzkuNTI3IDMyOC4yNTNDMjM5LjUyNyAzMjEuNzMzIDI0Mi4yMTYgMzE1LjU4NiAyNDYuODI1IDMxMC45NzNDMjUxLjQzNSAzMDYuMzYgMjU3LjU4IDMwMy42OCAyNjQuMTExIDMwMy42OFpNNDguMjM5OSAwLjYxMzE4SDQ3OS45NzlDNDkzLjAzOSAwLjYxMzE4IDUwNC45NDcgNS45ODY0MSA1MTMuMzk3IDE0LjQzOTdDNTIyLjIzMiAyMy4yNzk3IDUyNy42MDkgMzQuNzk5NCA1MjcuNjA5IDQ3Ljg1MjhWMjcwLjI1M1YzNDIuNDY2QzUyNy42MDkgMzU1LjUzMyA1MjIuMjMyIDM2Ny40NCA1MTMuNzgxIDM3Ni4yNjZDNTA0Ljk0NyAzODQuNzIgNDkzLjAzOSAzOTAuMDkzIDQ3OS45NzkgMzkwLjA5M0gzMTIuODkyVjQ2NS4zODZIMzcyLjQyOEMzNzYuMjY5IDQ2NS4zODYgMzc5LjM0MyA0NjguNDUzIDM3OS4zNDMgNDcxLjkyQzM3OS4zNDMgNDc1Ljc2IDM3Ni4yNjkgNDc4LjgyNiAzNzIuNDI4IDQ3OC44MjZIMzA2LjM2MUgzMDUuOTc3SDIyMi4yNDFIMjIxLjg1N0gxNTUuNzkxQzE1Mi4zMzMgNDc4LjgyNiAxNDkuMjYxIDQ3NS43NiAxNDkuMjYxIDQ3MS45MkMxNDkuMjYxIDQ2OC40NTMgMTUyLjMzMyA0NjUuMzg2IDE1NS43OTEgNDY1LjM4NkgyMTUuMzI4VjM5MC4wOTNINDguMjM5OUMzNS4xNzk5IDM5MC4wOTMgMjMuMjczMiAzODQuNzIgMTQuODIyNiAzNzYuMjY2QzUuOTg3OTEgMzY3LjQ0IDAuNjEwNTk2IDM1NS41MzMgMC42MTA1OTYgMzQyLjQ2NlYyNzAuMjUzVjQ3Ljg1MjhDMC42MTA1OTYgMzQuNzk5NCA1Ljk4NzkxIDIzLjI3OTcgMTQuODIyNiAxNC40Mzk3QzIzLjI3MzIgNS45ODY0MSAzNS4xNzk5IDAuNjEzMTggNDguMjM5OSAwLjYxMzE4IiBmaWxsPSIjMkUyRDJEIi8+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="346.6" y="53" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="204.6" y="53.5" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="481px" height="291px" viewBox="-0.5 -0.5 481 291" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2023-03-20T08:58:47.205Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.8.16 Chrome/106.0.5249.199 Electron/21.4.0 Safari/537.36&quot; etag=&quot;q6rv6FZaU_LAJZ8DLjMH&quot; version=&quot;20.8.16&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;z_UtGdSUZwvYQkXjM40-&quot; name=&quot;Page-1&quot;&gt;5Vpdl5s2EP01fmyO+TR+jHedNOds2z11P7aPMghQIiMqxNrur6+wJQOWnMWLFpzkyehKgHRHmrkzeOLcbXYfKcjTX0gE8cSeRruJcz+xbcuyXP5TIfsjEswFkFAUiUE1sEL/QQFOBVqiCBatgYwQzFDeBkOSZTBkLQxQSrbtYTHB7bfmIIEKsAoBVtG/UcRSsQpvWuM/Q5Sk8s3WVPRsgBwsgCIFEdk2IGc5ce4oIex4tdndQVyRJ3k53vfhQu9pYhRmrMsN9vGGZ4BLsTYxL7aXi6WkzCJYjZ9OnMU2RQyuchBWvVtuXo6lbIN5y+KXMcL4jmBCD/c6cRzbYcjxglHyBTZ6In/tez7vUWcsFvEMKYO7BiRW8BGSDWR0z4eIXkeQKXaTK9ne1rZxA4GlDbtIDIjtkJyeXDPGLwRpegKdtyUw8mAQuToCA3vt+IYItOZnDAYqg46tYfB0IvtQ6CoULrMEZZBj7x8/KXTCiJ9F0SSUpSQhGcDLGl20Ca/HPBCSC5o/Q8b2wrGAkpG2ETiTdP9U3f/Ok81/xOMOjftdq7UXrYIByt5XDoYDGcmgxD6gavWHMRfNVZCShmKNM+HUAE2g3KxHqFr9V01KIQYMPbc9VR/zeKNYYIfYU+P6wP67mSeaNf9VY9+TWssZi1v/dri1v85tfSRaB6I+HxeOxKttYo9lk5nijn4nGJf5pHKAPubzW6wpv0qqq1+5tunn8BMKIsTJuUeUSxVEMo5DUDBNMA1CqA+m68BzvWnjYbJP+CADIcL22iHC0wRZXxMhfAMBIlADxPKHJN23hyN9rpD+YPUj3QAh7uxMqHgaoaLTKQYIkVKnyUhPsfcGjPj+gIxYCiOjxDMZmqzrQlMXtSZjpXiajJb9ZYiMb62Y53aMecL2P/GofbyjcxAUz3okiM+tHkLiuOCzOLf96ZXdtoOaTC4AC1MOrcr1BjEGab/zcr1vNnDCHP/lyGe5miPmmDhian75W8nykn1vpDpDkqpmnIeN+ilbk93oHt06L2dYGmp0ybgRasbJ9l6Zb+szGQNJouWr3nnW0TkbT0jkZJo+IGdog4rNIycb4Nvbsu6QW1ZN2Iw6xGFKcOcMaipwlk7qG6nAWWqGNa4b6CHkQgyKAoVnWq5Z95he4S1gFp0pRI5cW82TO7+P1uMTtaRVbkPtzb+lSPFqO8lxw7t9W803b6QQFQEYxFqJ6IcBXMdmPOLsZdn9VrUPW01sh6s4jcLukJUl6cZGjjZXpf9XhYyTi7LN+yidMpW2G8FHqenpn1kBYqg6qAUm4RcVfqQkBwk4nIixN8Fl6dDJNJqvGCNaRs1x/3iqigb7LBwlcGtP0gsf9C5V9maGFGEnswY3JQo8xawrBhi8Oct2/Zx4Zln7x7WsmuU/wIRnG/10hwGpoNTq5qpW0P29xkRyr/kau4L/ljALv4uyp052vRmVapL/F6QoRoaZHEa/KkxqvgQaYpI36z/kHTPl+m+NzvJ/&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="0" y="0" width="480" height="80" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><rect x="160" y="80" width="320" height="210" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><path d="M 250 160 L 250 213.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 250 218.88 L 246.5 211.88 L 250 213.63 L 253.5 211.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 250px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">Engine API</div></div></div></foreignObject><text x="250" y="193" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">Engine API</text></switch></g><path d="M 280 145 L 323.63 145" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 328.88 145 L 321.88 148.5 L 323.63 145 L 321.88 141.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 280 115 L 323.63 115" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 328.88 115 L 321.88 118.5 L 323.63 115 L 321.88 111.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="220" y="100" width="60" height="60" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 130px; margin-left: 221px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Rollup <br />Node</div></div></div></foreignObject><text x="250" y="134" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup...</text></switch></g><rect x="220" y="220" width="60" height="60" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 250px; margin-left: 221px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EE</div></div></div></foreignObject><text x="250" y="254" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">EE</text></switch></g><rect x="440" y="50" width="30" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 60px; margin-left: 441px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1</div></div></div></foreignObject><text x="455" y="64" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1</text></switch></g><rect x="440" y="260" width="30" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 270px; margin-left: 441px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L2</div></div></div></foreignObject><text x="455" y="274" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2</text></switch></g><path d="M 400 100 L 400 25 L 226.37 25" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 221.12 25 L 228.12 21.5 L 226.37 25 L 228.12 28.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="330" y="100" width="140" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 115px; margin-left: 331px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Batch Submitter</div></div></div></foreignObject><text x="400" y="119" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Batch Submitter</text></switch></g><rect x="330" y="130" width="140" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 145px; margin-left: 331px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Output Submitter</div></div></div></foreignObject><text x="400" y="149" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Output Submitter</text></switch></g><rect x="100" y="10" width="120" height="30" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 25px; margin-left: 101px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">BatchInbox</div></div></div></foreignObject><text x="160" y="29" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">BatchInbox</text></switch></g><path d="M 220 55 L 250 55 L 250 93.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 250 98.88 L 246.5 91.88 L 250 93.63 L 253.5 91.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="100" y="40" width="120" height="30" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 55px; margin-left: 101px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">OptimismPortal</div></div></div></foreignObject><text x="160" y="59" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">OptimismPortal</text></switch></g><rect x="0" y="80" width="160" height="210" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><path d="M 33.63 130 L 20 130 L 20 25 L 100 25" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 38.88 130 L 31.88 133.5 L 33.63 130 L 31.88 126.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 70 160 L 70 213.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 70 218.88 L 66.5 211.88 L 70 213.63 L 73.5 211.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="40" y="100" width="60" height="60" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 130px; margin-left: 41px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Rollup <br />Node</div></div></div></foreignObject><text x="70" y="134" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup...</text></switch></g><rect x="40" y="220" width="60" height="60" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 250px; margin-left: 41px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EE</div></div></div></foreignObject><text x="70" y="254" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">EE</text></switch></g><path d="M 100 55 L 55 55 L 55 93.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 55 98.88 L 51.5 91.88 L 55 93.63 L 58.5 91.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 213.63 130 L 106.37 130" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 218.88 130 L 211.88 133.5 L 213.63 130 L 211.88 126.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 101.12 130 L 108.12 126.5 L 106.37 130 L 108.12 133.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 130px; margin-left: 160px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">Unsafe<br />Block<br />Propagation</div></div></div></foreignObject><text x="160" y="133" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">Unsafe...</text></switch></g><path d="M 213.63 265 L 106.37 265" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 218.88 265 L 211.88 268.5 L 213.63 265 L 211.88 261.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 101.12 265 L 108.12 261.5 L 106.37 265 L 108.12 268.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 265px; margin-left: 160px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">TX Sync</div></div></div></foreignObject><text x="160" y="268" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">TX Sync</text></switch></g><path d="M 213.63 235 L 106.37 235" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 218.88 235 L 211.88 238.5 L 213.63 235 L 211.88 231.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 101.12 235 L 108.12 231.5 L 106.37 235 L 108.12 238.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 235px; margin-left: 160px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">State Sync</div></div></div></foreignObject><text x="160" y="238" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">State Sync</text></switch></g><rect x="330" y="190" width="80" height="30" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 205px; margin-left: 331px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Legend</div></div></div></foreignObject><text x="370" y="209" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Legend</text></switch></g><rect x="330" y="220" width="80" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 235px; margin-left: 331px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Sequencer</div></div></div></foreignObject><text x="370" y="239" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencer</text></switch></g><rect x="330" y="250" width="80" height="30" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 265px; margin-left: 331px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Verifier</div></div></div></foreignObject><text x="370" y="269" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Verifier</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="771px" height="201px" viewBox="-0.5 -0.5 771 201" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-27T03:59:25.759Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; version=&quot;17.2.4&quot; etag=&quot;dfECpYJffLwyyW-s9Yme&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;GSzoaz18CgCjYh4YR-OU&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="430" y="0" width="160" height="200" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 7px; margin-left: 431px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Epoch 3</div></div></div></foreignObject><text x="510" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Epoch 3</text></switch></g><rect x="270" y="0" width="160" height="200" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 7px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Epoch 2</div></div></div></foreignObject><text x="350" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Epoch 2</text></switch></g><rect x="110" y="0" width="160" height="200" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 7px; margin-left: 111px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Epoch 1</div></div></div></foreignObject><text x="190" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Epoch 1</text></switch></g><rect x="0" y="25" width="60" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 40px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">L1</div></div></div></foreignObject><text x="30" y="44" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L1</text></switch></g><path d="M 180 160 L 136.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 131.12 160 L 138.12 156.5 L 136.37 160 L 138.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="90" y="140" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="90" y="140" width="20" height="20" fill="#dae8fc" stroke="#6c8ebf" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 150px; margin-left: 91px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">D1</div></div></div></foreignObject><text x="100" y="154" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">D1</text></switch></g><rect x="110" y="140" width="20" height="20" fill="#dae8fc" stroke="#6c8ebf" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 150px; margin-left: 111px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B1</div></div></div></foreignObject><text x="120" y="154" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B1</text></switch></g><path d="M 250 40 L 136.37 40" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 131.12 40 L 138.12 36.5 L 136.37 40 L 138.12 43.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 160px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">L2</div></div></div></foreignObject><text x="30" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2</text></switch></g><path d="M 250 160 L 206.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 201.12 160 L 208.12 156.5 L 206.37 160 L 208.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="250" y="140" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="250" y="140" width="20" height="20" fill="#d5e8d4" stroke="#82b366" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 150px; margin-left: 251px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">D2</div></div></div></foreignObject><text x="260" y="154" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">D2</text></switch></g><path d="M 280 140 Q 280.06 30 403.63 30" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 408.88 30 L 401.88 33.5 L 403.63 30 L 401.88 26.5 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><rect x="270" y="140" width="20" height="20" fill="#d5e8d4" stroke="#82b366" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 150px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B3</div></div></div></foreignObject><text x="280" y="154" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B3</text></switch></g><rect x="250" y="20" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="250" y="20" width="20" height="20" fill="#dae8fc" stroke="#6c8ebf" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 251px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B2</div></div></div></foreignObject><text x="260" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B2</text></switch></g><rect x="270" y="20" width="20" height="20" fill="#d5e8d4" stroke="#82b366" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">D2</div></div></div></foreignObject><text x="280" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">D2</text></switch></g><path d="M 260.06 140 Q 260.06 90 270.06 90 Q 280.06 90 280.01 46.37" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 280 41.12 L 283.51 48.11 L 280.01 46.37 L 276.51 48.12 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 410 40 L 320.06 40 L 296.37 40" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 291.12 40 L 298.12 36.5 L 296.37 40 L 298.12 43.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="410" y="20" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="90" y="20" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="110" y="20" width="20" height="20" fill="#dae8fc" stroke="#6c8ebf" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 111px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B1</div></div></div></foreignObject><text x="120" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B1</text></switch></g><rect x="90" y="20" width="20" height="20" fill="#dae8fc" stroke="#6c8ebf" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 91px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">D1</div></div></div></foreignObject><text x="100" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">D1</text></switch></g><path d="M 100 140 L 100 46.37" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="none"/><path d="M 100 41.12 L 103.5 48.12 L 100 46.37 L 96.5 48.12 Z" fill="#6c8ebf" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="none"/><path d="M 120 140 L 120 46.37" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="none"/><path d="M 120 41.12 L 123.5 48.12 L 120 46.37 L 116.5 48.12 Z" fill="#6c8ebf" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="none"/><path d="M 190 150 Q 190.06 94.94 225.06 94.94 Q 260.06 94.94 260.01 46.37" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="none"/><path d="M 260 41.12 L 263.51 48.11 L 260.01 46.37 L 256.51 48.12 Z" fill="#6c8ebf" stroke="#6c8ebf" stroke-miterlimit="10" pointer-events="none"/><rect x="410" y="20" width="20" height="20" fill="#d5e8d4" stroke="#82b366" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B3</div></div></div></foreignObject><text x="420" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B3</text></switch></g><rect x="410" y="40" width="20" height="20" fill="#d5e8d4" stroke="#82b366" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 50px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B4</div></div></div></foreignObject><text x="420" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B4</text></switch></g><rect x="430" y="40" width="20" height="20" fill="#d5e8d4" stroke="#82b366" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 50px; margin-left: 431px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B5</div></div></div></foreignObject><text x="440" y="54" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B5</text></switch></g><path d="M 410 160 Q 390.06 160 395.06 160 Q 400.06 160 386.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 381.12 160 L 388.12 156.5 L 386.37 160 L 388.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 420 140 Q 420.06 120 445.06 120 Q 470.06 120 470.06 75 Q 470.06 30 456.37 30" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 451.12 30 L 458.12 26.5 L 456.37 30 L 458.12 33.5 Z" fill="#d6b656" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><rect x="410" y="140" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 330 150 Q 330.06 110 375.06 110 Q 420.06 110 420.01 66.37" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 420 61.12 L 423.51 68.11 L 420.01 66.37 L 416.51 68.12 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 320 160 Q 300.06 160 296.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 291.12 160 L 298.12 156.5 L 296.37 160 L 298.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="320" y="150" width="20" height="20" fill="#d5e8d4" stroke="#82b366" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 160px; margin-left: 321px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B4</div></div></div></foreignObject><text x="330" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B4</text></switch></g><rect x="180" y="150" width="20" height="20" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 160px; margin-left: 181px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B2</div></div></div></foreignObject><text x="190" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B2</text></switch></g><path d="M 370 150 Q 370.06 120 405.06 120 Q 440.06 120 440.01 66.37" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 440 61.12 L 443.51 68.11 L 440.01 66.37 L 436.51 68.12 Z" fill="#82b366" stroke="#82b366" stroke-miterlimit="10" pointer-events="none"/><path d="M 360 160 Q 340.06 160 350.06 160 Q 360.06 160 346.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 341.12 160 L 348.12 156.5 L 346.37 160 L 348.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="360" y="150" width="20" height="20" fill="#d5e8d4" stroke="#82b366" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 160px; margin-left: 361px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B5</div></div></div></foreignObject><text x="370" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B5</text></switch></g><rect x="430" y="20" width="20" height="20" fill="#fff2cc" stroke="#d6b656" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 431px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">D3</div></div></div></foreignObject><text x="440" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">D3</text></switch></g><rect x="570" y="20" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="570" y="20" width="20" height="20" fill="#fff2cc" stroke="#d6b656" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 571px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B6</div></div></div></foreignObject><text x="580" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B6</text></switch></g><rect x="590" y="20" width="20" height="20" fill="#fff2cc" stroke="#d6b656" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 30px; margin-left: 591px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B7</div></div></div></foreignObject><text x="600" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B7</text></switch></g><path d="M 480 160 Q 460.06 160 465.06 160 Q 470.06 160 456.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 451.12 160 L 458.12 156.5 L 456.37 160 L 458.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 490 150 Q 490.06 80 535.06 80 Q 580.06 80 580.01 46.37" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 580 41.12 L 583.51 48.11 L 580.01 46.37 L 576.51 48.12 Z" fill="#d6b656" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><rect x="480" y="150" width="20" height="20" fill="#fff2cc" stroke="#d6b656" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 160px; margin-left: 481px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B6</div></div></div></foreignObject><text x="490" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B6</text></switch></g><path d="M 520 160 Q 500.06 160 510.06 160 Q 520.06 160 506.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 501.12 160 L 508.12 156.5 L 506.37 160 L 508.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 530 150 Q 530.06 94.94 565.06 94.94 Q 600.06 94.94 600.01 46.37" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 600 41.12 L 603.51 48.11 L 600.01 46.37 L 596.51 48.12 Z" fill="#d6b656" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><rect x="520" y="150" width="20" height="20" fill="#fff2cc" stroke="#d6b656" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 160px; margin-left: 521px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">B7</div></div></div></foreignObject><text x="530" y="164" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">B7</text></switch></g><path d="M 570 160 Q 550.06 160 555.06 160 Q 560.06 160 546.37 160" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 541.12 160 L 548.12 156.5 L 546.37 160 L 548.12 163.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="570" y="140" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-dasharray="3 3" pointer-events="none"/><path d="M 730 40 Q 640.06 40 616.37 40" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="none"/><path d="M 611.12 40 L 618.12 36.5 L 616.37 40 L 618.12 43.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="730" y="20" width="40" height="40" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-dasharray="3 3" pointer-events="none"/><rect x="410" y="140" width="20" height="20" fill="#fff2cc" stroke="#d6b656" stroke-dasharray="3 3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 18px; height: 1px; padding-top: 150px; margin-left: 411px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">D3</div></div></div></foreignObject><text x="420" y="154" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">D3</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="815px" height="580px" viewBox="-0.5 -0.5 815 580" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-27T01:55:09.088Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; version=&quot;17.2.4&quot; etag=&quot;7J-Y2d02TEiXTL8UaXtp&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;MobpyW67W2rCJfvVq0nI&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 315 238 L 315 291.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 315 296.88 L 311.5 289.88 L 315 291.63 L 318.5 289.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 259px; margin-left: 319px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><font style="font-size: 12px"><b style="font-size: 11px">3. </b><span style="font-size: 11px">Insert deposit block</span><br /></font></div></div></div></foreignObject><text x="319" y="261" fill="#000000" font-family="Helvetica" font-size="9px" text-anchor="middle">3. Insert deposit block&#xa;</text></switch></g><rect x="192.86" y="148" width="244.29" height="90" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 242px; height: 1px; padding-top: 155px; margin-left: 194px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>Rollup Node</b></div></div></div></foreignObject><text x="315" y="167" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup Node</text></switch></g><path d="M 317.11 96.21 L 317.12 118.06 L 315 118.06 L 315 148" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 317.11 90.96 L 320.61 97.96 L 317.11 96.21 L 313.61 97.96 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 118px; margin-left: 318px;"><div data-drawio-colors="color: #FFFFFF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><font color="#000000"><b>2.</b> Get Blocks (including deposit event)</font></div></div></div></foreignObject><text x="318" y="122" fill="#FFFFFF" font-family="Helvetica" font-size="11px" text-anchor="middle">2. Get Blocks (including deposit event)</text></switch></g><rect x="190" y="48" width="570" height="40" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 568px; height: 1px; padding-top: 68px; margin-left: 191px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Ethereum L1 Chain</div></div></div></foreignObject><text x="475" y="72" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Ethereum L1 Chain</text></switch></g><rect x="275" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 295 220 L 285 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><rect x="295" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 315 220 L 305 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><rect x="315" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="230" y="208" width="50" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 218px; margin-left: 255px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><font face="Times New Roman"><i>Rollup</i>(</font></div></div></div></foreignObject><text x="255" y="222" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup(</text></switch></g><rect x="325" y="208" width="20" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 218px; margin-left: 327px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><div><span style="font-family: &quot;times new roman&quot;">)</span></div></div></div></div></foreignObject><text x="327" y="222" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">)</text></switch></g><path d="M 335 220 L 345.63 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 347.88 220 L 344.88 221.5 L 345.63 220 L 344.88 218.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="285" y="208" width="30" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 218px; margin-left: 300px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: &quot;Times New Roman&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><font face="Helvetica" style="background-color: rgb(102 , 51 , 0)" color="#ffffff">L1</font></div></div></div></foreignObject><text x="300" y="222" fill="rgb(0, 0, 0)" font-family="Times New Roman" font-size="12px" text-anchor="middle">L1</text></switch></g><rect x="355" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 375 220 L 365 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><rect x="375" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><path d="M 395 220 L 385 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><rect x="395" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><rect x="365" y="208" width="30" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 218px; margin-left: 380px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: &quot;Times New Roman&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><font face="Helvetica" style="background-color: rgb(0 , 51 , 102)" color="#ffffff">L2</font></div></div></div></foreignObject><text x="380" y="222" fill="rgb(0, 0, 0)" font-family="Times New Roman" font-size="12px" text-anchor="middle">L2</text></switch></g><rect x="523" y="448" width="250" height="130" fill="#ffe6cc" stroke="#d79b00" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 455px; margin-left: 524px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>Fault Proof VM</b></div></div></div></foreignObject><text x="648" y="467" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Fault Proof VM</text></switch></g><rect x="528" y="478" width="240" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 493px; margin-left: 648px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><i>Executes blocks in the fault proof VM and<br />generates witnesses.</i></div></div></div></foreignObject><text x="648" y="497" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Executes blocks in the fault proof VM an...</text></switch></g><rect x="593" y="518" width="210" height="50" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 208px; height: 1px; padding-top: 525px; margin-left: 595px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px">Data to</span><span style="font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px"><font color="#000000"> generate the witnesses<br /></font></span><span style="font-family: &quot;helvetica&quot;">(eg. storage, blocks...)</span><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px ; background-color: rgb(248 , 249 , 250)"><br /></span><span style="font-family: &quot;helvetica&quot;">is</span><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot;"> fetched from L1 &amp; L2 nodes</span><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px">.</span></div></div></div></foreignObject><text x="595" y="537" fill="#333333" font-family="Helvetica" font-size="12px">Data to generate the witnesses...</text></switch></g><image x="540" y="522.5" width="40" height="40" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDQ0LjQ2NDk2NTgyMDMxMjUgNDQ0LjQ2MTk3NTA5NzY1NjI1IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0NDQuNDYyIDQ0NC40NjI7IiB4bWw6c3BhY2U9InByZXNlcnZlIiB3aWR0aD0iNDQ0LjQ2NDk2NTgyMDMxMjUiIGhlaWdodD0iNDQ0LjQ2MTk3NTA5NzY1NjI1Ij4mI3hhOzxnPiYjeGE7CTxwYXRoIGQ9Ik0zMTcuMTY2LDExOS43OTZIMTI3LjI5N2MtNC4xNDMsMC03LjUsMy4zNTgtNy41LDcuNXYxODkuODY5YzAsNC4xNDIsMy4zNTcsNy41LDcuNSw3LjVoMTg5Ljg2OSYjMTA7JiM5OyYjOTtjNC4xNDMsMCw3LjUtMy4zNTgsNy41LTcuNVYxMjcuMjk2QzMyNC42NjYsMTIzLjE1NCwzMjEuMzA5LDExOS43OTYsMzE3LjE2NiwxMTkuNzk2eiBNMzA5LjY2NiwzMDkuNjY2SDEzNC43OTdWMTM0Ljc5NmgxNzQuODY5JiMxMDsmIzk7JiM5O1YzMDkuNjY2eiIvPiYjeGE7CTxwYXRoIGQ9Ik0xODUuODg3LDI2Ni4wNzZoNzIuNjg5YzQuMTQzLDAsNy41LTMuMzU4LDcuNS03LjV2LTcyLjY4OWMwLTQuMTQyLTMuMzU3LTcuNS03LjUtNy41aC03Mi42ODljLTQuMTQzLDAtNy41LDMuMzU4LTcuNSw3LjUmIzEwOyYjOTsmIzk7djcyLjY4OUMxNzguMzg3LDI2Mi43MTgsMTgxLjc0NCwyNjYuMDc2LDE4NS44ODcsMjY2LjA3NnogTTE5My4zODcsMTkzLjM4Nmg1Ny42ODl2NTcuNjg5aC01Ny42ODlWMTkzLjM4NnoiLz4mI3hhOwk8cGF0aCBkPSJNMzA1LjUyNCwxNWM2Ljk2LDAsMTAuMDgyLTkuMDY4LDQuNjM3LTEzLjM4OWMtNS40MDgtNC4yOTItMTMuNTM1LDAuODMyLTExLjk0OCw3LjU3OSYjMTA7JiM5OyYjOTtDMjk5LjAwNCwxMi41NDcsMzAyLjA2OCwxNSwzMDUuNTI0LDE1eiIvPiYjeGE7CTxwYXRoIGQ9Ik0xNDMuMTA0LDQzMC43M2MtMi40NTQtMS42MTYtNS42NDktMS42NjEtOC4xNDYtMC4xMTNjLTIuODkxLDEuNzkyLTQuMjExLDUuNDcxLTMuMTM1LDguNjk4JiMxMDsmIzk7JiM5O2MwLjk3OCwyLjkzLDMuNzE1LDUuMDE1LDYuODA5LDUuMTM4YzMuMTkxLDAuMTI3LDYuMTQzLTEuODI2LDcuMjk5LTQuNzk0QzE0Ny4xODUsNDM2LjQzNywxNDYsNDMyLjYzNiwxNDMuMTA0LDQzMC43M3oiLz4mI3hhOwk8cGF0aCBkPSJNNDM2Ljk2MiwxODguMDg2YzQuMTQzLDAsNy41LTMuMzU4LDcuNS03LjVzLTMuMzU3LTcuNS03LjUtNy41aC04Mi4yOTZ2LTI2LjY0NWg4Mi4yOTZjNC4xNDMsMCw3LjUtMy4zNTgsNy41LTcuNSYjMTA7JiM5OyYjOTtzLTMuMzU3LTcuNS03LjUtNy41aC04Mi4yOTZ2LTUuMzkyYzAtMTkuOTktMTYuMjY0LTM2LjI1My0zNi4yNTQtMzYuMjUzaC01LjM5MlYzMS42YzAtNC4xNDItMy4zNTctNy41LTcuNS03LjUmIzEwOyYjOTsmIzk7cy03LjUsMy4zNTgtNy41LDcuNXY1OC4xOTZoLTI2LjY0NVY3LjVjMC00LjE0Mi0zLjM1Ny03LjUtNy41LTcuNXMtNy41LDMuMzU4LTcuNSw3LjV2ODIuMjk2aC0yNi42NDVWNy41JiMxMDsmIzk7JiM5O2MwLTQuMTQyLTMuMzU3LTcuNS03LjUtNy41cy03LjUsMy4zNTgtNy41LDcuNXY4Mi4yOTZoLTI2LjY0NlY3LjVjMC00LjE0Mi0zLjM1Ny03LjUtNy41LTcuNXMtNy41LDMuMzU4LTcuNSw3LjV2ODIuMjk2aC0yNi42NDUmIzEwOyYjOTsmIzk7VjcuNWMwLTQuMTQyLTMuMzU3LTcuNS03LjUtNy41cy03LjUsMy4zNTgtNy41LDcuNXY4Mi4yOTZoLTUuMzkyYy0xOS45OSwwLTM2LjI1MywxNi4yNjMtMzYuMjUzLDM2LjI1M3Y1LjM5Mkg3LjUmIzEwOyYjOTsmIzk7Yy00LjE0MywwLTcuNSwzLjM1OC03LjUsNy41czMuMzU3LDcuNSw3LjUsNy41aDgyLjI5N3YyNi42NDVINy41Yy00LjE0MywwLTcuNSwzLjM1OC03LjUsNy41czMuMzU3LDcuNSw3LjUsNy41aDgyLjI5N3YyNi42NDVINy41JiMxMDsmIzk7JiM5O2MtNC4xNDMsMC03LjUsMy4zNTgtNy41LDcuNXMzLjM1Nyw3LjUsNy41LDcuNWg4Mi4yOTd2MjYuNjQ1SDcuNWMtNC4xNDMsMC03LjUsMy4zNTgtNy41LDcuNXMzLjM1Nyw3LjUsNy41LDcuNWg4Mi4yOTd2MjYuNjQ1SDcuNSYjMTA7JiM5OyYjOTtjLTQuMTQzLDAtNy41LDMuMzU4LTcuNSw3LjVzMy4zNTcsNy41LDcuNSw3LjVoODIuMjk3djUuMzkyYzAsMTkuOTksMTYuMjYzLDM2LjI1MywzNi4yNTMsMzYuMjUzaDUuMzkydjU4LjE5NyYjMTA7JiM5OyYjOTtjMCw0LjE0MiwzLjM1Nyw3LjUsNy41LDcuNXM3LjUtMy4zNTgsNy41LTcuNXYtNTguMTk3aDI2LjY0NXY4Mi4yOTZjMCw0LjE0MiwzLjM1Nyw3LjUsNy41LDcuNXM3LjUtMy4zNTgsNy41LTcuNXYtODIuMjk2aDI2LjY0NiYjMTA7JiM5OyYjOTt2ODIuMjk2YzAsNC4xNDIsMy4zNTcsNy41LDcuNSw3LjVzNy41LTMuMzU4LDcuNS03LjV2LTgyLjI5NmgyNi42NDV2ODIuMjk2YzAsNC4xNDIsMy4zNTcsNy41LDcuNSw3LjVzNy41LTMuMzU4LDcuNS03LjV2LTgyLjI5NiYjMTA7JiM5OyYjOTtoMjYuNjQ1djgyLjI5NmMwLDQuMTQyLDMuMzU3LDcuNSw3LjUsNy41czcuNS0zLjM1OCw3LjUtNy41di04Mi4yOTZoNS4zOTJjMTkuOTksMCwzNi4yNTQtMTYuMjYzLDM2LjI1NC0zNi4yNTN2LTUuMzkyaDgyLjI5NiYjMTA7JiM5OyYjOTtjNC4xNDMsMCw3LjUtMy4zNTgsNy41LTcuNXMtMy4zNTctNy41LTcuNS03LjVoLTgyLjI5NnYtMjYuNjQ1aDgyLjI5NmM0LjE0MywwLDcuNS0zLjM1OCw3LjUtNy41cy0zLjM1Ny03LjUtNy41LTcuNWgtODIuMjk2JiMxMDsmIzk7JiM5O3YtMjYuNjQ1aDgyLjI5NmM0LjE0MywwLDcuNS0zLjM1OCw3LjUtNy41cy0zLjM1Ny03LjUtNy41LTcuNWgtODIuMjk2di0yNi42NDVINDM2Ljk2MnogTTMzOS42NjYsMzE4LjQxMiYjMTA7JiM5OyYjOTtjMCwxMS43MTktOS41MzQsMjEuMjUzLTIxLjI1NCwyMS4yNTNIMTI2LjA1Yy0xMS43MTksMC0yMS4yNTMtOS41MzQtMjEuMjUzLTIxLjI1M1YxMjYuMDVjMC0xMS43MTksOS41MzQtMjEuMjUzLDIxLjI1My0yMS4yNTMmIzEwOyYjOTsmIzk7aDE5Mi4zNjJjMTEuNzIsMCwyMS4yNTQsOS41MzQsMjEuMjU0LDIxLjI1M1YzMTguNDEyeiIvPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PC9zdmc+" preserveAspectRatio="none"/><rect x="235" y="174" width="160" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 189px; margin-left: 315px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><i>Transform latest L1 blocks <br />into L2 block inputs</i></div></div></div></foreignObject><text x="315" y="193" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Transform latest L1 blocks...</text></switch></g><rect x="190" y="298" width="250" height="120" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 305px; margin-left: 191px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>Execution Engine (mining mode)</b></div></div></div></foreignObject><text x="315" y="317" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Execution Engine (mining mode)</text></switch></g><rect x="282" y="310" width="66" height="22" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 64px; height: 1px; padding-top: 321px; margin-left: 283px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font style="font-size: 9px">(eg. Geth)</font></div></div></div></foreignObject><text x="315" y="325" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">(eg. Geth)</text></switch></g><rect x="210.01" y="343" width="210" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 358px; margin-left: 315px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><i>Accept transactions, build blocks,<br />store the chain, serve RPC requests.<br /></i></div></div></div></foreignObject><text x="315" y="362" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Accept transactions, build blocks,...</text></switch></g><rect x="284.01" y="388" width="30" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 398px; margin-left: 285px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EVM</div></div></div></foreignObject><text x="299" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">EVM</text></switch></g><rect x="327.01" y="388" width="40" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 398px; margin-left: 328px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Chain</div></div></div></foreignObject><text x="347" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Chain</text></switch></g><rect x="380.01" y="388" width="40" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 398px; margin-left: 381px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">State</div></div></div></foreignObject><text x="400" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">State</text></switch></g><rect x="430" y="313" width="30" height="90" fill="#e1d5e7" stroke="#9673a6" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 358px; margin-left: 431px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">RPC</div></div></div></foreignObject><text x="445" y="362" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">RPC</text></switch></g><path d="M 510 263 L 485 263 L 485 324.06 L 466.88 324" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 461.63 323.98 L 468.64 320.51 L 466.88 324 L 468.62 327.51 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 287px; margin-left: 488px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><div><font color="rgba(0, 0, 0, 0)" face="monospace"><span style="font-size: 0px ; background-color: rgb(248 , 249 , 250)">4</span></font></div></div></div></div></foreignObject><text x="488" y="290" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">4</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 263px; margin-left: 481px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>5.</b> Get<br />latest<br />sequencer<br />blocks</div></div></div></foreignObject><text x="481" y="267" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">5. Get...</text></switch></g><path d="M 570 228 L 570 114.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 570 109.12 L 573.5 116.12 L 570 114.37 L 566.5 116.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 187px; margin-left: 571px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>6. </b>Submit sequencer blocks<br />(ie. a batch) to the batch inbox</div></div></div></foreignObject><text x="571" y="190" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">6. Submit sequencer blocks...</text></switch></g><rect x="510" y="228" width="120" height="140" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 235px; margin-left: 511px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>Sequencer<br />Batch Submitter</b></div></div></div></foreignObject><text x="570" y="247" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Sequencer...</text></switch></g><rect x="510" y="272" width="120" height="60" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 302px; margin-left: 570px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"><i>Queries for all<br />sequencer blocks &amp;<br />submits them to <br />the batch inbox.</i></div></div></div></foreignObject><text x="570" y="306" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Queries for all...</text></switch></g><path d="M 225 68 L 215 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="225" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 245 68 L 235 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="245" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 265 68 L 255 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="265" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 285 68 L 275 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="285" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 305 68 L 295 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="305" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 325 68 L 315 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="325" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 345 68 L 335 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="345" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 365 68 L 355 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="365" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 577.5 68 L 567.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="577.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 597.5 68 L 587.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="597.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 617.5 68 L 607.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="617.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 637.5 68 L 627.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="637.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 657.5 68 L 647.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="657.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 677.5 68 L 667.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="677.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 697.5 68 L 687.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="697.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 717.5 68 L 707.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="717.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="520" y="82" width="100" height="26" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 89px; margin-left: 521px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Batch Inbox</div></div></div></foreignObject><text x="570" y="101" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Batch Inbox</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 678px; height: 1px; padding-top: 30px; margin-left: 92px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><h1>Sequencer Syncing Deposits &amp; Accepting a Transaction </h1></div></div></div></foreignObject><text x="92" y="34" fill="#000000" font-family="Helvetica" font-size="12px">Sequencer Syncing Deposits &amp; Accepting a Transaction </text></switch></g><rect x="170" y="313" width="30" height="90" fill="#e1d5e7" stroke="#9673a6" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 358px; margin-left: 171px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">RPC</div></div></div></foreignObject><text x="185" y="362" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">RPC</text></switch></g><rect x="220" y="388" width="48" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 46px; height: 1px; padding-top: 398px; margin-left: 221px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">TxPool</div></div></div></foreignObject><text x="244" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">TxPool</text></switch></g><path d="M 30 238.06 L 100.06 238.06 L 100.06 358.06 L 163.63 358.01" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 168.88 358 L 161.88 361.51 L 163.63 358.01 L 161.88 354.51 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 299px; margin-left: 104px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>4.</b> Send Transaction</div></div></div></foreignObject><text x="104" y="302" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">4. Send Transaction</text></switch></g><path d="M 30 238 L 100.06 238.06 L 100.06 68.06 L 183.63 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 188.88 68 L 181.88 71.51 L 183.63 68 L 181.88 64.51 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 159px; margin-left: 101px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>1. </b>Submit Deposit</div></div></div></foreignObject><text x="101" y="162" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1. Submit Deposit</text></switch></g><ellipse cx="15" cy="215.5" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 15 223 L 15 248 M 15 228 L 0 228 M 15 228 L 30 228 M 15 248 L 0 268 M 15 248 L 30 268" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 275px; margin-left: 15px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;">User</div></div></div></foreignObject><text x="15" y="287" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">User</text></switch></g><image x="29.5" y="217.5" width="20" height="20" xlink:href="https://cdn2.iconfinder.com/data/icons/ecommerce-tiny-line/64/transaction_ecommerce_shop-128.png" preserveAspectRatio="none" pointer-events="none"/><rect x="170" y="438" width="282" height="50" fill="#f5f5f5" stroke="#666666" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 463px; margin-left: 204px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><span style="color: rgb(51 , 51 , 51)"><b>Note:</b>  Sequencer will likely run a consensus<br />protocol not demonstrated in this diagram.</span></div></div></div></foreignObject><text x="204" y="467" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">Note:  Sequencer will likely run a consen...</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 463px; margin-left: 185px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><font style="font-size: 20px" color="#990000"><b>!!</b></font></div></div></div></foreignObject><text x="185" y="467" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">!!</text></switch></g><path d="M 680 368 L 680.06 398.06 L 555 398.06 L 555 394.88 L 466.61 394.9" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 461.36 394.9 L 468.36 391.4 L 466.61 394.9 L 468.36 398.4 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 396px; margin-left: 574px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>7. </b>Get latest assertable block hash</div></div></div></foreignObject><text x="574" y="399" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">7. Get latest assertable block hash</text></switch></g><path d="M 710 228 L 710.06 168.06 L 710.89 115.46" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 710.97 110.21 L 714.36 117.26 L 710.89 115.46 L 707.36 117.15 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 168px; margin-left: 710px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>9. </b>Submit validated<br />block hash assertion</div></div></div></foreignObject><text x="710" y="171" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">9. Submit validated...</text></switch></g><rect x="650" y="228" width="120" height="140" fill="#f0ffcf" stroke="#b8d653" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 235px; margin-left: 651px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><b>L2 Output Submitter</b></div></div></div></foreignObject><text x="710" y="247" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Output Submitter</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 302px; margin-left: 710px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><i>Queries for the next<br />assertable block hash &amp; <br />submits it to the <br />L2 Output Oracle.</i></div></div></div></foreignObject><text x="710" y="306" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Queries for the next...</text></switch></g><rect x="630" y="82" width="130" height="26" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 89px; margin-left: 631px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">L2 Output Oracle</div></div></div></foreignObject><text x="695" y="101" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Output Oracle</text></switch></g><image x="536.6" y="53" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="394.6" y="53.5" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><path d="M 570.53 336 L 570.53 316.06 L 570.25 325.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 570.09 330.88 L 566.8 323.78 L 570.25 325.63 L 573.8 323.99 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><image x="556.5" y="335.5" width="27" height="27" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIiB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIgd2lkdGg9IjYwMCIgaGVpZ2h0PSI2MDAiIGlkPSJzdmcyIiB2ZXJzaW9uPSIxLjEiIGlua3NjYXBlOnZlcnNpb249IjAuNDguMiByOTgxOSIgc29kaXBvZGk6ZG9jbmFtZT0iQWlyZHJvcCAtIENvcGllLnN2ZyIgdmlld0JveD0iMS4wMDAwMDg1ODMwNjg4NDc3IDAuOTk5NjMzNzg5MDYyNSA2MDAgNjAwIj4mI3hhOyAgPGRlZnMgaWQ9ImRlZnM0Ij4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIiBpZD0ibGluZWFyR3JhZGllbnQzMDY4Ij4mI3hhOyAgICAgIDxzdG9wIHN0eWxlPSJzdG9wLWNvbG9yOiM3MGVmZmY7c3RvcC1vcGFjaXR5OjEiIG9mZnNldD0iMCIgaWQ9InN0b3AzMDcwIi8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojNTc3MGZmO3N0b3Atb3BhY2l0eToxIiBvZmZzZXQ9IjEiIGlkPSJzdG9wMzA3MiIvPiYjeGE7ICAgIDwvbGluZWFyR3JhZGllbnQ+JiN4YTsgICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXJHcmFkaWVudDMwMTMiIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyI+JiN4YTsgICAgICA8c3RvcCBpZD0ic3RvcDMwMTUiIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzAyNTVmYjtzdG9wLW9wYWNpdHk6MSIvPiYjeGE7ICAgICAgPHN0b3AgaWQ9InN0b3AzMDE3IiBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMxM2RkZjU7c3RvcC1vcGFjaXR5OjEiLz4mI3hhOyAgICA8L2xpbmVhckdyYWRpZW50PiYjeGE7ICAgIDxsaW5lYXJHcmFkaWVudCBpbmtzY2FwZTpjb2xsZWN0PSJhbHdheXMiIGlkPSJsaW5lYXJHcmFkaWVudDM5MTUiPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwODFmODtzdG9wLW9wYWNpdHk6MTsiIG9mZnNldD0iMCIgaWQ9InN0b3AzOTE3Ii8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojMDFkZGZmO3N0b3Atb3BhY2l0eToxIiBvZmZzZXQ9IjEiIGlkPSJzdG9wMzkxOSIvPiYjeGE7ICAgIDwvbGluZWFyR3JhZGllbnQ+JiN4YTsgICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXJHcmFkaWVudDM4ODMiPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwODFmODtzdG9wLW9wYWNpdHk6MTsiIG9mZnNldD0iMCIgaWQ9InN0b3AzODg1Ii8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojMDA4MWY4O3N0b3Atb3BhY2l0eTowOyIgb2Zmc2V0PSIxIiBpZD0ic3RvcDM4ODciLz4mI3hhOyAgICA8L2xpbmVhckdyYWRpZW50PiYjeGE7ICAgIDxsaW5lYXJHcmFkaWVudCBpZD0ibGluZWFyR3JhZGllbnQzODQzIj4mI3hhOyAgICAgIDxzdG9wIGlkPSJzdG9wMzg1MSIgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojM2Q3M2MzO3N0b3Atb3BhY2l0eToxOyIvPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwNjRmNTtzdG9wLW9wYWNpdHk6MC4zNzI1NDkwMjsiIG9mZnNldD0iMC4yNSIgaWQ9InN0b3AzODU3Ii8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojMDA2NGY1O3N0b3Atb3BhY2l0eTowLjI0NzA1ODgyOyIgb2Zmc2V0PSIwLjUiIGlkPSJzdG9wMzg1NSIvPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwNjRmNTtzdG9wLW9wYWNpdHk6MDsiIG9mZnNldD0iMSIgaWQ9InN0b3AzODQ3Ii8+JiN4YTsgICAgPC9saW5lYXJHcmFkaWVudD4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImxpbmVhckdyYWRpZW50MzgzNSI+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojZmZmZmZmO3N0b3Atb3BhY2l0eToxOyIgb2Zmc2V0PSIwIiBpZD0ic3RvcDM4MzciLz4mI3hhOyAgICAgIDxzdG9wIHN0eWxlPSJzdG9wLWNvbG9yOiNmZmZmZmY7c3RvcC1vcGFjaXR5OjA7IiBvZmZzZXQ9IjEiIGlkPSJzdG9wMzgzOSIvPiYjeGE7ICAgIDwvbGluZWFyR3JhZGllbnQ+JiN4YTsgICAgPGxpbmVhckdyYWRpZW50IGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIgeGxpbms6aHJlZj0iI2xpbmVhckdyYWRpZW50MzkxNSIgaWQ9ImxpbmVhckdyYWRpZW50MzkyMSIgeDE9IjM3Ny44ODc4NSIgeTE9IjUxMi42ODkyNyIgeDI9IjM3OC40NzE5MiIgeTI9IjMzOC42Mzg4OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiLz4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIiB4bGluazpocmVmPSIjbGluZWFyR3JhZGllbnQzMDEzIiBpZD0ibGluZWFyR3JhZGllbnQzMDI1IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgxLjUyMzQzNWUtNSw0NTAuMzYyKSIgeDE9IjMwNS4yMDA5MyIgeTE9IjU5OC41OTE5OCIgeDI9IjMwNS43ODUiIHkyPSI4LjI0Mzc1OTIiLz4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIiB4bGluazpocmVmPSIjbGluZWFyR3JhZGllbnQzMDY4IiBpZD0ibGluZWFyR3JhZGllbnQzMDY2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgwLjE1LDAsMCwwLjE1LDAuODUwMDIzODcsOTYxLjIxMjE3KSIgeDE9IjMwNS4yMDA5MyIgeTE9IjU5OC41OTE5OCIgeDI9IjMwNS43ODUiIHkyPSI4LjI0Mzc1OTIiLz4mI3hhOyAgPC9kZWZzPiYjeGE7ICA8c29kaXBvZGk6bmFtZWR2aWV3IGlkPSJiYXNlIiBwYWdlY29sb3I9IiNmZmZmZmYiIGJvcmRlcmNvbG9yPSIjNjY2NjY2IiBib3JkZXJvcGFjaXR5PSIxLjAiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnpvb209IjAuMzc0MTA4ODIiIGlua3NjYXBlOmN4PSItMjk4LjYxNzMzIiBpbmtzY2FwZTpjeT0iMzYuODkzNjI3IiBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIgc2hvd2dyaWQ9ImZhbHNlIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjEzNjYiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjcwNiIgaW5rc2NhcGU6d2luZG93LXg9Ii04IiBpbmtzY2FwZTp3aW5kb3cteT0iLTgiIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiLz4mI3hhOyAgPG1ldGFkYXRhIGlkPSJtZXRhZGF0YTciPiYjeGE7ICAgIDxyZGY6cmRmPiYjeGE7ICAgICAgPGNjOndvcmsgcmRmOmFib3V0PSIiPiYjeGE7ICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4mI3hhOyAgICAgICAgPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPiYjeGE7ICAgICAgICA8ZGM6dGl0bGUvPiYjeGE7ICAgICAgPC9jYzp3b3JrPiYjeGE7ICAgIDwvcmRmOnJkZj4mI3hhOyAgPC9tZXRhZGF0YT4mI3hhOyAgPGcgaW5rc2NhcGU6bGFiZWw9IkNhbHF1ZSAxIiBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIiBpZD0ibGF5ZXIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC00NTAuMzYyMTgpIj4mI3hhOyAgICA8ZyBpZD0iZzMwNjIiIHRyYW5zZm9ybT0ibWF0cml4KDYuNjY2NjY2NiwwLDAsNi42NjY2NjY2LC01LjY2NjgxMDYsLTU5NTcuNzE5MSkiPiYjeGE7ICAgICAgPHBhdGggaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgc3R5bGU9ImNvbG9yOiMwMDAwMDA7ZmlsbDp1cmwoI2xpbmVhckdyYWRpZW50MzA2Nik7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMTttYXJrZXI6bm9uZTt2aXNpYmlsaXR5OnZpc2libGU7ZGlzcGxheTppbmxpbmU7b3ZlcmZsb3c6dmlzaWJsZTtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlIiBkPSJtIDIxLjY1MjY1OSw5NjEuMzYyMjIgNDguNjk0NzM0LDAgYyAxMS40NDE1NTIsMCAyMC42NTI2MzMsOS4yMTEwOCAyMC42NTI2MzMsMjAuNjUyNjQgbCAwLDQ4LjY5NDc0IGMgMCwxMS40NDE2IC05LjIxMTA4MSwyMC42NTI2IC0yMC42NTI2MzMsMjAuNjUyNiBsIC00OC42OTQ3MzQsMCBjIC0xMS40NDE1NjMsMCAtMjAuNjUyNjMzNiwtOS4yMTEgLTIwLjY1MjYzMzYsLTIwLjY1MjYgbCAwLC00OC42OTQ3NCBjIDAsLTExLjQ0MTU2IDkuMjExMDcwNiwtMjAuNjUyNjQgMjAuNjUyNjMzNiwtMjAuNjUyNjQgeiIgaWQ9InJlY3QyOTk2Ii8+JiN4YTsgICAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDQ1MC4zNjIxOCkiIHNvZGlwb2RpOm5vZGV0eXBlcz0ic2NjY2NjY2NjYWFhY2NjY3NzY3NzY2NjY2NjY2NjY2NjY2Njc3NjY2NjY3NzY2NjY2NhYWFjYyIgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgaWQ9InJlY3QzMDI3IiBkPSJtIDIwLjcxODc1LDUzNi41OTM3NSBjIC0wLjQ3NDIwMiwwIC0wLjkyMDkzOCwwLjA4MTggLTEuMzQzNzUsMC4yNSBsIDguNDY4NzUsOC43MTg3NSA4LjU2MjUsOC44NzUgMC4xNTYyNSwwLjE4NzUgMC4yNSwwLjI1IDAuMjUsMC4yNSAwLjUsMC41MzEyNSA3LjM0Mzc1LDcuNTMxMjUgYyAwLjEyMjI2OSwwLjA3NiAwLjQ3NjYwMiwwLjQwNDIgMC43NTM0MzQsMC41NDI1OCAwLjM1NjU4MywwLjE3ODI0IDAuNzQzMDg5LDAuMzQyNTUgMS4xNDE0ODQsMC4zNTY4IDAuNDI5OTIsMC4wMTU0IDAuODY5MzM0LC0wLjEwNzgyIDEuMjU2MTgxLC0wLjI5NjAxIDAuMjg5NzMyLC0wLjE0MDk2IDAuNDE4NTcyLC0wLjM0Mjk0IDAuNzU1MTUxLC0wLjYwMzM3IGwgOC41LC04Ljc4MTI1IDguNTkzNzUsLTguODQzNzUgOC4yODEyNSwtOC41MzEyNSBjIC0wLjUzMTY0MywtMC4yODgwNiAtMS4xMjA0NjYsLTAuNDM3NSAtMS43NSwtMC40Mzc1IHogbSAtMi41OTM3NSwxLjA2MjUgYyAtMC45MDMxMTUsMC44NTU3MiAtMS40Njg3NSwyLjE0MjE3IC0xLjQ2ODc1LDMuNTkzNzUgbCAwLDI4LjYyNSBjIDAsMS4xNzUzNSAwLjM3NzQ5OSwyLjI0MzA3IDEsMy4wNjI1IGwgMS4xODc1LC0xLjEyNSA4Ljg0Mzc1LC04LjU5Mzc1IDcuODQzNzUsLTcuNTkzNzUgLTAuMTU2MjUsLTAuMTg3NSAtOC41OTM3NSwtOC44NDM3NSAtOC41OTM3NSwtOC44NzUgeiBtIDU3LjE4NzUsMC4yODEyNSAtOC4zNzUsOC42NTYyNSAtOC41NjI1LDguODQzNzUgLTAuMTU2MjUsMC4xNTYyNSA4LjE1NjI1LDcuOTA2MjUgOC44NDM3NSw4LjU5Mzc1IDAuNTMxMjUsMC41IGMgMC40NzYxNjQsLTAuNzY0MDIgMC43NSwtMS43MDUxOCAwLjc1LC0yLjcxODc1IGwgMCwtMjguNjI1IGMgMCwtMS4yOTQyOCAtMC40NDg1MTYsLTIuNDY3OTUgLTEuMTg3NSwtMy4zMTI1IHogbSAtMzguNzgxMjUsMTguNzE4NzUgLTcuODEyNSw3LjU5Mzc1IC04Ljg3NSw4LjU5Mzc1IC0xLjEyNSwxLjA5Mzc1IGMgMC41OTMwOTYsMC4zODE5NiAxLjI2ODA0MiwwLjYyNSAyLDAuNjI1IGwgNTEuNzE4NzUsMCBjIDAuODc5OTU3LDAgMS42NzgxMTYsLTAuMzM4NTMgMi4zNDM3NSwtMC44NzUgbCAtMC41NjI1LC0wLjU2MjUgLTguODc1LC04LjU5Mzc1IC04LjE1NjI1LC03Ljg3NSAtNy4zNDM3NSw3LjU2MjUgYyAtMC4zOTc0NjUsMC4yNjM1IC0wLjY2MzA2NCwwLjU1NTc2IC0xLjA1MTE2OCwwLjczNTIzIC0wLjYyNDYxNSwwLjI4ODg1IC0xLjMwOTE2MywwLjUzMzIxIC0xLjk5NzI1MiwwLjUyMjY3IC0wLjY4OTkyMiwtMC4wMTA2IC0xLjM2NjQyOCwtMC4yODA2MSAtMS45ODU1NzcsLTAuNTg1MTcgLTAuMzEwNzkyLC0wLjE1Mjg4IC0wLjQ3NjQzOCwtMC4zMDQ4MSAtMC44NDEwMDMsLTAuNjEwMjMgeiIgc3R5bGU9ImNvbG9yOiMwMDAwMDA7ZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDo2LjE5OTk5OTgxO21hcmtlcjpub25lO3Zpc2liaWxpdHk6dmlzaWJsZTtkaXNwbGF5OmlubGluZTtvdmVyZmxvdzp2aXNpYmxlO2VuYWJsZS1iYWNrZ3JvdW5kOmFjY3VtdWxhdGUiLz4mI3hhOyAgICA8L2c+JiN4YTsgIDwvZz4mI3hhOzwvc3ZnPg==" preserveAspectRatio="none" pointer-events="none"/><path d="M 710 368 L 710.06 408.06 L 710.43 441.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 710.49 446.88 L 706.91 439.92 L 710.43 441.63 L 713.91 439.84 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 421px; margin-left: 713px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>8. </b>Verify block hash in the fault proof VM<br />to detect on-chain&lt;-&gt;off-chain divergence</div></div></div></foreignObject><text x="713" y="424" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">8. Verify block hash in the fault proof VM...</text></switch></g><image x="699.5" y="335.5" width="27" height="27" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIiB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIgd2lkdGg9IjYwMCIgaGVpZ2h0PSI2MDAiIGlkPSJzdmcyIiB2ZXJzaW9uPSIxLjEiIGlua3NjYXBlOnZlcnNpb249IjAuNDguMiByOTgxOSIgc29kaXBvZGk6ZG9jbmFtZT0iQWlyZHJvcCAtIENvcGllLnN2ZyIgdmlld0JveD0iMS4wMDAwMDg1ODMwNjg4NDc3IDAuOTk5NjMzNzg5MDYyNSA2MDAgNjAwIj4mI3hhOyAgPGRlZnMgaWQ9ImRlZnM0Ij4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIiBpZD0ibGluZWFyR3JhZGllbnQzMDY4Ij4mI3hhOyAgICAgIDxzdG9wIHN0eWxlPSJzdG9wLWNvbG9yOiM3MGVmZmY7c3RvcC1vcGFjaXR5OjEiIG9mZnNldD0iMCIgaWQ9InN0b3AzMDcwIi8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojNTc3MGZmO3N0b3Atb3BhY2l0eToxIiBvZmZzZXQ9IjEiIGlkPSJzdG9wMzA3MiIvPiYjeGE7ICAgIDwvbGluZWFyR3JhZGllbnQ+JiN4YTsgICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXJHcmFkaWVudDMwMTMiIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyI+JiN4YTsgICAgICA8c3RvcCBpZD0ic3RvcDMwMTUiIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzAyNTVmYjtzdG9wLW9wYWNpdHk6MSIvPiYjeGE7ICAgICAgPHN0b3AgaWQ9InN0b3AzMDE3IiBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMxM2RkZjU7c3RvcC1vcGFjaXR5OjEiLz4mI3hhOyAgICA8L2xpbmVhckdyYWRpZW50PiYjeGE7ICAgIDxsaW5lYXJHcmFkaWVudCBpbmtzY2FwZTpjb2xsZWN0PSJhbHdheXMiIGlkPSJsaW5lYXJHcmFkaWVudDM5MTUiPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwODFmODtzdG9wLW9wYWNpdHk6MTsiIG9mZnNldD0iMCIgaWQ9InN0b3AzOTE3Ii8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojMDFkZGZmO3N0b3Atb3BhY2l0eToxIiBvZmZzZXQ9IjEiIGlkPSJzdG9wMzkxOSIvPiYjeGE7ICAgIDwvbGluZWFyR3JhZGllbnQ+JiN4YTsgICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXJHcmFkaWVudDM4ODMiPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwODFmODtzdG9wLW9wYWNpdHk6MTsiIG9mZnNldD0iMCIgaWQ9InN0b3AzODg1Ii8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojMDA4MWY4O3N0b3Atb3BhY2l0eTowOyIgb2Zmc2V0PSIxIiBpZD0ic3RvcDM4ODciLz4mI3hhOyAgICA8L2xpbmVhckdyYWRpZW50PiYjeGE7ICAgIDxsaW5lYXJHcmFkaWVudCBpZD0ibGluZWFyR3JhZGllbnQzODQzIj4mI3hhOyAgICAgIDxzdG9wIGlkPSJzdG9wMzg1MSIgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojM2Q3M2MzO3N0b3Atb3BhY2l0eToxOyIvPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwNjRmNTtzdG9wLW9wYWNpdHk6MC4zNzI1NDkwMjsiIG9mZnNldD0iMC4yNSIgaWQ9InN0b3AzODU3Ii8+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojMDA2NGY1O3N0b3Atb3BhY2l0eTowLjI0NzA1ODgyOyIgb2Zmc2V0PSIwLjUiIGlkPSJzdG9wMzg1NSIvPiYjeGE7ICAgICAgPHN0b3Agc3R5bGU9InN0b3AtY29sb3I6IzAwNjRmNTtzdG9wLW9wYWNpdHk6MDsiIG9mZnNldD0iMSIgaWQ9InN0b3AzODQ3Ii8+JiN4YTsgICAgPC9saW5lYXJHcmFkaWVudD4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImxpbmVhckdyYWRpZW50MzgzNSI+JiN4YTsgICAgICA8c3RvcCBzdHlsZT0ic3RvcC1jb2xvcjojZmZmZmZmO3N0b3Atb3BhY2l0eToxOyIgb2Zmc2V0PSIwIiBpZD0ic3RvcDM4MzciLz4mI3hhOyAgICAgIDxzdG9wIHN0eWxlPSJzdG9wLWNvbG9yOiNmZmZmZmY7c3RvcC1vcGFjaXR5OjA7IiBvZmZzZXQ9IjEiIGlkPSJzdG9wMzgzOSIvPiYjeGE7ICAgIDwvbGluZWFyR3JhZGllbnQ+JiN4YTsgICAgPGxpbmVhckdyYWRpZW50IGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIgeGxpbms6aHJlZj0iI2xpbmVhckdyYWRpZW50MzkxNSIgaWQ9ImxpbmVhckdyYWRpZW50MzkyMSIgeDE9IjM3Ny44ODc4NSIgeTE9IjUxMi42ODkyNyIgeDI9IjM3OC40NzE5MiIgeTI9IjMzOC42Mzg4OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiLz4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIiB4bGluazpocmVmPSIjbGluZWFyR3JhZGllbnQzMDEzIiBpZD0ibGluZWFyR3JhZGllbnQzMDI1IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgxLjUyMzQzNWUtNSw0NTAuMzYyKSIgeDE9IjMwNS4yMDA5MyIgeTE9IjU5OC41OTE5OCIgeDI9IjMwNS43ODUiIHkyPSI4LjI0Mzc1OTIiLz4mI3hhOyAgICA8bGluZWFyR3JhZGllbnQgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIiB4bGluazpocmVmPSIjbGluZWFyR3JhZGllbnQzMDY4IiBpZD0ibGluZWFyR3JhZGllbnQzMDY2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgwLjE1LDAsMCwwLjE1LDAuODUwMDIzODcsOTYxLjIxMjE3KSIgeDE9IjMwNS4yMDA5MyIgeTE9IjU5OC41OTE5OCIgeDI9IjMwNS43ODUiIHkyPSI4LjI0Mzc1OTIiLz4mI3hhOyAgPC9kZWZzPiYjeGE7ICA8c29kaXBvZGk6bmFtZWR2aWV3IGlkPSJiYXNlIiBwYWdlY29sb3I9IiNmZmZmZmYiIGJvcmRlcmNvbG9yPSIjNjY2NjY2IiBib3JkZXJvcGFjaXR5PSIxLjAiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiIGlua3NjYXBlOnpvb209IjAuMzc0MTA4ODIiIGlua3NjYXBlOmN4PSItMjk4LjYxNzMzIiBpbmtzY2FwZTpjeT0iMzYuODkzNjI3IiBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIgc2hvd2dyaWQ9ImZhbHNlIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjEzNjYiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjcwNiIgaW5rc2NhcGU6d2luZG93LXg9Ii04IiBpbmtzY2FwZTp3aW5kb3cteT0iLTgiIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiLz4mI3hhOyAgPG1ldGFkYXRhIGlkPSJtZXRhZGF0YTciPiYjeGE7ICAgIDxyZGY6cmRmPiYjeGE7ICAgICAgPGNjOndvcmsgcmRmOmFib3V0PSIiPiYjeGE7ICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4mI3hhOyAgICAgICAgPGRjOnR5cGUgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIvPiYjeGE7ICAgICAgICA8ZGM6dGl0bGUvPiYjeGE7ICAgICAgPC9jYzp3b3JrPiYjeGE7ICAgIDwvcmRmOnJkZj4mI3hhOyAgPC9tZXRhZGF0YT4mI3hhOyAgPGcgaW5rc2NhcGU6bGFiZWw9IkNhbHF1ZSAxIiBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIiBpZD0ibGF5ZXIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC00NTAuMzYyMTgpIj4mI3hhOyAgICA8ZyBpZD0iZzMwNjIiIHRyYW5zZm9ybT0ibWF0cml4KDYuNjY2NjY2NiwwLDAsNi42NjY2NjY2LC01LjY2NjgxMDYsLTU5NTcuNzE5MSkiPiYjeGE7ICAgICAgPHBhdGggaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgc3R5bGU9ImNvbG9yOiMwMDAwMDA7ZmlsbDp1cmwoI2xpbmVhckdyYWRpZW50MzA2Nik7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMTttYXJrZXI6bm9uZTt2aXNpYmlsaXR5OnZpc2libGU7ZGlzcGxheTppbmxpbmU7b3ZlcmZsb3c6dmlzaWJsZTtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlIiBkPSJtIDIxLjY1MjY1OSw5NjEuMzYyMjIgNDguNjk0NzM0LDAgYyAxMS40NDE1NTIsMCAyMC42NTI2MzMsOS4yMTEwOCAyMC42NTI2MzMsMjAuNjUyNjQgbCAwLDQ4LjY5NDc0IGMgMCwxMS40NDE2IC05LjIxMTA4MSwyMC42NTI2IC0yMC42NTI2MzMsMjAuNjUyNiBsIC00OC42OTQ3MzQsMCBjIC0xMS40NDE1NjMsMCAtMjAuNjUyNjMzNiwtOS4yMTEgLTIwLjY1MjYzMzYsLTIwLjY1MjYgbCAwLC00OC42OTQ3NCBjIDAsLTExLjQ0MTU2IDkuMjExMDcwNiwtMjAuNjUyNjQgMjAuNjUyNjMzNiwtMjAuNjUyNjQgeiIgaWQ9InJlY3QyOTk2Ii8+JiN4YTsgICAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDQ1MC4zNjIxOCkiIHNvZGlwb2RpOm5vZGV0eXBlcz0ic2NjY2NjY2NjYWFhY2NjY3NzY3NzY2NjY2NjY2NjY2NjY2Njc3NjY2NjY3NzY2NjY2NhYWFjYyIgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgaWQ9InJlY3QzMDI3IiBkPSJtIDIwLjcxODc1LDUzNi41OTM3NSBjIC0wLjQ3NDIwMiwwIC0wLjkyMDkzOCwwLjA4MTggLTEuMzQzNzUsMC4yNSBsIDguNDY4NzUsOC43MTg3NSA4LjU2MjUsOC44NzUgMC4xNTYyNSwwLjE4NzUgMC4yNSwwLjI1IDAuMjUsMC4yNSAwLjUsMC41MzEyNSA3LjM0Mzc1LDcuNTMxMjUgYyAwLjEyMjI2OSwwLjA3NiAwLjQ3NjYwMiwwLjQwNDIgMC43NTM0MzQsMC41NDI1OCAwLjM1NjU4MywwLjE3ODI0IDAuNzQzMDg5LDAuMzQyNTUgMS4xNDE0ODQsMC4zNTY4IDAuNDI5OTIsMC4wMTU0IDAuODY5MzM0LC0wLjEwNzgyIDEuMjU2MTgxLC0wLjI5NjAxIDAuMjg5NzMyLC0wLjE0MDk2IDAuNDE4NTcyLC0wLjM0Mjk0IDAuNzU1MTUxLC0wLjYwMzM3IGwgOC41LC04Ljc4MTI1IDguNTkzNzUsLTguODQzNzUgOC4yODEyNSwtOC41MzEyNSBjIC0wLjUzMTY0MywtMC4yODgwNiAtMS4xMjA0NjYsLTAuNDM3NSAtMS43NSwtMC40Mzc1IHogbSAtMi41OTM3NSwxLjA2MjUgYyAtMC45MDMxMTUsMC44NTU3MiAtMS40Njg3NSwyLjE0MjE3IC0xLjQ2ODc1LDMuNTkzNzUgbCAwLDI4LjYyNSBjIDAsMS4xNzUzNSAwLjM3NzQ5OSwyLjI0MzA3IDEsMy4wNjI1IGwgMS4xODc1LC0xLjEyNSA4Ljg0Mzc1LC04LjU5Mzc1IDcuODQzNzUsLTcuNTkzNzUgLTAuMTU2MjUsLTAuMTg3NSAtOC41OTM3NSwtOC44NDM3NSAtOC41OTM3NSwtOC44NzUgeiBtIDU3LjE4NzUsMC4yODEyNSAtOC4zNzUsOC42NTYyNSAtOC41NjI1LDguODQzNzUgLTAuMTU2MjUsMC4xNTYyNSA4LjE1NjI1LDcuOTA2MjUgOC44NDM3NSw4LjU5Mzc1IDAuNTMxMjUsMC41IGMgMC40NzYxNjQsLTAuNzY0MDIgMC43NSwtMS43MDUxOCAwLjc1LC0yLjcxODc1IGwgMCwtMjguNjI1IGMgMCwtMS4yOTQyOCAtMC40NDg1MTYsLTIuNDY3OTUgLTEuMTg3NSwtMy4zMTI1IHogbSAtMzguNzgxMjUsMTguNzE4NzUgLTcuODEyNSw3LjU5Mzc1IC04Ljg3NSw4LjU5Mzc1IC0xLjEyNSwxLjA5Mzc1IGMgMC41OTMwOTYsMC4zODE5NiAxLjI2ODA0MiwwLjYyNSAyLDAuNjI1IGwgNTEuNzE4NzUsMCBjIDAuODc5OTU3LDAgMS42NzgxMTYsLTAuMzM4NTMgMi4zNDM3NSwtMC44NzUgbCAtMC41NjI1LC0wLjU2MjUgLTguODc1LC04LjU5Mzc1IC04LjE1NjI1LC03Ljg3NSAtNy4zNDM3NSw3LjU2MjUgYyAtMC4zOTc0NjUsMC4yNjM1IC0wLjY2MzA2NCwwLjU1NTc2IC0xLjA1MTE2OCwwLjczNTIzIC0wLjYyNDYxNSwwLjI4ODg1IC0xLjMwOTE2MywwLjUzMzIxIC0xLjk5NzI1MiwwLjUyMjY3IC0wLjY4OTkyMiwtMC4wMTA2IC0xLjM2NjQyOCwtMC4yODA2MSAtMS45ODU1NzcsLTAuNTg1MTcgLTAuMzEwNzkyLC0wLjE1Mjg4IC0wLjQ3NjQzOCwtMC4zMDQ4MSAtMC44NDEwMDMsLTAuNjEwMjMgeiIgc3R5bGU9ImNvbG9yOiMwMDAwMDA7ZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDo2LjE5OTk5OTgxO21hcmtlcjpub25lO3Zpc2liaWxpdHk6dmlzaWJsZTtkaXNwbGF5OmlubGluZTtvdmVyZmxvdzp2aXNpYmxlO2VuYWJsZS1iYWNrZ3JvdW5kOmFjY3VtdWxhdGUiLz4mI3hhOyAgICA8L2c+JiN4YTsgIDwvZz4mI3hhOzwvc3ZnPg==" preserveAspectRatio="none" pointer-events="none"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="571px" height="259px" viewBox="-0.5 -0.5 571 259" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-27T02:07:17.010Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; version=&quot;17.2.4&quot; etag=&quot;kgErL1EhUEkryYzszLW0&quot; type=&quot;google&quot;&gt;&lt;diagram id=&quot;XUp9Uo5zUpcl_6EjXjKs&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="0" y="0" width="570" height="40" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 568px; height: 1px; padding-top: 20px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Ethereum L1 Chain</div></div></div></foreignObject><text x="285" y="24" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Ethereum L1 Chain</text></switch></g><path d="M 35 20 L 25 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="35" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 55 20 L 45 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="55" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 75 20 L 65 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="75" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 95 20 L 85 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="95" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 115 20 L 105 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="115" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 135 20 L 125 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="135" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 155 20 L 145 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="155" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 175 20 L 165 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="175" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 387.5 20 L 377.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="387.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 407.5 20 L 397.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="407.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 427.5 20 L 417.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="427.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 447.5 20 L 437.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="447.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 467.5 20 L 457.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="467.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 487.5 20 L 477.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="487.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 507.5 20 L 497.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="507.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 527.5 20 L 517.5 20" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="527.5" y="15" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><rect x="460" y="34" width="100" height="26" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 41px; margin-left: 461px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Batch Inbox</div></div></div></foreignObject><text x="510" y="53" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Batch Inbox</text></switch></g><rect x="310" y="34" width="130" height="26" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 41px; margin-left: 311px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">L2 Output Oracle</div></div></div></foreignObject><text x="375" y="53" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Output Oracle</text></switch></g><path d="M 390 176 L 389.95 65.87" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 389.95 60.62 L 393.45 67.62 L 389.95 65.87 L 386.45 67.63 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 137px; margin-left: 393px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>3. </b>Assert block hash<br />containing withdrawal<br />commitment</div></div></div></foreignObject><text x="393" y="141" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">3. Assert block hash...</text></switch></g><path d="M 420 206 L 510 206 L 510 66.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 510 61.12 L 513.5 68.12 L 510 66.37 L 506.5 68.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 143px; margin-left: 511px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>2. </b>Post batch<br />with withdrawal<br />transaction data</div></div></div></foreignObject><text x="511" y="146" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">2. Post batch...</text></switch></g><path d="M 200 206.5 L 280 206.5 L 353.63 206.04" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 358.88 206.01 L 351.9 209.55 L 353.63 206.04 L 351.86 202.55 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 206px; margin-left: 278px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>1.</b> Send <br /><i>initiate<br />withdrawal</i><br />transaction</div></div></div></foreignObject><text x="278" y="209" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">1. Send...</text></switch></g><path d="M 185 176.5 L 185 66.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 185 61.12 L 188.5 68.12 L 185 66.37 L 181.5 68.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 130px; margin-left: 186px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>5. </b>Send<br /><i>execute <br />withdrawal</i><br />transaction</div></div></div></foreignObject><text x="186" y="133" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">5. Send...</text></switch></g><path d="M 170 206.5 L 115 206.5 L 115 156.3 L 66.04 156.32" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 60.79 156.32 L 67.79 152.82 L 66.04 156.32 L 67.79 159.82 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 190px; margin-left: 116px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>4. </b>Wait for block<br />hash to finalize</div></div></div></foreignObject><text x="116" y="193" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">4. Wait for block...</text></switch></g><ellipse cx="185" cy="184" rx="7.5" ry="7.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 185 191.5 L 185 216.5 M 185 196.5 L 170 196.5 M 185 196.5 L 200 196.5 M 185 216.5 L 170 236.5 M 185 216.5 L 200 236.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 244px; margin-left: 185px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><b>User</b></div></div></div></foreignObject><text x="185" y="256" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">User</text></switch></g><rect x="10" y="34" width="60" height="26" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 41px; margin-left: 11px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">ERC20</div></div></div></foreignObject><text x="40" y="53" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">ERC20</text></switch></g><ellipse cx="45" cy="155" rx="15" ry="15" fill="#f5f5f5" stroke="#666666" stroke-width="2" pointer-events="none"/><path d="M 45 141.5 L 45 155 L 37.5 155" fill="none" stroke="#666666" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 210 47 L 260.3 47 L 304.13 47.15" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 309.38 47.16 L 302.37 50.64 L 304.13 47.15 L 302.39 43.64 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 71px; margin-left: 260px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>6. </b>Verify<br />withdrawal<br />in finalized<br />block hash</div></div></div></foreignObject><text x="260" y="74" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">6. Verify...</text></switch></g><path d="M 160 47 L 76.37 47" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 71.12 47 L 78.12 43.5 L 76.37 47 L 78.12 50.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 65px; margin-left: 122px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>7.</b><br />Transfer<br />tokens</div></div></div></foreignObject><text x="122" y="68" fill="#000000" font-family="Helvetica" font-size="11px" text-anchor="middle">7....</text></switch></g><rect x="160" y="34" width="50" height="26" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 48px; height: 1px; padding-top: 41px; margin-left: 161px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Bridge</div></div></div></foreignObject><text x="185" y="53" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Bridge</text></switch></g><image x="202.5" y="176" width="22" height="22" xlink:href="https://cdn2.iconfinder.com/data/icons/ecommerce-tiny-line/64/transaction_ecommerce_shop-128.png" preserveAspectRatio="none" pointer-events="none"/><image x="346.6" y="5" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="204.6" y="5.5" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" pointer-events="none" text-anchor="middle" font-size="12px"><text x="389.5" y="249.5">Sequencers</text></g><rect x="360" y="176" width="60" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><image x="366.5" y="179.5" width="18.73" height="17" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjYuOTk4NDEzMDg1OTM3NSIgaGVpZ2h0PSI0NzguMjEyNzk5MDcyMjY1NiIgdmlld0JveD0iMC42MTA1OTYwNjA3NTI4Njg3IDAuNjEzMTgwMDQxMzEzMTcxNCA1MjYuOTk4NDEzMDg1OTM3NSA0NzguMjEyNzk5MDcyMjY1NiIgZmlsbD0ibm9uZSI+JiN4YTs8cGF0aCBkPSJNNTE0LjE2NSAyNzcuMTczSDE0LjQzODZWMzQyLjQ2NkMxNC40Mzg2IDM1MS42OTMgMTguMjc4NiAzNjAuNTIgMjQuNDI1MiAzNjYuNjY2QzMwLjU3MDYgMzcyLjgxMyAzOS4wMjEyIDM3Ni42NTMgNDguMjM5OSAzNzYuNjUzSDIyMi4yNDFIMzA1Ljk3N0g0NzkuOTc5QzQ4OS4xOTcgMzc2LjY1MyA0OTguMDMyIDM3Mi44MTMgNTA0LjE3OSAzNjYuNjY2QzUxMC4zMjQgMzYwLjUyIDUxNC4xNjUgMzUxLjY5MyA1MTQuMTY1IDM0Mi40NjZWMjc3LjE3M1pNMTQuNDM4NiAyNjMuNzMzSDUxNC4xNjVWNDcuODUyOEM1MTQuMTY1IDM4LjYzOTQgNTEwLjMyNCAzMC4xODY0IDUwNC4xNzkgMjQuMDM5N0M0OTguMDMyIDE3Ljg5MzEgNDg5LjE5NyAxNC4wNTI4IDQ3OS45NzkgMTQuMDUyOEg0OC4yMzk5QzM5LjAyMTIgMTQuMDUyOCAzMC41NzA2IDE3Ljg5MzEgMjQuNDI1MiAyNC4wMzk3QzE4LjI3ODYgMzAuMTg2NCAxNC40Mzg2IDM4LjYzOTQgMTQuNDM4NiA0Ny44NTI4VjI2My43MzNaTTIyOS4xNTYgNDY1LjM4NkgyOTkuNDQ4VjM5MC4wOTNIMjI5LjE1NlY0NjUuMzg2Wk0yNzEuNzkyIDMyMC41NzNDMjY5Ljg3MSAzMTguNjUzIDI2Ny4xODMgMzE3LjUwNiAyNjQuMTExIDMxNy41MDZDMjYxLjAzNyAzMTcuNTA2IDI1OC4zNDggMzE4LjY1MyAyNTYuNDI4IDMyMC41NzNDMjU0LjUwNyAzMjIuNDkzIDI1My4zNTUgMzI1LjE4NiAyNTMuMzU1IDMyOC4yNTNDMjUzLjM1NSAzMzEuMzMzIDI1NC41MDcgMzM0LjAxMyAyNTYuNDI4IDMzNS45NDZDMjU4LjM0OCAzMzguMjQgMjYxLjAzNyAzMzkuNCAyNjQuMTExIDMzOS40QzI2Ny4xODMgMzM5LjQgMjY5Ljg3MSAzMzguMjQgMjcxLjc5MiAzMzUuOTQ2QzI3NC4wOTYgMzM0LjAxMyAyNzUuMjQ5IDMzMS4zMzMgMjc1LjI0OSAzMjguMjUzQzI3NS4yNDkgMzI1LjE4NiAyNzQuMDk2IDMyMi40OTMgMjcxLjc5MiAzMjAuNTczWk0yNjQuMTExIDMwMy42OEMyNzEuMDI0IDMwMy42OCAyNzcuMTY5IDMwNi4zNiAyODEuMzk1IDMxMC45NzNDMjg2LjAwNCAzMTUuNTg2IDI4OC42OTMgMzIxLjczMyAyODguNjkzIDMyOC4yNTNDMjg4LjY5MyAzMzUuMTczIDI4Ni4wMDQgMzQxLjMyIDI4MS4zOTUgMzQ1LjU0NkMyNzcuMTY5IDM1MC4xNDYgMjcxLjAyNCAzNTIuODQgMjY0LjExMSAzNTIuODRDMjU3LjU4IDM1Mi44NCAyNTEuNDM1IDM1MC4xNDYgMjQ2LjgyNSAzNDUuNTQ2QzI0Mi4yMTYgMzQxLjMyIDIzOS41MjcgMzM1LjE3MyAyMzkuNTI3IDMyOC4yNTNDMjM5LjUyNyAzMjEuNzMzIDI0Mi4yMTYgMzE1LjU4NiAyNDYuODI1IDMxMC45NzNDMjUxLjQzNSAzMDYuMzYgMjU3LjU4IDMwMy42OCAyNjQuMTExIDMwMy42OFpNNDguMjM5OSAwLjYxMzE4SDQ3OS45NzlDNDkzLjAzOSAwLjYxMzE4IDUwNC45NDcgNS45ODY0MSA1MTMuMzk3IDE0LjQzOTdDNTIyLjIzMiAyMy4yNzk3IDUyNy42MDkgMzQuNzk5NCA1MjcuNjA5IDQ3Ljg1MjhWMjcwLjI1M1YzNDIuNDY2QzUyNy42MDkgMzU1LjUzMyA1MjIuMjMyIDM2Ny40NCA1MTMuNzgxIDM3Ni4yNjZDNTA0Ljk0NyAzODQuNzIgNDkzLjAzOSAzOTAuMDkzIDQ3OS45NzkgMzkwLjA5M0gzMTIuODkyVjQ2NS4zODZIMzcyLjQyOEMzNzYuMjY5IDQ2NS4zODYgMzc5LjM0MyA0NjguNDUzIDM3OS4zNDMgNDcxLjkyQzM3OS4zNDMgNDc1Ljc2IDM3Ni4yNjkgNDc4LjgyNiAzNzIuNDI4IDQ3OC44MjZIMzA2LjM2MUgzMDUuOTc3SDIyMi4yNDFIMjIxLjg1N0gxNTUuNzkxQzE1Mi4zMzMgNDc4LjgyNiAxNDkuMjYxIDQ3NS43NiAxNDkuMjYxIDQ3MS45MkMxNDkuMjYxIDQ2OC40NTMgMTUyLjMzMyA0NjUuMzg2IDE1NS43OTEgNDY1LjM4NkgyMTUuMzI4VjM5MC4wOTNINDguMjM5OUMzNS4xNzk5IDM5MC4wOTMgMjMuMjczMiAzODQuNzIgMTQuODIyNiAzNzYuMjY2QzUuOTg3OTEgMzY3LjQ0IDAuNjEwNTk2IDM1NS41MzMgMC42MTA1OTYgMzQyLjQ2NlYyNzAuMjUzVjQ3Ljg1MjhDMC42MTA1OTYgMzQuNzk5NCA1Ljk4NzkxIDIzLjI3OTcgMTQuODIyNiAxNC40Mzk3QzIzLjI3MzIgNS45ODY0MSAzNS4xNzk5IDAuNjEzMTggNDguMjM5OSAwLjYxMzE4IiBmaWxsPSIjMkUyRDJEIi8+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><path d="M 397 188.5 L 385.73 188.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><image x="396.5" y="179.5" width="18.73" height="17" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjYuOTk4NDEzMDg1OTM3NSIgaGVpZ2h0PSI0NzguMjEyNzk5MDcyMjY1NiIgdmlld0JveD0iMC42MTA1OTYwNjA3NTI4Njg3IDAuNjEzMTgwMDQxMzEzMTcxNCA1MjYuOTk4NDEzMDg1OTM3NSA0NzguMjEyNzk5MDcyMjY1NiIgZmlsbD0ibm9uZSI+JiN4YTs8cGF0aCBkPSJNNTE0LjE2NSAyNzcuMTczSDE0LjQzODZWMzQyLjQ2NkMxNC40Mzg2IDM1MS42OTMgMTguMjc4NiAzNjAuNTIgMjQuNDI1MiAzNjYuNjY2QzMwLjU3MDYgMzcyLjgxMyAzOS4wMjEyIDM3Ni42NTMgNDguMjM5OSAzNzYuNjUzSDIyMi4yNDFIMzA1Ljk3N0g0NzkuOTc5QzQ4OS4xOTcgMzc2LjY1MyA0OTguMDMyIDM3Mi44MTMgNTA0LjE3OSAzNjYuNjY2QzUxMC4zMjQgMzYwLjUyIDUxNC4xNjUgMzUxLjY5MyA1MTQuMTY1IDM0Mi40NjZWMjc3LjE3M1pNMTQuNDM4NiAyNjMuNzMzSDUxNC4xNjVWNDcuODUyOEM1MTQuMTY1IDM4LjYzOTQgNTEwLjMyNCAzMC4xODY0IDUwNC4xNzkgMjQuMDM5N0M0OTguMDMyIDE3Ljg5MzEgNDg5LjE5NyAxNC4wNTI4IDQ3OS45NzkgMTQuMDUyOEg0OC4yMzk5QzM5LjAyMTIgMTQuMDUyOCAzMC41NzA2IDE3Ljg5MzEgMjQuNDI1MiAyNC4wMzk3QzE4LjI3ODYgMzAuMTg2NCAxNC40Mzg2IDM4LjYzOTQgMTQuNDM4NiA0Ny44NTI4VjI2My43MzNaTTIyOS4xNTYgNDY1LjM4NkgyOTkuNDQ4VjM5MC4wOTNIMjI5LjE1NlY0NjUuMzg2Wk0yNzEuNzkyIDMyMC41NzNDMjY5Ljg3MSAzMTguNjUzIDI2Ny4xODMgMzE3LjUwNiAyNjQuMTExIDMxNy41MDZDMjYxLjAzNyAzMTcuNTA2IDI1OC4zNDggMzE4LjY1MyAyNTYuNDI4IDMyMC41NzNDMjU0LjUwNyAzMjIuNDkzIDI1My4zNTUgMzI1LjE4NiAyNTMuMzU1IDMyOC4yNTNDMjUzLjM1NSAzMzEuMzMzIDI1NC41MDcgMzM0LjAxMyAyNTYuNDI4IDMzNS45NDZDMjU4LjM0OCAzMzguMjQgMjYxLjAzNyAzMzkuNCAyNjQuMTExIDMzOS40QzI2Ny4xODMgMzM5LjQgMjY5Ljg3MSAzMzguMjQgMjcxLjc5MiAzMzUuOTQ2QzI3NC4wOTYgMzM0LjAxMyAyNzUuMjQ5IDMzMS4zMzMgMjc1LjI0OSAzMjguMjUzQzI3NS4yNDkgMzI1LjE4NiAyNzQuMDk2IDMyMi40OTMgMjcxLjc5MiAzMjAuNTczWk0yNjQuMTExIDMwMy42OEMyNzEuMDI0IDMwMy42OCAyNzcuMTY5IDMwNi4zNiAyODEuMzk1IDMxMC45NzNDMjg2LjAwNCAzMTUuNTg2IDI4OC42OTMgMzIxLjczMyAyODguNjkzIDMyOC4yNTNDMjg4LjY5MyAzMzUuMTczIDI4Ni4wMDQgMzQxLjMyIDI4MS4zOTUgMzQ1LjU0NkMyNzcuMTY5IDM1MC4xNDYgMjcxLjAyNCAzNTIuODQgMjY0LjExMSAzNTIuODRDMjU3LjU4IDM1Mi44NCAyNTEuNDM1IDM1MC4xNDYgMjQ2LjgyNSAzNDUuNTQ2QzI0Mi4yMTYgMzQxLjMyIDIzOS41MjcgMzM1LjE3MyAyMzkuNTI3IDMyOC4yNTNDMjM5LjUyNyAzMjEuNzMzIDI0Mi4yMTYgMzE1LjU4NiAyNDYuODI1IDMxMC45NzNDMjUxLjQzNSAzMDYuMzYgMjU3LjU4IDMwMy42OCAyNjQuMTExIDMwMy42OFpNNDguMjM5OSAwLjYxMzE4SDQ3OS45NzlDNDkzLjAzOSAwLjYxMzE4IDUwNC45NDcgNS45ODY0MSA1MTMuMzk3IDE0LjQzOTdDNTIyLjIzMiAyMy4yNzk3IDUyNy42MDkgMzQuNzk5NCA1MjcuNjA5IDQ3Ljg1MjhWMjcwLjI1M1YzNDIuNDY2QzUyNy42MDkgMzU1LjUzMyA1MjIuMjMyIDM2Ny40NCA1MTMuNzgxIDM3Ni4yNjZDNTA0Ljk0NyAzODQuNzIgNDkzLjAzOSAzOTAuMDkzIDQ3OS45NzkgMzkwLjA5M0gzMTIuODkyVjQ2NS4zODZIMzcyLjQyOEMzNzYuMjY5IDQ2NS4zODYgMzc5LjM0MyA0NjguNDUzIDM3OS4zNDMgNDcxLjkyQzM3OS4zNDMgNDc1Ljc2IDM3Ni4yNjkgNDc4LjgyNiAzNzIuNDI4IDQ3OC44MjZIMzA2LjM2MUgzMDUuOTc3SDIyMi4yNDFIMjIxLjg1N0gxNTUuNzkxQzE1Mi4zMzMgNDc4LjgyNiAxNDkuMjYxIDQ3NS43NiAxNDkuMjYxIDQ3MS45MkMxNDkuMjYxIDQ2OC40NTMgMTUyLjMzMyA0NjUuMzg2IDE1NS43OTEgNDY1LjM4NkgyMTUuMzI4VjM5MC4wOTNINDguMjM5OUMzNS4xNzk5IDM5MC4wOTMgMjMuMjczMiAzODQuNzIgMTQuODIyNiAzNzYuMjY2QzUuOTg3OTEgMzY3LjQ0IDAuNjEwNTk2IDM1NS41MzMgMC42MTA1OTYgMzQyLjQ2NlYyNzAuMjUzVjQ3Ljg1MjhDMC42MTA1OTYgMzQuNzk5NCA1Ljk4NzkxIDIzLjI3OTcgMTQuODIyNiAxNC40Mzk3QzIzLjI3MzIgNS45ODY0MSAzNS4xNzk5IDAuNjEzMTggNDguMjM5OSAwLjYxMzE4IiBmaWxsPSIjMkUyRDJEIi8+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><path d="M 381.52 205.22 L 376.37 197" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 401.19 205.9 L 406.37 197" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><image x="372.54" y="204.72" width="33.92" height="30.78" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MjYuOTk4NDEzMDg1OTM3NSIgaGVpZ2h0PSI0NzguMjEyNzk5MDcyMjY1NiIgdmlld0JveD0iMC42MTA1OTYwNjA3NTI4Njg3IDAuNjEzMTgwMDQxMzEzMTcxNCA1MjYuOTk4NDEzMDg1OTM3NSA0NzguMjEyNzk5MDcyMjY1NiIgZmlsbD0ibm9uZSI+JiN4YTs8cGF0aCBkPSJNNTE0LjE2NSAyNzcuMTczSDE0LjQzODZWMzQyLjQ2NkMxNC40Mzg2IDM1MS42OTMgMTguMjc4NiAzNjAuNTIgMjQuNDI1MiAzNjYuNjY2QzMwLjU3MDYgMzcyLjgxMyAzOS4wMjEyIDM3Ni42NTMgNDguMjM5OSAzNzYuNjUzSDIyMi4yNDFIMzA1Ljk3N0g0NzkuOTc5QzQ4OS4xOTcgMzc2LjY1MyA0OTguMDMyIDM3Mi44MTMgNTA0LjE3OSAzNjYuNjY2QzUxMC4zMjQgMzYwLjUyIDUxNC4xNjUgMzUxLjY5MyA1MTQuMTY1IDM0Mi40NjZWMjc3LjE3M1pNMTQuNDM4NiAyNjMuNzMzSDUxNC4xNjVWNDcuODUyOEM1MTQuMTY1IDM4LjYzOTQgNTEwLjMyNCAzMC4xODY0IDUwNC4xNzkgMjQuMDM5N0M0OTguMDMyIDE3Ljg5MzEgNDg5LjE5NyAxNC4wNTI4IDQ3OS45NzkgMTQuMDUyOEg0OC4yMzk5QzM5LjAyMTIgMTQuMDUyOCAzMC41NzA2IDE3Ljg5MzEgMjQuNDI1MiAyNC4wMzk3QzE4LjI3ODYgMzAuMTg2NCAxNC40Mzg2IDM4LjYzOTQgMTQuNDM4NiA0Ny44NTI4VjI2My43MzNaTTIyOS4xNTYgNDY1LjM4NkgyOTkuNDQ4VjM5MC4wOTNIMjI5LjE1NlY0NjUuMzg2Wk0yNzEuNzkyIDMyMC41NzNDMjY5Ljg3MSAzMTguNjUzIDI2Ny4xODMgMzE3LjUwNiAyNjQuMTExIDMxNy41MDZDMjYxLjAzNyAzMTcuNTA2IDI1OC4zNDggMzE4LjY1MyAyNTYuNDI4IDMyMC41NzNDMjU0LjUwNyAzMjIuNDkzIDI1My4zNTUgMzI1LjE4NiAyNTMuMzU1IDMyOC4yNTNDMjUzLjM1NSAzMzEuMzMzIDI1NC41MDcgMzM0LjAxMyAyNTYuNDI4IDMzNS45NDZDMjU4LjM0OCAzMzguMjQgMjYxLjAzNyAzMzkuNCAyNjQuMTExIDMzOS40QzI2Ny4xODMgMzM5LjQgMjY5Ljg3MSAzMzguMjQgMjcxLjc5MiAzMzUuOTQ2QzI3NC4wOTYgMzM0LjAxMyAyNzUuMjQ5IDMzMS4zMzMgMjc1LjI0OSAzMjguMjUzQzI3NS4yNDkgMzI1LjE4NiAyNzQuMDk2IDMyMi40OTMgMjcxLjc5MiAzMjAuNTczWk0yNjQuMTExIDMwMy42OEMyNzEuMDI0IDMwMy42OCAyNzcuMTY5IDMwNi4zNiAyODEuMzk1IDMxMC45NzNDMjg2LjAwNCAzMTUuNTg2IDI4OC42OTMgMzIxLjczMyAyODguNjkzIDMyOC4yNTNDMjg4LjY5MyAzMzUuMTczIDI4Ni4wMDQgMzQxLjMyIDI4MS4zOTUgMzQ1LjU0NkMyNzcuMTY5IDM1MC4xNDYgMjcxLjAyNCAzNTIuODQgMjY0LjExMSAzNTIuODRDMjU3LjU4IDM1Mi44NCAyNTEuNDM1IDM1MC4xNDYgMjQ2LjgyNSAzNDUuNTQ2QzI0Mi4yMTYgMzQxLjMyIDIzOS41MjcgMzM1LjE3MyAyMzkuNTI3IDMyOC4yNTNDMjM5LjUyNyAzMjEuNzMzIDI0Mi4yMTYgMzE1LjU4NiAyNDYuODI1IDMxMC45NzNDMjUxLjQzNSAzMDYuMzYgMjU3LjU4IDMwMy42OCAyNjQuMTExIDMwMy42OFpNNDguMjM5OSAwLjYxMzE4SDQ3OS45NzlDNDkzLjAzOSAwLjYxMzE4IDUwNC45NDcgNS45ODY0MSA1MTMuMzk3IDE0LjQzOTdDNTIyLjIzMiAyMy4yNzk3IDUyNy42MDkgMzQuNzk5NCA1MjcuNjA5IDQ3Ljg1MjhWMjcwLjI1M1YzNDIuNDY2QzUyNy42MDkgMzU1LjUzMyA1MjIuMjMyIDM2Ny40NCA1MTMuNzgxIDM3Ni4yNjZDNTA0Ljk0NyAzODQuNzIgNDkzLjAzOSAzOTAuMDkzIDQ3OS45NzkgMzkwLjA5M0gzMTIuODkyVjQ2NS4zODZIMzcyLjQyOEMzNzYuMjY5IDQ2NS4zODYgMzc5LjM0MyA0NjguNDUzIDM3OS4zNDMgNDcxLjkyQzM3OS4zNDMgNDc1Ljc2IDM3Ni4yNjkgNDc4LjgyNiAzNzIuNDI4IDQ3OC44MjZIMzA2LjM2MUgzMDUuOTc3SDIyMi4yNDFIMjIxLjg1N0gxNTUuNzkxQzE1Mi4zMzMgNDc4LjgyNiAxNDkuMjYxIDQ3NS43NiAxNDkuMjYxIDQ3MS45MkMxNDkuMjYxIDQ2OC40NTMgMTUyLjMzMyA0NjUuMzg2IDE1NS43OTEgNDY1LjM4NkgyMTUuMzI4VjM5MC4wOTNINDguMjM5OUMzNS4xNzk5IDM5MC4wOTMgMjMuMjczMiAzODQuNzIgMTQuODIyNiAzNzYuMjY2QzUuOTg3OTEgMzY3LjQ0IDAuNjEwNTk2IDM1NS41MzMgMC42MTA1OTYgMzQyLjQ2NlYyNzAuMjUzVjQ3Ljg1MjhDMC42MTA1OTYgMzQuNzk5NCA1Ljk4NzkxIDIzLjI3OTcgMTQuODIyNiAxNC40Mzk3QzIzLjI3MzIgNS45ODY0MSAzNS4xNzk5IDAuNjEzMTggNDguMjM5OSAwLjYxMzE4IiBmaWxsPSIjMkUyRDJEIi8+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than diagrams.net -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="601px" height="549px" viewBox="-0.5 -0.5 601 549" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2022-03-27T02:10:26.197Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36&quot; etag=&quot;HVJ6BvLpXxYQWVEogCeM&quot; version=&quot;17.2.4&quot; type=&quot;google&quot; pages=&quot;5&quot;&gt;&lt;diagram id=&quot;pa5Zq7vvImeQUXFm5tUZ&quot; name=&quot;Verifier&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;6hN7fcHnLs0WyHn6UafR&quot; name=&quot;Sequencer&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;-hkjP0EtaJXZYg540UFq&quot; name=&quot;Withdrawal&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;YIQN2cyMAm-IvyV_td1r&quot; name=&quot;Network High Level&quot;&gt;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&lt;/diagram&gt;&lt;diagram id=&quot;DTTy1wCJd32_-uvfoNST&quot; name=&quot;Pluggable Proof&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 125.01 238 L 125 291.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 125 296.88 L 121.5 289.88 L 125 291.63 L 128.5 289.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 259px; margin-left: 129px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 9px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><font style="font-size: 12px"><b style="font-size: 11px">2. </b>Insert and reorg blocks</font></div></div></div></foreignObject><text x="129" y="261" fill="#000000" font-family="Helvetica" font-size="9px" text-anchor="middle">2. Insert and reorg blocks</text></switch></g><rect x="2.86" y="148" width="244.29" height="90" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 242px; height: 1px; padding-top: 155px; margin-left: 4px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>Rollup Node</b></div></div></div></foreignObject><text x="125" y="167" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup Node</text></switch></g><path d="M 127.11 96.21 L 127.1 118 L 125 118 L 125.01 148" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 127.11 90.96 L 130.61 97.96 L 127.11 96.21 L 123.61 97.96 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 118px; margin-left: 128px;"><div data-drawio-colors="color: #FFFFFF; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(255, 255, 255); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"><font color="#000000"><b>1.</b> Get Blocks</font></div></div></div></foreignObject><text x="128" y="122" fill="#FFFFFF" font-family="Helvetica" font-size="11px" text-anchor="middle">1. Get Blocks</text></switch></g><rect x="0" y="48" width="570" height="40" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 568px; height: 1px; padding-top: 68px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Ethereum L1 Chain</div></div></div></foreignObject><text x="285" y="72" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Ethereum L1 Chain</text></switch></g><rect x="85" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 105 220 L 95 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="105" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 125 220 L 115 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="125" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 218px; margin-left: 65px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><font face="Times New Roman"><i>Rollup</i>(</font></div></div></div></foreignObject><text x="65" y="222" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Rollup(</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 218px; margin-left: 137px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><div><span style="font-family: &quot;times new roman&quot;">)</span></div></div></div></div></foreignObject><text x="137" y="222" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">)</text></switch></g><path d="M 145 220 L 155.63 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 157.88 220 L 154.88 221.5 L 155.63 220 L 154.88 218.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 218px; margin-left: 110px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: &quot;Times New Roman&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><font face="Helvetica" style="background-color: rgb(102 , 51 , 0)" color="#ffffff">L1</font></div></div></div></foreignObject><text x="110" y="222" fill="rgb(0, 0, 0)" font-family="Times New Roman" font-size="12px" text-anchor="middle">L1</text></switch></g><rect x="165" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 185 220 L 175 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="185" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 205 220 L 195 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="205" y="215" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 218px; margin-left: 190px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: &quot;Times New Roman&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><font face="Helvetica" style="background-color: rgb(0 , 51 , 102)" color="#ffffff">L2</font></div></div></div></foreignObject><text x="190" y="222" fill="rgb(0, 0, 0)" font-family="Times New Roman" font-size="12px" text-anchor="middle">L2</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 189px; margin-left: 125px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><i>Transform latest L1 blocks <br />into L2 block inputs</i></div></div></div></foreignObject><text x="125" y="193" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Transform latest L1 blocks...</text></switch></g><rect x="0" y="298" width="250" height="120" fill="#e1d5e7" stroke="#9673a6" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 305px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><b>Execution Engine</b></div></div></div></foreignObject><text x="125" y="317" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Execution Engine</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 64px; height: 1px; padding-top: 321px; margin-left: 93px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><font style="font-size: 9px">(eg. Geth)</font></div></div></div></foreignObject><text x="125" y="325" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">(eg. Geth)</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 358px; margin-left: 125px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><i>Execute blocks, store the chain,<br />serve RPC calls.</i></div></div></div></foreignObject><text x="125" y="362" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Execute blocks, store the chai...</text></switch></g><rect x="62" y="388" width="30" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 398px; margin-left: 63px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">EVM</div></div></div></foreignObject><text x="77" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">EVM</text></switch></g><rect x="105" y="388" width="40" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 398px; margin-left: 106px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Chain</div></div></div></foreignObject><text x="125" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Chain</text></switch></g><rect x="158" y="388" width="40" height="20" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 398px; margin-left: 159px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">State</div></div></div></foreignObject><text x="178" y="402" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">State</text></switch></g><rect x="240" y="313" width="30" height="90" fill="#e1d5e7" stroke="#9673a6" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 358px; margin-left: 241px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">RPC</div></div></div></foreignObject><text x="255" y="362" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">RPC</text></switch></g><path d="M 371.25 227.34 L 371.3 172.92 L 371.09 124.87" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 371.07 119.62 L 374.6 126.61 L 371.09 124.87 L 367.6 126.64 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 167px; margin-left: 358px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b style="font-size: 11px">3. </b>Read <br />BlockHash<br />Assertion</div></div></div></foreignObject><text x="358" y="171" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">3. Read...</text></switch></g><path d="M 320 255.5 L 295 255.5 L 295 324 L 276.88 323.99" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 271.63 323.98 L 278.63 320.49 L 276.88 323.99 L 278.63 327.49 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 261px; margin-left: 277px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>4. </b>Get<br />corresponding<br />block hash</div></div></div></foreignObject><text x="277" y="265" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">4. Get...</text></switch></g><path d="M 445 338 L 445 411.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 445 416.88 L 441.5 409.88 L 445 411.63 L 448.5 409.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 375px; margin-left: 446px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>5. </b>Get witness<br />for invalid assertion</div></div></div></foreignObject><text x="446" y="378" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">5. Get witness...</text></switch></g><path d="M 445 228 L 445 188 L 445.63 154.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 445.73 149.12 L 449.1 156.18 L 445.63 154.37 L 442.1 156.05 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 183px; margin-left: 448px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>6. </b>Isolate disputed<br />state transition</div></div></div></foreignObject><text x="448" y="187" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">6. Isolate disputed...</text></switch></g><path d="M 517.25 227.34 L 517.3 188 L 517.05 154.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 517.01 149.12 L 520.56 156.09 L 517.05 154.37 L 513.56 156.14 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 184px; margin-left: 551px;"><div data-drawio-colors="color: #000000; background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;"><b>7. </b>Verify disputed<br />state transition</div></div></div></foreignObject><text x="551" y="187" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">7. Verify disputed...</text></switch></g><rect x="320" y="228" width="250" height="110" fill="#f8cecc" stroke="#b85450" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 235px; margin-left: 321px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><b>Challenger Agent</b></div></div></div></foreignObject><text x="445" y="247" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Challenger Agent</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 273px; margin-left: 445px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><i>Watches L1 chain for fault &amp; performs<br /></i>challenges.</div></div></div></foreignObject><text x="445" y="277" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Watches L1 chain for fault &amp; perform...</text></switch></g><path d="M 35 68 L 25 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="35" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 55 68 L 45 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="55" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 75 68 L 65 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="75" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 95 68 L 85 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="95" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 115 68 L 105 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="115" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 135 68 L 125 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="135" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 155 68 L 145 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="155" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 175 68 L 165 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="175" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 387.5 68 L 377.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="387.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 407.5 68 L 397.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="407.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 427.5 68 L 417.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="427.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 447.5 68 L 437.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="447.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 467.5 68 L 457.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="467.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 487.5 68 L 477.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="487.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 507.5 68 L 497.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="507.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><path d="M 527.5 68 L 517.5 68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><rect x="527.5" y="63" width="10" height="10" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 317px; margin-left: 458px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><font face="Times New Roman"><i>local_blockhash ≠ assertion_blockhash</i></font></div></div></div></foreignObject><text x="458" y="321" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">local_blockhash ≠ assertion_blockhash</text></switch></g><rect x="320" y="418" width="250" height="130" fill="#ffe6cc" stroke="#d79b00" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 248px; height: 1px; padding-top: 425px; margin-left: 321px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><b>Fault Proof VM</b></div></div></div></foreignObject><text x="445" y="437" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Fault Proof VM</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 463px; margin-left: 445px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: nowrap;"><i>Executes blocks in the fault proof VM and<br />generates witnesses.<br /></i></div></div></div></foreignObject><text x="445" y="467" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Executes blocks in the fault proof VM an...</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 208px; height: 1px; padding-top: 495px; margin-left: 392px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px">Data to</span><span style="font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px"><font color="#000000"> generate the witnesses<br /></font></span><span style="font-family: &quot;helvetica&quot;">(eg. storage, blocks...)</span><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px ; background-color: rgb(248 , 249 , 250)"><br /></span><span style="font-family: &quot;helvetica&quot;">is</span><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot;"> fetched from L1 &amp; L2 nodes</span><span style="color: rgb(0 , 0 , 0) ; font-family: &quot;helvetica&quot; ; font-size: 12px ; font-weight: 400 ; letter-spacing: normal ; text-indent: 0px ; text-transform: none ; word-spacing: 0px">.</span></div></div></div></foreignObject><text x="392" y="507" fill="#333333" font-family="Helvetica" font-size="12px">Data to generate the witnesses...</text></switch></g><rect x="330" y="82" width="232" height="36" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 230px; height: 1px; padding-top: 89px; margin-left: 331px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">L2 Output Oracle Contract</div></div></div></foreignObject><text x="446" y="101" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">L2 Output Oracle Contract</text></switch></g><rect x="415.75" y="112" width="60" height="36" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 130px; margin-left: 417px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">k-section<br />game</div></div></div></foreignObject><text x="446" y="134" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">k-section...</text></switch></g><rect x="482" y="112" width="70" height="36" fill="#dae8fc" stroke="#6c8ebf" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 68px; height: 1px; padding-top: 130px; margin-left: 483px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">Single-step<br />verifier</div></div></div></foreignObject><text x="517" y="134" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Single-step...</text></switch></g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 518px; height: 1px; padding-top: 30px; margin-left: 2px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><h1>Verifier Detecting &amp; Executing a Fault Proof</h1></div></div></div></foreignObject><text x="2" y="34" fill="#000000" font-family="Helvetica" font-size="12px">Verifier Detecting &amp; Executing a Fault Proof</text></switch></g><image x="346.6" y="53.5" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="204.6" y="54" width="17.81" height="29" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjU1Ljk5OTExNDk5MDIzNDM4IiBoZWlnaHQ9IjQxNi45MDY1ODU2OTMzNTk0IiB2aWV3Qm94PSIwIDAgMjU1Ljk5OTExNDk5MDIzNDM4IDQxNi45MDY1ODU2OTMzNTk0IiB2ZXJzaW9uPSIxLjEiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4mI3hhOwk8Zz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM0MzQzNCIgcG9pbnRzPSIxMjcuOTYxMSAwIDEyNS4xNjYxIDkuNSAxMjUuMTY2MSAyODUuMTY4IDEyNy45NjExIDI4Ny45NTggMjU1LjkyMzEgMjEyLjMyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiM4QzhDOEMiIHBvaW50cz0iMTI3Ljk2MiAwIDAgMjEyLjMyIDEyNy45NjIgMjg3Ljk1OSAxMjcuOTYyIDE1NC4xNTgiLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzNDM0MzQiIgcG9pbnRzPSIxMjcuOTYxMSAzMTIuMTg2NiAxMjYuMzg2MSAzMTQuMTA2NiAxMjYuMzg2MSA0MTIuMzA1NiAxMjcuOTYxMSA0MTYuOTA2NiAyNTUuOTk5MSAyMzYuNTg2NiIvPiYjeGE7CQk8cG9seWdvbiBmaWxsPSIjOEM4QzhDIiBwb2ludHM9IjEyNy45NjIgNDE2LjkwNTIgMTI3Ljk2MiAzMTIuMTg1MiAwIDIzNi41ODUyIi8+JiN4YTsJCTxwb2x5Z29uIGZpbGw9IiMxNDE0MTQiIHBvaW50cz0iMTI3Ljk2MTEgMjg3Ljk1NzcgMjU1LjkyMTEgMjEyLjMyMDcgMTI3Ljk2MTEgMTU0LjE1ODciLz4mI3hhOwkJPHBvbHlnb24gZmlsbD0iIzM5MzkzOSIgcG9pbnRzPSIwLjAwMDkgMjEyLjMyMDggMTI3Ljk2MDkgMjg3Ljk1NzggMTI3Ljk2MDkgMTU0LjE1ODgiLz4mI3hhOwk8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="329.5" y="303.5" width="28.79" height="26" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiB3aWR0aD0iNjEuNjMzOTQ5Mjc5Nzg1MTU2IiBoZWlnaHQ9IjU2LjIxNjk1NzA5MjI4NTE1NiIgaWQ9InN2ZzIzOTAiIHNvZGlwb2RpOnZlcnNpb249IjAuMzIiIGlua3NjYXBlOnZlcnNpb249IjAuNDYiIHZlcnNpb249IjEuMCIgc29kaXBvZGk6ZG9jbmFtZT0id2FybmluZy5zdmciIGlua3NjYXBlOm91dHB1dF9leHRlbnNpb249Im9yZy5pbmtzY2FwZS5vdXRwdXQuc3ZnLmlua3NjYXBlIiB2aWV3Qm94PSI5LjEzMTY3MTkwNTUxNzU3OCAxMS42NTcwNTQ5MDExMjMwNDcgNjEuNjMzOTQ5Mjc5Nzg1MTU2IDU2LjIxNjk1NzA5MjI4NTE1NiI+JiN4YTsgIDxkZWZzIGlkPSJkZWZzMjM5MiI+JiN4YTsgICAgPGlua3NjYXBlOnBlcnNwZWN0aXZlIHNvZGlwb2RpOnR5cGU9Imlua3NjYXBlOnBlcnNwM2QiIGlua3NjYXBlOnZwX3g9IjAgOiA1MjYuMTgxMDkgOiAxIiBpbmtzY2FwZTp2cF95PSIwIDogMTAwMCA6IDAiIGlua3NjYXBlOnZwX3o9Ijc0NC4wOTQ0OCA6IDUyNi4xODEwOSA6IDEiIGlua3NjYXBlOnBlcnNwM2Qtb3JpZ2luPSIzNzIuMDQ3MjQgOiAzNTAuNzg3MzkgOiAxIiBpZD0icGVyc3BlY3RpdmUyMzk4Ii8+JiN4YTsgIDwvZGVmcz4mI3hhOyAgPHNvZGlwb2RpOm5hbWVkdmlldyBpZD0iYmFzZSIgcGFnZWNvbG9yPSIjZmZmZmZmIiBib3JkZXJjb2xvcj0iIzY2NjY2NiIgYm9yZGVyb3BhY2l0eT0iMS4wIiBncmlkdG9sZXJhbmNlPSIxMDAwMCIgZ3VpZGV0b2xlcmFuY2U9IjEwIiBvYmplY3R0b2xlcmFuY2U9IjEwIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIiBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIiBpbmtzY2FwZTp6b29tPSIxLjk3OTg5OSIgaW5rc2NhcGU6Y3g9IjEwOS44MTY1OSIgaW5rc2NhcGU6Y3k9IjYyLjU4OTM5IiBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIgc2hvd2dyaWQ9ImZhbHNlIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjY0MCIgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iNzE1IiBpbmtzY2FwZTp3aW5kb3cteD0iOTUwIiBpbmtzY2FwZTp3aW5kb3cteT0iMzkyIi8+JiN4YTsgIDxtZXRhZGF0YSBpZD0ibWV0YWRhdGEyMzk1Ij4mI3hhOyAgICA8cmRmOnJkZj4mI3hhOyAgICAgIDxjYzp3b3JrIHJkZjphYm91dD0iIj4mI3hhOyAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+JiN4YTsgICAgICAgIDxkYzp0eXBlIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiLz4mI3hhOyAgICAgIDwvY2M6d29yaz4mI3hhOyAgICA8L3JkZjpyZGY+JiN4YTsgIDwvbWV0YWRhdGE+JiN4YTsgIDxnIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIiBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIiBpZD0ibGF5ZXIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjEuOTEzMjE0LC0xNi45ODM4OSkiPiYjeGE7ICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDAuNDU1NDA3LDAsMCwwLjQ1NTQwNywyNi4yNzE0NDcsMjMuODY3NTE3KSIgc3R5bGU9ImZpbGw6I2ZmZDQyYTtmaWxsLW9wYWNpdHk6MSIgaWQ9ImcyMzg3IiBpbmtzY2FwZTpleHBvcnQtZmlsZW5hbWU9Ii9ob21lL21nc21pdGgvRGVza3RvcC93YXJuaW5nLnBuZyIgaW5rc2NhcGU6ZXhwb3J0LXhkcGk9IjkwIiBpbmtzY2FwZTpleHBvcnQteWRwaT0iOTAiPiYjeGE7ICAgICAgPHBhdGggc3R5bGU9ImZpbGw6I2ZmZDQyYTtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzAwMDAwMDtzdHJva2Utd2lkdGg6Ni44MzEzNzk0MTtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIgc29kaXBvZGk6bm9kZXR5cGVzPSJjY2NjY2NjY2NjYyIgaWQ9InBhdGgyMzg5IiBkPSJNIDEyLjQ3MywxMjEuMDgyIEMgMTEuNTU5MDMzLDEyMi44NDMyOSAxMC40ODE4LDEyNC40OSAxMC40ODE3LDEyNi40MjMgTCAxMC40OTA3MjgsMTI3LjIzMDg4IEMgMTAuNDkwNzI4LDEzMS40MDI4OCAxMy43NTY2LDEzMy45MjUgMTcuNTExMywxMzMuOTI1IEwgMTM4LjgzMSwxMzMuOTI1IEMgMTQyLjU4NiwxMzMuOTI1IDE0NS44MTk4NiwxMzAuNzk4NDggMTQ1LjgxOTg2LDEyNi42MjY0OCBMIDE0NS43OCwxMjUuODE1IEMgMTQ1Ljc4LDEyMy44ODIgMTQ0LjgyOTcxLDEyMi4yMDM0OCAxNDMuNzg5LDEyMC40NzQgTCA4My43MDU2LDEyLjY5MzggQyA4MS4wNTEsOS43NDQyMyA3Ni43NDczLDkuNzQ0MjMgNzQuMDkyMywxMi42OTQyIEwgMTIuNDczLDEyMS4wODIgeiIvPiYjeGE7ICAgIDwvZz4mI3hhOyAgICA8cGF0aCB0cmFuc2Zvcm09Im1hdHJpeCgwLjU0MjExNzgsMCwwLDAuNTQyMTE3OCw0OS41NDYzOTcsMzMuNzMxNDgxKSIgZD0iTSAzMS45NjI5MjQsNzQuNDc1MzggQSA4LjA0MTYyNjksOC4wNDE2MjY5IDAgMSAxIDE1Ljg3OTY3LDc0LjQ3NTM4IEEgOC4wNDE2MjY5LDguMDQxNjI2OSAwIDEgMSAzMS45NjI5MjQsNzQuNDc1MzggeiIgc29kaXBvZGk6cnk9IjguMDQxNjI2OSIgc29kaXBvZGk6cng9IjguMDQxNjI2OSIgc29kaXBvZGk6Y3k9Ijc0LjQ3NTM4IiBzb2RpcG9kaTpjeD0iMjMuOTIxMjk3IiBpZD0icGF0aDIzOTMiIHN0eWxlPSJvcGFjaXR5OjE7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDttYXJrZXI6bm9uZTttYXJrZXItc3RhcnQ6bm9uZTttYXJrZXItbWlkOm5vbmU7bWFya2VyLWVuZDpub25lO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTo0LCA0O3N0cm9rZS1kYXNob2Zmc2V0OjU7c3Ryb2tlLW9wYWNpdHk6MTt2aXNpYmlsaXR5OnZpc2libGU7ZGlzcGxheTppbmxpbmU7b3ZlcmZsb3c6dmlzaWJsZTtlbmFibGUtYmFja2dyb3VuZDphY2N1bXVsYXRlIiBzb2RpcG9kaTp0eXBlPSJhcmMiIGlua3NjYXBlOmV4cG9ydC1maWxlbmFtZT0iL2hvbWUvbWdzbWl0aC9EZXNrdG9wL3dhcm5pbmcucG5nIiBpbmtzY2FwZTpleHBvcnQteGRwaT0iOTAiIGlua3NjYXBlOmV4cG9ydC15ZHBpPSI5MCIvPiYjeGE7ICAgIDxwYXRoIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2Njc2NjYyIgaWQ9InBhdGgyMzk1IiBkPSJNIDYyLjQ4NjE2Nyw0My44MTY5MzggQyA2NC4xOTg4NTcsNDMuODE2OTM4IDY2Ljg1Njg4Nyw0NS4xODE1MDcgNjYuODU2ODg3LDQ2Ljg3NjUwOCBMIDY1LjU3NzY1Nyw2NC40OTIyMTYgQyA2NS41Nzc2NTcsNjYuMTg3MjIxIDY0LjE5ODg1Nyw2Ny41NTE3ODYgNjIuNDg2MTY3LDY3LjU1MTc4NiBDIDYwLjc3MzQ4Nyw2Ny41NTE3ODYgNTkuMzk0Njg3LDY2LjE4NzIyMSA1OS4zOTQ2ODcsNjQuNDkyMjE2IEwgNTcuOTAyMjQ3LDQ2Ljg3NjUwOCBDIDU3LjkwMjI0Nyw0NS4xODE1MDcgNjAuNzczNDg3LDQzLjgxNjkzOCA2Mi40ODYxNjcsNDMuODE2OTM4IHoiIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjI7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO21hcmtlcjpub25lO21hcmtlci1zdGFydDpub25lO21hcmtlci1taWQ6bm9uZTttYXJrZXItZW5kOm5vbmU7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5OjQsIDQ7c3Ryb2tlLWRhc2hvZmZzZXQ6NTtzdHJva2Utb3BhY2l0eToxO3Zpc2liaWxpdHk6dmlzaWJsZTtkaXNwbGF5OmlubGluZTtvdmVyZmxvdzp2aXNpYmxlO2VuYWJsZS1iYWNrZ3JvdW5kOmFjY3VtdWxhdGUiIGlua3NjYXBlOmV4cG9ydC1maWxlbmFtZT0iL2hvbWUvbWdzbWl0aC9EZXNrdG9wL3dhcm5pbmcucG5nIiBpbmtzY2FwZTpleHBvcnQteGRwaT0iOTAiIGlua3NjYXBlOmV4cG9ydC15ZHBpPSI5MCIvPiYjeGE7ICA8L2c+JiN4YTs8L3N2Zz4=" preserveAspectRatio="none" pointer-events="none"/><image x="337" y="492.5" width="40" height="40" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDQ0LjQ2NDk2NTgyMDMxMjUgNDQ0LjQ2MTk3NTA5NzY1NjI1IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0NDQuNDYyIDQ0NC40NjI7IiB4bWw6c3BhY2U9InByZXNlcnZlIiB3aWR0aD0iNDQ0LjQ2NDk2NTgyMDMxMjUiIGhlaWdodD0iNDQ0LjQ2MTk3NTA5NzY1NjI1Ij4mI3hhOzxnPiYjeGE7CTxwYXRoIGQ9Ik0zMTcuMTY2LDExOS43OTZIMTI3LjI5N2MtNC4xNDMsMC03LjUsMy4zNTgtNy41LDcuNXYxODkuODY5YzAsNC4xNDIsMy4zNTcsNy41LDcuNSw3LjVoMTg5Ljg2OSYjMTA7JiM5OyYjOTtjNC4xNDMsMCw3LjUtMy4zNTgsNy41LTcuNVYxMjcuMjk2QzMyNC42NjYsMTIzLjE1NCwzMjEuMzA5LDExOS43OTYsMzE3LjE2NiwxMTkuNzk2eiBNMzA5LjY2NiwzMDkuNjY2SDEzNC43OTdWMTM0Ljc5NmgxNzQuODY5JiMxMDsmIzk7JiM5O1YzMDkuNjY2eiIvPiYjeGE7CTxwYXRoIGQ9Ik0xODUuODg3LDI2Ni4wNzZoNzIuNjg5YzQuMTQzLDAsNy41LTMuMzU4LDcuNS03LjV2LTcyLjY4OWMwLTQuMTQyLTMuMzU3LTcuNS03LjUtNy41aC03Mi42ODljLTQuMTQzLDAtNy41LDMuMzU4LTcuNSw3LjUmIzEwOyYjOTsmIzk7djcyLjY4OUMxNzguMzg3LDI2Mi43MTgsMTgxLjc0NCwyNjYuMDc2LDE4NS44ODcsMjY2LjA3NnogTTE5My4zODcsMTkzLjM4Nmg1Ny42ODl2NTcuNjg5aC01Ny42ODlWMTkzLjM4NnoiLz4mI3hhOwk8cGF0aCBkPSJNMzA1LjUyNCwxNWM2Ljk2LDAsMTAuMDgyLTkuMDY4LDQuNjM3LTEzLjM4OWMtNS40MDgtNC4yOTItMTMuNTM1LDAuODMyLTExLjk0OCw3LjU3OSYjMTA7JiM5OyYjOTtDMjk5LjAwNCwxMi41NDcsMzAyLjA2OCwxNSwzMDUuNTI0LDE1eiIvPiYjeGE7CTxwYXRoIGQ9Ik0xNDMuMTA0LDQzMC43M2MtMi40NTQtMS42MTYtNS42NDktMS42NjEtOC4xNDYtMC4xMTNjLTIuODkxLDEuNzkyLTQuMjExLDUuNDcxLTMuMTM1LDguNjk4JiMxMDsmIzk7JiM5O2MwLjk3OCwyLjkzLDMuNzE1LDUuMDE1LDYuODA5LDUuMTM4YzMuMTkxLDAuMTI3LDYuMTQzLTEuODI2LDcuMjk5LTQuNzk0QzE0Ny4xODUsNDM2LjQzNywxNDYsNDMyLjYzNiwxNDMuMTA0LDQzMC43M3oiLz4mI3hhOwk8cGF0aCBkPSJNNDM2Ljk2MiwxODguMDg2YzQuMTQzLDAsNy41LTMuMzU4LDcuNS03LjVzLTMuMzU3LTcuNS03LjUtNy41aC04Mi4yOTZ2LTI2LjY0NWg4Mi4yOTZjNC4xNDMsMCw3LjUtMy4zNTgsNy41LTcuNSYjMTA7JiM5OyYjOTtzLTMuMzU3LTcuNS03LjUtNy41aC04Mi4yOTZ2LTUuMzkyYzAtMTkuOTktMTYuMjY0LTM2LjI1My0zNi4yNTQtMzYuMjUzaC01LjM5MlYzMS42YzAtNC4xNDItMy4zNTctNy41LTcuNS03LjUmIzEwOyYjOTsmIzk7cy03LjUsMy4zNTgtNy41LDcuNXY1OC4xOTZoLTI2LjY0NVY3LjVjMC00LjE0Mi0zLjM1Ny03LjUtNy41LTcuNXMtNy41LDMuMzU4LTcuNSw3LjV2ODIuMjk2aC0yNi42NDVWNy41JiMxMDsmIzk7JiM5O2MwLTQuMTQyLTMuMzU3LTcuNS03LjUtNy41cy03LjUsMy4zNTgtNy41LDcuNXY4Mi4yOTZoLTI2LjY0NlY3LjVjMC00LjE0Mi0zLjM1Ny03LjUtNy41LTcuNXMtNy41LDMuMzU4LTcuNSw3LjV2ODIuMjk2aC0yNi42NDUmIzEwOyYjOTsmIzk7VjcuNWMwLTQuMTQyLTMuMzU3LTcuNS03LjUtNy41cy03LjUsMy4zNTgtNy41LDcuNXY4Mi4yOTZoLTUuMzkyYy0xOS45OSwwLTM2LjI1MywxNi4yNjMtMzYuMjUzLDM2LjI1M3Y1LjM5Mkg3LjUmIzEwOyYjOTsmIzk7Yy00LjE0MywwLTcuNSwzLjM1OC03LjUsNy41czMuMzU3LDcuNSw3LjUsNy41aDgyLjI5N3YyNi42NDVINy41Yy00LjE0MywwLTcuNSwzLjM1OC03LjUsNy41czMuMzU3LDcuNSw3LjUsNy41aDgyLjI5N3YyNi42NDVINy41JiMxMDsmIzk7JiM5O2MtNC4xNDMsMC03LjUsMy4zNTgtNy41LDcuNXMzLjM1Nyw3LjUsNy41LDcuNWg4Mi4yOTd2MjYuNjQ1SDcuNWMtNC4xNDMsMC03LjUsMy4zNTgtNy41LDcuNXMzLjM1Nyw3LjUsNy41LDcuNWg4Mi4yOTd2MjYuNjQ1SDcuNSYjMTA7JiM5OyYjOTtjLTQuMTQzLDAtNy41LDMuMzU4LTcuNSw3LjVzMy4zNTcsNy41LDcuNSw3LjVoODIuMjk3djUuMzkyYzAsMTkuOTksMTYuMjYzLDM2LjI1MywzNi4yNTMsMzYuMjUzaDUuMzkydjU4LjE5NyYjMTA7JiM5OyYjOTtjMCw0LjE0MiwzLjM1Nyw3LjUsNy41LDcuNXM3LjUtMy4zNTgsNy41LTcuNXYtNTguMTk3aDI2LjY0NXY4Mi4yOTZjMCw0LjE0MiwzLjM1Nyw3LjUsNy41LDcuNXM3LjUtMy4zNTgsNy41LTcuNXYtODIuMjk2aDI2LjY0NiYjMTA7JiM5OyYjOTt2ODIuMjk2YzAsNC4xNDIsMy4zNTcsNy41LDcuNSw3LjVzNy41LTMuMzU4LDcuNS03LjV2LTgyLjI5NmgyNi42NDV2ODIuMjk2YzAsNC4xNDIsMy4zNTcsNy41LDcuNSw3LjVzNy41LTMuMzU4LDcuNS03LjV2LTgyLjI5NiYjMTA7JiM5OyYjOTtoMjYuNjQ1djgyLjI5NmMwLDQuMTQyLDMuMzU3LDcuNSw3LjUsNy41czcuNS0zLjM1OCw3LjUtNy41di04Mi4yOTZoNS4zOTJjMTkuOTksMCwzNi4yNTQtMTYuMjYzLDM2LjI1NC0zNi4yNTN2LTUuMzkyaDgyLjI5NiYjMTA7JiM5OyYjOTtjNC4xNDMsMCw3LjUtMy4zNTgsNy41LTcuNXMtMy4zNTctNy41LTcuNS03LjVoLTgyLjI5NnYtMjYuNjQ1aDgyLjI5NmM0LjE0MywwLDcuNS0zLjM1OCw3LjUtNy41cy0zLjM1Ny03LjUtNy41LTcuNWgtODIuMjk2JiMxMDsmIzk7JiM5O3YtMjYuNjQ1aDgyLjI5NmM0LjE0MywwLDcuNS0zLjM1OCw3LjUtNy41cy0zLjM1Ny03LjUtNy41LTcuNWgtODIuMjk2di0yNi42NDVINDM2Ljk2MnogTTMzOS42NjYsMzE4LjQxMiYjMTA7JiM5OyYjOTtjMCwxMS43MTktOS41MzQsMjEuMjUzLTIxLjI1NCwyMS4yNTNIMTI2LjA1Yy0xMS43MTksMC0yMS4yNTMtOS41MzQtMjEuMjUzLTIxLjI1M1YxMjYuMDVjMC0xMS43MTksOS41MzQtMjEuMjUzLDIxLjI1My0yMS4yNTMmIzEwOyYjOTsmIzk7aDE5Mi4zNjJjMTEuNzIsMCwyMS4yNTQsOS41MzQsMjEuMjU0LDIxLjI1M1YzMTguNDEyeiIvPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PGc+JiN4YTs8L2c+JiN4YTs8Zz4mI3hhOzwvZz4mI3hhOzxnPiYjeGE7PC9nPiYjeGE7PC9zdmc+" preserveAspectRatio="none" pointer-events="none"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
<!-- DOCTOC SKIP -->
# Batch Submitter
The batch submitter, also referred to as the batcher, is the entity submitting the L2 sequencer data to L1,
to make it available for verifiers.
[derivation spec]: derivation.md
The format of the data transactions is defined in the [derivation spec]:
the data is constructed from L2 blocks in the reverse order as it is derived from data into L2 blocks.
The timing, operation and transaction signing is implementation-specific: any data can be submitted at any time,
but only the data that matches the [derivation spec] rules will be valid from the verifier perspective.
The most minimal batcher implementation can be defined as a loop of the following operations:
1. See if the `unsafe` L2 block number is past the `safe` block number: `unsafe` data needs to be submitted.
2. Iterate over all unsafe L2 blocks, skip any that were previously submitted.
3. Open a channel, buffer all the L2 block data to be submitted,
while applying the encoding and compression as defined in the [derivation spec].
4. Pull frames from the channel to fill data transactions with, until the channel is empty.
5. Submit the data transactions to L1
The L2 view of safe/unsafe does not instantly update after data is submitted, nor when it gets confirmed on L1,
so special care may have to be taken to not duplicate data submissions.
# Bond Manager Interface
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [The Bond Problem](#the-bond-problem)
- [Simple Bond](#simple-bond)
- [Variable Bond](#variable-bond)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
In the context of permissionless output proposals, bonds are a value that must
be attached to an output proposal. In this case, the bond will be paid in ether.
By requiring a bond to be posted with an output proposal, spam and invalid outputs
are disincentivized. Explicitly, if invalid outputs are proposed, challenge agents
can delete the invalid output via a [dispute-game](./dispute-game-interface.md) and seize the
proposer's bond. So, posting invalid outputs is directly disincentivized in this way
since the proposer would lose their bond if the challenge agents seize it.
Concretely, outputs will be permissionlessly proposed to the `L2OutputOracle` contract.
When submitting an output proposal, the ether value is sent as the bond. This bond is
then held by a bond manager contract. The bond manager contract is responsible for
both the [dispute-games](./dispute-game-interface.md) and the `L2OutputOracle` (further detailed
in [proposals](./proposals.md)).
The bond manager will need to handle bond logic for a variety of different
[dispute-games](./dispute-game-interface.md). In the simplest "attestation" dispute game,
bonds will not be required since the attestors are a permissioned set of trusted entities.
But in more complex games, such as the fault dispute game, challengers and defenders
perform a series of alternating onchain transactions requiring bonds at each step.
## The Bond Problem
At its core, the bond manager is straightforward - it escrows or holds ether and can be claimed
at maturity or seized if forfeited. But the uncertainty of introducing bonds lies in the
bond _sizing_, i.e. how much should a bond be? Sizing bonds correctly is a function of
the bond invariant: the bond must be greater than or equal to the cost of the next step.
If bonds are priced too low, then the bond invariant is violated and there isn't an economic
incentive to execute the next step. If bonds are priced too high, then the actors posting
bonds can be priced out.
Below, we outline two different approaches to sizing bonds and the tradeoffs of each.
### Simple Bond
The _Simple Bond_ is a very conservative approach to bond management, establishing a **fixed** bond
size. The idea behind simple bond pricing is to establish the worst case gas cost for
the next step in the dispute game.
With this approach, the size of the bond is computed up-front when a dispute game is created.
For example, in an attestation dispute game, this bond size can be computed as such:
```md
bond_size = (signer_threshold * (challenge_gas + security overhead)) + resolution_gas(signer_threshold)
```
Notice that since the bond size is linearly proportional to the number of signers, the economic
security a given bond size provides decreases as the number of signers increases. Also note, the
`resolution_gas` function is split out from the `challenge_gas` cost because only the _last_ challenger
will pay for the gas cost to resolve the game in the attestation dispute game.
Working backwards, if we assume the number of signers to be `5`, a negligible resolution gas cost, and
a `100,000` gas cost to progress the game, then the bond size should cover `500,000` gas. Meaning, a bond
of `1 ether` would cover the cost of progressing the game for `5` signers as long as the gas price
(base fee) does not exceed `2,000 gwei` for the entire finalization window. It would be prohibitively
expensive to keep the settlement layer base fee this high.
### Variable Bond
Better bond heuristics can be used to establish a bond price that accounts for
the time-weighted gas price. One instance of this called _Variable Bonds_ use a
separate oracle contract, `GasPriceFluctuationTracker`, that tracks gas fluctuations
within a pre-determined bounds. This replaces the ideal solution of tracking
challenge costs over all L1 blocks, but provides a reasonable bounds. The initial
actors posting this bond are responsible for funding this contract.
# Standard Bridges
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Token Depositing](#token-depositing)
- [Upgradability](#upgradability)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
The standard bridges are responsible for allowing cross domain
ETH and ERC20 token transfers. They are built on top of the cross domain
messenger contracts and give a standard interface for depositing tokens.
The bridge works for both L1 native tokens and L2 native tokens. The legacy API
is preserved to ensure that existing applications will not experience any
problems with the Bedrock `StandardBridge` contracts.
The `L2StandardBridge` is a predeploy contract located at
`0x4200000000000000000000000000000000000010`.
```solidity
interface StandardBridge {
event ERC20BridgeFinalized(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData);
event ERC20BridgeInitiated(address indexed localToken, address indexed remoteToken, address indexed from, address to, uint256 amount, bytes extraData);
event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
function bridgeERC20(address _localToken, address _remoteToken, uint256 _amount, uint32 _minGasLimit, bytes memory _extraData) external;
function bridgeERC20To(address _localToken, address _remoteToken, address _to, uint256 _amount, uint32 _minGasLimit, bytes memory _extraData) external;
function bridgeETH(uint32 _minGasLimit, bytes memory _extraData) payable external;
function bridgeETHTo(address _to, uint32 _minGasLimit, bytes memory _extraData) payable external;
function deposits(address, address) view external returns (uint256);
function finalizeBridgeERC20(address _localToken, address _remoteToken, address _from, address _to, uint256 _amount, bytes memory _extraData) external;
function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) payable external;
function messenger() view external returns (address);
function OTHER_BRIDGE() view external returns (address);
}
```
## Token Depositing
The `bridgeERC20` function is used to send a token from one domain to another
domain. An `OptimismMintableERC20` token contract must exist on the remote
domain to be able to deposit tokens to that domain. One of these tokens can be
deployed using the `OptimismMintableERC20Factory` contract.
## Upgradability
Both the L1 and L2 standard bridges should be behind upgradable proxies.
0x608060405234801561001057600080fd5b50610fb5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063de26c4a111610066578063de26c4a1146101da578063f45e65d8146101ed578063f8206140146101f5578063fe173b97146101cc57600080fd5b806354fd4d501461016657806368d5dca6146101af5780636ef25c3a146101cc578063c5985918146101d257600080fd5b8063313ce567116100d3578063313ce5671461012757806349948e0e1461012e5780634ef6e22414610141578063519b4bd31461015e57600080fd5b80630c18c162146100fa57806322b90ab3146101155780632e0f26251461011f575b600080fd5b6101026101fd565b6040519081526020015b60405180910390f35b61011d61031e565b005b610102600681565b6006610102565b61010261013c366004610b73565b610541565b60005461014e9060ff1681565b604051901515815260200161010c565b610102610565565b6101a26040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161010c9190610c42565b6101b76105c6565b60405163ffffffff909116815260200161010c565b48610102565b6101b761064b565b6101026101e8366004610b73565b6106ac565b610102610760565b610102610853565b6000805460ff1615610296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f47617350726963654f7261636c653a206f76657268656164282920697320646560448201527f707265636174656400000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610cb5565b905090565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663e591b2826040518163ffffffff1660e01b8152600401602060405180830381865afa15801561037d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a19190610cce565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f47617350726963654f7261636c653a206f6e6c7920746865206465706f73697460448201527f6f72206163636f756e742063616e2073657420697345636f746f6e6520666c6160648201527f6700000000000000000000000000000000000000000000000000000000000000608482015260a40161028d565b60005460ff1615610514576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a2045636f746f6e6520616c72656164792060448201527f6163746976650000000000000000000000000000000000000000000000000000606482015260840161028d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6000805460ff161561055c57610556826108b4565b92915050565b61055682610958565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16635cf249696040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff166368d5dca66040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103199190610d04565b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663c59859186040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b6000806106b883610ab4565b60005490915060ff16156106cc5792915050565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f9190610cb5565b6107599082610d59565b9392505050565b6000805460ff16156107f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f47617350726963654f7261636c653a207363616c61722829206973206465707260448201527f6563617465640000000000000000000000000000000000000000000000000000606482015260840161028d565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff1663f82061406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f5573d6000803e3d6000fd5b6000806108c083610ab4565b905060006108cc610565565b6108d461064b565b6108df906010610d71565b63ffffffff166108ef9190610d9d565b905060006108fb610853565b6109036105c6565b63ffffffff166109139190610d9d565b905060006109218284610d59565b61092b9085610d9d565b90506109396006600a610efa565b610944906010610d9d565b61094e9082610f06565b9695505050505050565b60008061096483610ab4565b9050600073420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16639e8c49666040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109eb9190610cb5565b6109f3610565565b73420000000000000000000000000000000000001573ffffffffffffffffffffffffffffffffffffffff16638b239f736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610cb5565b610a809085610d59565b610a8a9190610d9d565b610a949190610d9d565b9050610aa26006600a610efa565b610aac9082610f06565b949350505050565b80516000908190815b81811015610b3757848181518110610ad757610ad7610f41565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016600003610b1757610b10600484610d59565b9250610b25565b610b22601084610d59565b92505b80610b2f81610f70565b915050610abd565b50610aac82610440610d59565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610b8557600080fd5b813567ffffffffffffffff80821115610b9d57600080fd5b818401915084601f830112610bb157600080fd5b813581811115610bc357610bc3610b44565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b44565b81604052828152876020848701011115610c2257600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b81811115610c81576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cc757600080fd5b5051919050565b600060208284031215610ce057600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461075957600080fd5b600060208284031215610d1657600080fd5b815163ffffffff8116811461075957600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610d6c57610d6c610d2a565b500190565b600063ffffffff80831681851681830481118215151615610d9457610d94610d2a565b02949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610dd557610dd5610d2a565b500290565b600181815b80851115610e3357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610e1957610e19610d2a565b80851615610e2657918102915b93841c9390800290610ddf565b509250929050565b600082610e4a57506001610556565b81610e5757506000610556565b8160018114610e6d5760028114610e7757610e93565b6001915050610556565b60ff841115610e8857610e88610d2a565b50506001821b610556565b5060208310610133831016604e8410600b8410161715610eb6575081810a610556565b610ec08383610dda565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ef257610ef2610d2a565b029392505050565b60006107598383610e3b565b600082610f3c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610fa157610fa1610d2a565b506001019056fea164736f6c634300080f000a
0x608060405234801561001057600080fd5b5061053e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638381f58a11610097578063c598591811610066578063c598591814610229578063e591b28214610249578063e81b2c6d14610289578063f82061401461029257600080fd5b80638381f58a146101e35780638b239f73146101f75780639e8c496614610200578063b80777ea1461020957600080fd5b806354fd4d50116100d357806354fd4d50146101335780635cf249691461017c57806364ca23ef1461018557806368d5dca6146101b257600080fd5b8063015d8eb9146100fa57806309bd5a601461010f578063440a5e201461012b575b600080fd5b61010d61010836600461044c565b61029b565b005b61011860025481565b6040519081526020015b60405180910390f35b61010d6103da565b61016f6040518060400160405280600581526020017f312e322e3000000000000000000000000000000000000000000000000000000081525081565b60405161012291906104be565b61011860015481565b6003546101999067ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610122565b6003546101ce9068010000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610122565b6000546101999067ffffffffffffffff1681565b61011860055481565b61011860065481565b6000546101999068010000000000000000900467ffffffffffffffff1681565b6003546101ce906c01000000000000000000000000900463ffffffff1681565b61026473deaddeaddeaddeaddeaddeaddeaddeaddead000181565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610122565b61011860045481565b61011860075481565b3373deaddeaddeaddeaddeaddeaddeaddeaddead000114610342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c31426c6f636b3a206f6e6c7920746865206465706f7369746f72206163636f60448201527f756e742063616e20736574204c3120626c6f636b2076616c7565730000000000606482015260840160405180910390fd5b6000805467ffffffffffffffff98891668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116998916999099179890981790975560019490945560029290925560038054919094167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009190911617909255600491909155600555600655565b3373deaddeaddeaddeaddeaddeaddeaddeaddead00011461040357633cc50b456000526004601cfd5b60043560801c60035560143560801c600055602435600155604435600755606435600255608435600455565b803567ffffffffffffffff8116811461044757600080fd5b919050565b600080600080600080600080610100898b03121561046957600080fd5b6104728961042f565b975061048060208a0161042f565b9650604089013595506060890135945061049c60808a0161042f565b979a969950949793969560a0850135955060c08501359460e001359350915050565b600060208083528351808285015260005b818110156104eb578581018301518582016040015282016104cf565b818111156104fd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea164736f6c634300080f000a
# Cannon Fault Proof Virtual Machine Specification
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [State](#state)
- [State Hash](#state-hash)
- [Memory](#memory)
- [Heap](#heap)
- [Delay Slots](#delay-slots)
- [Syscalls](#syscalls)
- [I/O](#io)
- [Standard Streams](#standard-streams)
- [Hint Communication](#hint-communication)
- [Pre-image Communication](#pre-image-communication)
- [Pre-image I/O Alignment](#pre-image-io-alignment)
- [Exceptions](#exceptions)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
This is a description of the Cannon Fault Proof Virtual Machine (FPVM). The Cannon FPVM emulates
a minimal Linux-based system running on big-endian 32-bit MIPS32 architecture.
A lot of its behaviors are copied from Linux/MIPS with a few tweaks made for fault proofs.
For the rest of this doc, we refer to the Cannon FPVM as simply the FPVM.
Operationally, the FPVM is a state transition function. This state transition is referred to as a *Step*,
that executes a single instruction. We say the VM is a function $f$, given an input state $S_{pre}$, steps on a
single instruction encoded in the state to produce a new state $S_{post}$.
$$f(S_{pre}) \rightarrow S_{post}$$
Thus, the trace of a program executed by the FPVM is an ordered set of VM states.
## State
The virtual machine state highlights the effects of running a Fault Proof Program on the VM.
It consists of the following fields:
1. `memRoot` - A `bytes32` value representing the merkle root of VM memory.
2. `preimageKey` - `bytes32` value of the last requested pre-image key.
3. `preimageOffset` - The 32-bit value of the last requested pre-image offset.
4. `pc` - 32-bit program counter.
5. `nextPC` - 32-bit next program counter. Note that this value may not always be $pc+4$
when executing a branch/jump delay slot.
6. `lo` - 32-bit MIPS LO special register.
7. `hi` - 32-bit MIPS HI special register.
8. `heap` - 32-bit base address of the most recent memory allocation via mmap.
9. `exitCode` - 8-bit exit code.
10. `exited` - 1-bit indicator that the VM has exited.
11. `registers` - General-purpose MIPS32 registers. Each register is a 32-bit value.
The state is represented by packing the above fields, in order, into a 226-byte buffer.
### State Hash
The state hash is computed by hashing the 226-byte state buffer with the Keccak256 hash function
and then setting the high-order byte to the respective VM status.
The VM status can be derived from the state's `exited` and `exitCode` fields.
```rs
enum VmStatus {
Valid = 0,
Invalid = 1,
Panic = 2,
Unfinished = 3,
}
fn vm_status(exit_code: u8, exited: bool) -> u8 {
if exited {
match exit_code {
0 => VmStatus::Valid,
1 => VmStatus::Invalid,
_ => VmStatus::Panic,
}
} else {
VmStatus::Unfinished
}
}
```
## Memory
Memory is represented as a binary merkle tree.
The tree has a fixed-depth of 27 levels, with leaf values of 32 bytes each.
This spans the full 32-bit address space, where each leaf contains the memory at that part of the tree.
The state `memRoot` represents the merkle root of the tree, reflecting the effects of memory writes.
As a result of this memory representation, all memory operations are 4-byte aligned.
Memory access doesn't require any privileges. An instruction step can access any memory
location as the entire address space is unprotected.
### Heap
FPVM state contains a `heap` that tracks the base address of the most recent memory allocation.
Heap pages are bump allocated at the page boundary, per `mmap` syscall.
mmap-ing is purely to satisfy program runtimes that need the memory-pointer
result of the syscall to locate free memory. The page size is 4096.
The FPVM has a fixed program break at `0x40000000`. However, the FPVM is permitted to extend the
heap beyond this limit via mmap syscalls.
For simplicity, there are no memory protections against "heap overruns" against other memory segments.
Such VM steps are still considered valid state transitions.
Specification of memory mappings is outside the scope of this document as it is irrelevant to
the VM state. FPVM implementers may refer to the Linux/MIPS kernel for inspiration.
## Delay Slots
The post-state of a step updates the `nextPC`, indicating the instruction following the `pc`.
However, in the case of where a branch instruction is being stepped, the `nextPC` post-state is
set to the branch target. And the `pc` post-state set to the branch delay slot as usual.
A VM state transition is invalid whenever the current instruction is a delay slot that is filled
with jump or branch type instruction.
That is, where $nextPC \neq pc + 4$ while stepping on a jump/branch instruction.
Otherwise, there would be two consecutive delay slots. While this is considered "undefined"
behavior in typical MIPS implementations, FPVM must raise an exception when stepping on such states.
## Syscalls
Syscalls work similar to [Linux/MIPS](https://www.linux-mips.org/wiki/Syscall), including the
syscall calling conventions and general syscall handling behavior.
However, the FPVM supports a subset of Linux/MIPS syscalls with slightly different behaviors.
The following table list summarizes the supported syscalls and their behaviors.
| $v0 | system call | $a0 | $a1 | $a2 | Effect |
| -- | -- | -- | -- | -- | -- |
| 4090 | mmap | uint32 addr | uint32 len | | Allocates a page from the heap. See [heap](#heap) for details. |
| 4045 | brk | | | | Returns a fixed address for the program break at `0x40000000` |
| 4120 | clone | | | | Returns 1 |
| 4246 | exit_group | uint8 exit_code | | | Sets the Exited and ExitCode states to `true` and `$a0` respectively. |
| 4003 | read | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned reads. See [I/O](#io) for more details. |
| 4004 | write | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. |
| 4055 | fcntl | uint32 fd | int32 cmd | | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands |
For all of the above syscalls, an error is indicated by setting the return
register (`$v0`) to `0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly.
The VM must not modify any register other than `$v0` and `$a3` during syscall handling.
For unsupported syscalls, the VM must do nothing except to zero out the syscall return (`$v0`)
and errno (`$a3`) registers.
Note that the above syscalls have identical syscall numbers and ABIs as Linux/MIPS.
## I/O
The VM does not support Linux open(2). However, the VM can read from and write to a predefined set of file descriptors.
| Name | File descriptor | Description |
| ---- | --------------- | ----------- |
| stdin | 0 | read-only standard input stream. |
| stdout | 1 | write-only standard output stream. |
| stderr | 2 | write-only standard error stream. |
| hint response | 3 | read-only. Used to read the status of [pre-image hinting](./fault-proof.md#hinting). |
| hint request | 4 | write-only. Used to provide [pre-image hints](./fault-proof.md#hinting) |
| pre-image response | 5 | read-only. Used to [read pre-images](./fault-proof.md#pre-image-communication). |
| pre-image request | 6 | write-only. Used to [request pre-images](./fault-proof.md#pre-image-communication). |
Syscalls referencing unknown file descriptors fail with an `EBADF` errno as done on Linux.
Writing to and reading from standard output, input and error streams have no effect on the FPVM state.
FPVM implementations may use them for debugging purposes as long as I/O is stateless.
All I/O operations are restricted to a maximum of 4 bytes per operation.
Any read or write syscall request exceeding this limit will be truncated to 4 bytes.
Consequently, the return value of read/write syscalls is at most 4, indicating the actual number of bytes read/written.
### Standard Streams
Writing to stderr/stdout standard stream always succeeds with the write count input returned,
effectively continuing execution without writing work.
Reading from stdin has no effect other than to return zero and errno set to 0, signalling that there is no input.
### Hint Communication
Hint requests and responses have no effect on the VM state other than setting the `$v0` return
register to the requested read/write count.
VM implementations may utilize hints to setup subsequent pre-image requests.
### Pre-image Communication
The `preimageKey` and `preimageOffset` state are updated via read/write syscalls to the pre-image
read and write file descriptors (see [I/O](#io)).
The `preimageKey` buffers the stream of bytes written to the pre-image write fd.
The `preimageKey` buffer is shifted to accommodate new bytes written to the end of it.
A write also resets the `preimageOffset` to 0, indicating the intent to read a new pre-image.
When handling pre-image reads, the `preimageKey` is used to lookup the pre-image data from an Oracle.
A max 4-byte chunk of the pre-image at the `preimageOffset` is read to the specified address.
Each read operation increases the `preimageOffset` by the number of bytes requested
(truncated to 4 bytes and subject to alignment constraints).
#### Pre-image I/O Alignment
As mentioned earlier in [memory](#memory), all memory operations are 4-byte aligned.
Since pre-image I/O occurs on memory, all pre-image I/O operations must strictly adhere to alignment boundaries.
This means the start and end of a read/write operation must fall within the same alignment boundary.
If an operation were to violate this, the input `count` of the read/write syscall must be
truncated such that the effective address of the last byte read/written matches the input effective address.
The VM must read/write the maximum amount of bytes possible without crossing the input address alignment boundary.
For example, the effect of a write request for a 3-byte aligned buffer must be exactly 3 bytes.
If the buffer is misaligned, then the VM may write less than 3 bytes depending on the size of the misalignment.
## Exceptions
The FPVM may raise an exception rather than output a post-state to signal an invalid state
transition. Nominally, the FPVM must raise an exception in at least the following cases:
- Invalid instruction (either via an invalid opcode or an instruction referencing registers
outside the general purpose registers).
- Pre-image read at an offset larger than the size of the pre-image.
- Delay slot contains branch/jump instruction types.
VM implementations may raise an exception in other cases that is specific to the implementation.
For example, an on-chain FPVM that relies on pre-supplied merkle proofs for memory access may
raise an exception if the supplied merkle proof does not match the pre-state `memRoot`.
# Deposits
<!-- All glossary references in this file. -->
[g-transaction-type]: glossary.md#transaction-type
[g-derivation]: glossary.md#L2-chain-derivation
[g-deposited]: glossary.md#deposited
[g-deposits]: glossary.md#deposits
[g-l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction
[g-user-deposited]: glossary.md#user-deposited-transaction
[g-eoa]: glossary.md#eoa
[g-exec-engine]: glossary.md#execution-engine
[Deposited transactions][g-deposited], also known as [deposits][g-deposits] are transactions which
are initiated on L1, and executed on L2. This document outlines a new [transaction
type][g-transaction-type] for deposits. It also describes how deposits are initiated on L1, along
with the authorization and validation conditions on L2.
**Vocabulary note**: *deposited transaction* refers specifically to an L2 transaction, while
*deposit* can refer to the transaction at various stages (for instance when it is deposited on L1).
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [The Deposited Transaction Type](#the-deposited-transaction-type)
- [Source hash computation](#source-hash-computation)
- [Kinds of Deposited Transactions](#kinds-of-deposited-transactions)
- [Validation and Authorization of Deposited Transactions](#validation-and-authorization-of-deposited-transactions)
- [Execution](#execution)
- [Nonce Handling](#nonce-handling)
- [Deposit Receipt](#deposit-receipt)
- [L1 Attributes Deposited Transaction](#l1-attributes-deposited-transaction)
- [L1 Attributes Deposited Transaction Calldata](#l1-attributes-deposited-transaction-calldata)
- [L1 Attributes - Bedrock, Canyon, Delta](#l1-attributes---bedrock-canyon-delta)
- [L1 Attributes - Ecotone](#l1-attributes---ecotone)
- [Special Accounts on L2](#special-accounts-on-l2)
- [L1 Attributes Depositor Account](#l1-attributes-depositor-account)
- [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract)
- [L1 Attributes Predeployed Contract: Reference Implementation](#l1-attributes-predeployed-contract-reference-implementation)
- [Ecotone L1Block upgrade](#ecotone-l1block-upgrade)
- [User-Deposited Transactions](#user-deposited-transactions)
- [Deposit Contract](#deposit-contract)
- [Address Aliasing](#address-aliasing)
- [Deposit Contract Implementation: Optimism Portal](#deposit-contract-implementation-optimism-portal)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## The Deposited Transaction Type
[deposited-tx-type]: #the-deposited-transaction-type
[Deposited transactions][g-deposited] have the following notable distinctions from existing
transaction types:
1. They are derived from Layer 1 blocks, and must be included as part of the protocol.
2. They do not include signature validation (see [User-Deposited Transactions][user-deposited]
for the rationale).
3. They buy their L2 gas on L1 and, as such, the L2 gas is not refundable.
We define a new [EIP-2718] compatible transaction type with the prefix `0x7E` to represent a deposit transaction.
A deposit has the following fields
(rlp encoded in the order they appear here):
[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
- `bytes32 sourceHash`: the source-hash, uniquely identifies the origin of the deposit.
- `address from`: The address of the sender account.
- `address to`: The address of the recipient account, or the null (zero-length) address if the
deposited transaction is a contract creation.
- `uint256 mint`: The ETH value to mint on L2.
- `uint256 value`: The ETH value to send to the recipient account.
- `uint64 gas`: The gas limit for the L2 transaction.
- `bool isSystemTx`: If true, the transaction does not interact with the L2 block gas pool.
- Note: boolean is disabled (enforced to be `false`) starting from the Regolith upgrade.
- `bytes data`: The calldata.
In contrast to [EIP-155] transactions, this transaction type:
- Does not include a `nonce`, since it is identified by the `sourceHash`.
API responses still include a `nonce` attribute:
- Before Regolith: the `nonce` is always `0`
- With Regolith: the `nonce` is set to the `depositNonce` attribute of the corresponding transaction receipt.
- Does not include signature information, and makes the `from` address explicit.
API responses contain zeroed signature `v`, `r`, `s` values for backwards compatibility.
- Includes new `sourceHash`, `from`, `mint`, and `isSystemTx` attributes.
API responses contain these as additional fields.
[EIP-155]:https://eips.ethereum.org/EIPS/eip-155
We select `0x7E` because transaction type identifiers are currently allowed to go up to `0x7F`.
Picking a high identifier minimizes the risk that the identifier will be used be claimed by another
transaction type on the L1 chain in the future. We don't pick `0x7F` itself in case it becomes used
for a variable-length encoding scheme.
### Source hash computation
The `sourceHash` of a deposit transaction is computed based on the origin:
- User-deposited:
`keccak256(bytes32(uint256(0)), keccak256(l1BlockHash, bytes32(uint256(l1LogIndex))))`.
Where the `l1BlockHash`, and `l1LogIndex` all refer to the inclusion of the deposit log event on L1.
`l1LogIndex` is the index of the deposit event log in the combined list of log events of the block.
- L1 attributes deposited:
`keccak256(bytes32(uint256(1)), keccak256(l1BlockHash, bytes32(uint256(seqNumber))))`.
Where `l1BlockHash` refers to the L1 block hash of which the info attributes are deposited.
And `seqNumber = l2BlockNum - l2EpochStartBlockNum`,
where `l2BlockNum` is the L2 block number of the inclusion of the deposit tx in L2,
and `l2EpochStartBlockNum` is the L2 block number of the first L2 block in the epoch.
- Upgrade-deposited: `keccak256(bytes32(uint256(2)), keccak256(intent))`.
Where `intent` is a UTF-8 byte string, identifying the upgrade intent.
Without a `sourceHash` in a deposit, two different deposited transactions could have the same exact hash.
The outer `keccak256` hashes the actual uniquely identifying information with a domain,
to avoid collisions between different types of sources.
We do not use the sender's nonce to ensure uniqueness because this would require an extra L2 EVM state read from the
[execution engine][g-exec-engine] during block-derivation.
### Kinds of Deposited Transactions
Although we define only one new transaction type, we can distinguish between two kinds of deposited
transactions, based on their positioning in the L2 block:
1. The first transaction MUST be a [L1 attributes deposited transaction][l1-attr-deposit], followed by
2. an array of zero-or-more [user-deposited transactions][user-deposited]
submitted to the deposit feed contract on L1 (called `OptimismPortal`).
User-deposited transactions are only present in the first block of a L2 epoch.
We only define a single new transaction type in order to minimize modifications to L1 client
software, and complexity in general.
### Validation and Authorization of Deposited Transactions
[authorization]: #validation-and-authorization-of-deposited-transaction
As noted above, the deposited transaction type does not include a signature for validation. Rather,
authorization is handled by the [L2 chain derivation][g-derivation] process, which when correctly
applied will only derive transactions with a `from` address attested to by the logs of the [L1
deposit contract][deposit-contract].
### Execution
In order to execute a deposited transaction:
First, the balance of the `from` account MUST be increased by the amount of `mint`.
This is unconditional, and does not revert on deposit failure.
Then, the execution environment for a deposited transaction is initialized based on the
transaction's attributes, in exactly the same manner as it would be for an EIP-155 transaction.
The deposit transaction is processed exactly like a type-3 (EIP-1559) transaction, with the exception of:
- No fee fields are verified: the deposit does not have any, as it pays for gas on L1.
- No `nonce` field is verified: the deposit does not have any, it's uniquely identified by its `sourceHash`.
- No access-list is processed: the deposit has no access-list, and it is thus processed as if the access-list is empty.
- No check if `from` is an Externally Owner Account (EOA): the deposit is ensured not to be an EOA through L1 address
masking, this may change in future L1 contract-deployments to e.g. enable an account-abstraction like mechanism.
- Before the Regolith upgrade:
- The execution output states a non-standard gas usage:
- If `isSystemTx` is false: execution output states it uses `gasLimit` gas.
- If `isSystemTx` is true: execution output states it uses `0` gas.
- No gas is refunded as ETH. (either by not refunding or utilizing the fact the gas-price of the deposit is `0`)
- No transaction priority fee is charged. No payment is made to the block fee-recipient.
- No L1-cost fee is charged, as deposits are derived from L1 and do not have to be submitted as data back to it.
- No base fee is charged. The total base fee accounting does not change.
Note that this includes contract-deployment behavior like with regular transactions, and gas
metering is the same (with the exception of fee related changes above), including metering of
intrinsic gas.
Any non-EVM state-transition error emitted by the EVM execution is processed in a special way:
- It is transformed into an EVM-error:
i.e. the deposit will always be included, but its receipt will indicate a failure
if it runs into a non-EVM state-transition error, e.g. failure to transfer the specified
`value` amount of ETH due to insufficient account-balance.
- The world state is rolled back to the start of the EVM processing, after the minting part of the deposit.
- The `nonce` of `from` in the world state is incremented by 1, making the error equivalent to a native EVM failure.
Note that a previous `nonce` increment may have happened during EVM processing, but this would be rolled back first.
Finally, after the above processing, the execution post-processing runs the same:
i.e. the gas pool and receipt are processed identical to a regular transaction.
Starting with the Regolith upgrade however, the receipt of deposit transactions is extended with an additional
`depositNonce` value, storing the `nonce` value of the `from` sender as registered *before* the EVM processing.
Note that the gas used as stated by the execution output is subtracted from the gas pool,
but this execution output value has special edge cases before the Regolith upgrade.
Note for application developers: because `CALLER` and `ORIGIN` are set to `from`, the
semantics of using the `tx.origin == msg.sender` check will not work to determine whether
or not a caller is an EOA during a deposit transaction. Instead, the check could only be useful for
identifying the first call in the L2 deposit transaction. However this check does still satisfy
the common case in which developers are using this check to ensure that the `CALLER` is unable to
execute code before and after the call.
#### Nonce Handling
Despite the lack of signature validation, we still increment the nonce of the `from` account when a
deposit transaction is executed. In the context of a deposit-only roll up, this is not necessary
for transaction ordering or replay prevention, however it maintains consistency with the use of
nonces during [contract creation][create-nonce]. It may also simplify integration with downstream
tooling (such as wallets and block explorers).
[create-nonce]: https://github.com/ethereum/execution-specs/blob/617903a8f8d7b50cf71bf1aa733c37897c8d75c1/src/ethereum/frontier/utils/address.py#L40
## Deposit Receipt
Transaction receipts use standard typing as per [EIP-2718].
The Deposit transaction receipt type is equal to a regular receipt,
but extended with an optional `depositNonce` field.
The RLP-encoded consensus-enforced fields are:
- `postStateOrStatus` (standard): this contains the transaction status, see [EIP-658].
- `cumulativeGasUsed` (standard): gas used in the block thus far, including this transaction.
- The actual gas used is derived from the difference in `CumulativeGasUsed` with the previous transaction.
- Starting with Regolith, this accounts for the actual gas usage by the deposit, like regular transactions.
- `bloom` (standard): bloom filter of the transaction logs.
- `logs` (standard): log events emitted by the EVM processing.
- `depositNonce` (unique extension): Optional field. The deposit transaction persists the nonce used during execution.
- `depositNonceVersion` (unique extension): Optional field. The value must be 1 if the field is present
- Before Canyon, these `depositNonce` & `depositNonceVersion` fields must always be omitted.
- With Canyon, these `depositNonce` & `depositNonceVersion` fields must always be included.
Starting with Regolith, the receipt API responses utilize the receipt changes for more accurate response data:
- The `depositNonce` is included in the receipt JSON data in API responses
- For contract-deployments (when `to == null`), the `depositNonce` helps derive the correct `contractAddress` meta-data,
instead of assuming the nonce was zero.
- The `cumulativeGasUsed` accounts for the actual gas usage, as metered in the EVM processing.
[EIP-658]: https://eips.ethereum.org/EIPS/eip-658
## L1 Attributes Deposited Transaction
[l1-attr-deposit]: #l1-attributes-deposited-transaction
An [L1 attributes deposited transaction][g-l1-attr-deposit] is a deposit transaction sent to the [L1
attributes predeployed contract][predeploy].
This transaction MUST have the following values:
1. `from` is `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001` (the address of the
[L1 Attributes depositor account][depositor-account])
2. `to` is `0x4200000000000000000000000000000000000015` (the address of the [L1 attributes predeployed
contract][predeploy]).
3. `mint` is `0`
4. `value` is `0`
5. `gasLimit` is set to 150,000,000 prior to the Regolith upgrade, and 1,000,000 after.
6. `isSystemTx` is set to `true` prior to the Regolith upgrade, and `false` after.
7. `data` is an encoded call to the [L1 attributes predeployed contract][predeploy] that
depends on the upgrades that are active (see below).
This system-initiated transaction for L1 attributes is not charged any ETH for its allocated
`gasLimit`, as it is considered part of state-transition processing.
### L1 Attributes Deposited Transaction Calldata
#### L1 Attributes - Bedrock, Canyon, Delta
The `data` field of the L1 attributes deposited transaction is an [ABI][ABI] encoded call to the
`setL1BlockValues()` function with correct values associated with the corresponding L1 block
(cf. [reference implementation][l1-attr-ref-implem]).
#### L1 Attributes - Ecotone
On the Ecotone activation block, and if Ecotone is not activated at Genesis,
the L1 Attributes Transaction includes a call to `setL1BlockValues()`
because the L1 Attributes transaction precedes the [Ecotone Upgrade Transactions][ecotone-upgrade-txs],
meaning that `setL1BlockValuesEcotone` is not guaranteed to exist yet.
Every subsequent L1 Attributes transaction should include a call to the `setL1BlockValuesEcotone()` function.
The input args are no longer ABI encoded function parameters,
but are instead packed into 5 32-byte aligned segments (starting after the function selector).
Each unsigned integer argument is encoded as big-endian using a number of bytes corresponding to the underlying type.
The overall calldata layout is as follows:
[ecotone-upgrade-txs]: derivation.md#network-upgrade-automation-transactions
| Input arg | Type | Calldata bytes | Segment |
| ----------------- | ----------- | -------------- | --------|
| {0x440a5e20} | | 0-3 | n/a |
| baseFeeScalar | uint32 | 4-7 | 1 |
| blobBaseFeeScalar | uint32 | 8-11 | |
| sequenceNumber | uint64 | 12-19 | |
| l1BlockTimestamp | uint64 | 20-27 | |
| l1BlockNumber | uint64 | 28-35 | |
| basefee | uint256 | 36-67 | 2 |
| blobBaseFee | uint256 | 68-99 | 3 |
| l1BlockHash | bytes32 | 100-131 | 4 |
| batcherHash | bytes32 | 132-163 | 5 |
Total calldata length MUST be exactly 164 bytes, implying the sixth and final segment is only
partially filled. This helps to slow database growth as every L2 block includes a L1 Attributes
deposit transaction.
In the first L2 block after the Ecotone activation block, the Ecotone L1 attributes are first used.
The pre-Ecotone values are migrated over 1:1.
Blocks after the Ecotone activation block contain all pre-Ecotone values 1:1,
and also set the following new attributes:
- The `baseFeeScalar` is set to the pre-Ecotone `scalar` value.
- The `blobBaseFeeScalar` is set to `0`.
- The pre-Ecotone `overhead` attribute is dropped.
- The `blobBaseFee` is set to the L1 blob base fee of the L1 origin block.
Or `1` if the L1 block does not support blobs.
The `1` value is derived from the EIP-4844 `MIN_BLOB_GASPRICE`.
## Special Accounts on L2
The L1 attributes deposit transaction involves two special purpose accounts:
1. The L1 attributes depositor account
2. The L1 attributes predeployed contract
### L1 Attributes Depositor Account
[depositor-account]: #l1-attributes-depositor-account
The depositor account is an [EOA][g-eoa] with no known private key. It has the address
`0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001`. Its value is returned by the `CALLER` and `ORIGIN`
opcodes during execution of the L1 attributes deposited transaction.
### L1 Attributes Predeployed Contract
[predeploy]: #l1-attributes-predeployed-contract
A predeployed contract on L2 at address `0x4200000000000000000000000000000000000015`, which holds
certain block variables from the corresponding L1 block in storage, so that they may be accessed
during the execution of the subsequent deposited transactions.
The predeploy stores the following values:
- L1 block attributes:
- `number` (`uint64`)
- `timestamp` (`uint64`)
- `basefee` (`uint256`)
- `hash` (`bytes32`)
- `sequenceNumber` (`uint64`): This equals the L2 block number relative to the start of the epoch,
i.e. the L2 block distance to the L2 block height that the L1 attributes last changed,
and reset to 0 at the start of a new epoch.
- System configurables tied to the L1 block, see [System configuration specification](./system_config.md):
- `batcherHash` (`bytes32`): A versioned commitment to the batch-submitter(s) currently operating.
- `overhead` (`uint256`): The L1 fee overhead to apply to L1 cost computation of transactions in this L2 block.
The `overhead` value is dropped as it is no longer used in the
[Ecotone L1 fee formula](./exec-engine.md#ecotone-l1-cost-fee-changes-eip-4844-da).
- `scalar` (`uint256`): The L1 fee scalar to apply to L1 cost computation of transactions in this L2 block.
- With the Ecotone upgrade, the predeploy additionally stores:
- `blobBaseFee` (`uint256`)
- `baseFeeScalar` (`uint32`): system configurable to scale the `basefee` in the Ecotone l1 cost computation
- `blobBasefeeScalar` (`uint32`): system configurable to scale the `blobBaseFee` in the Ecotone l1 cost computation
The `overhead` and `scalar` values can continue to be accessed after the Ecotone activation block,
but no longer have any effect on system operation.
The contract implements an authorization scheme, such that it only accepts state-changing calls from
the [depositor account][depositor-account].
The contract has the following solidity interface, and can be interacted with according to the
[contract ABI specification][ABI].
[ABI]: https://docs.soliditylang.org/en/v0.8.10/abi-spec.html
#### L1 Attributes Predeployed Contract: Reference Implementation
[l1-attr-ref-implem]: #l1-attributes-predeployed-contract-reference-implementation
A reference implementation of the L1 Attributes predeploy contract can be found in [L1Block.sol].
[L1Block.sol]: ../packages/contracts-bedrock/src/L2/L1Block.sol
After running `pnpm build` in the `packages/contracts-bedrock` directory, the bytecode to add to
the genesis file will be located in the `deployedBytecode` field of the build artifacts file at
`/packages/contracts-bedrock/forge-artifacts/L1Block.sol/L1Block.json`.
#### Ecotone L1Block upgrade
The L1 Attributes Predeployed contract, `L1Block.sol`, is upgraded as part of the Ecotone upgrade.
The version is incremented to `1.2.0`, one new storage slot is introduced, and one existing slot
begins to store additional data:
- `blobBaseFee` (`uint256`): The L1 blob base fee.
- `blobBaseFeeScalar` (`uint32`): The scalar value applied to the L1 blob base fee portion of the L1 cost.
- `baseFeeScalar` (`uint32`): The scalar value applied to the L1 base fee portion of the L1 cost.
The function called by the L1 attributes transaction depends on the network upgrade:
- Before the Ecotone activation:
- `setL1BlockValues` is called, following the pre-Ecotone L1 attributes rules.
- At the Ecotone activation block:
- `setL1BlockValues` function MUST be called, except if activated at genesis.
The contract is upgraded later in this block, to support `setL1BlockValuesEcotone`.
- After the Ecotone activation:
- `setL1BlockValues` function is deprecated and MUST never be called.
- `setL1BlockValuesEcotone` MUST be called with the new Ecotone attributes.
`setL1BlockValuesEcotone` uses a tightly packed encoding for its parameters, which is described in
[L1 Attributes Deposited Transaction Calldata](#l1-attributes-deposited-transaction-calldata).
## User-Deposited Transactions
[user-deposited]: #user-deposited-transactions
[User-deposited transactions][g-user-deposited] are [deposited transactions][deposited-tx-type]
generated by the [L2 Chain Derivation][g-derivation] process. The content of each user-deposited
transaction are determined by the corresponding `TransactionDeposited` event emitted by the
[deposit contract][deposit-contract] on L1.
1. `from` is unchanged from the emitted value (though it may
have been transformed to an alias in `OptimismPortal`, the deposit feed contract).
2. `to` is any 20-byte address (including the zero address)
- In case of a contract creation (cf. `isCreation`), this address is set to `null`.
3. `mint` is set to the emitted value.
4. `value` is set to the emitted value.
5. `gaslimit` is unchanged from the emitted value. It must be at least 21000.
6. `isCreation` is set to `true` if the transaction is a contract creation, `false` otherwise.
7. `data` is unchanged from the emitted value. Depending on the value of `isCreation` it is handled
as either calldata or contract initialization code.
8. `isSystemTx` is set by the rollup node for certain transactions that have unmetered execution.
It is `false` for user deposited transactions
### Deposit Contract
[deposit-contract]: #deposit-contract
The deposit contract is deployed to L1. Deposited transactions are derived from the values in
the `TransactionDeposited` event(s) emitted by the deposit contract.
The deposit contract is responsible for maintaining the [guaranteed gas market](./guaranteed-gas-market.md),
charging deposits for gas to be used on L2, and ensuring that the total amount of guaranteed
gas in a single L1 block does not exceed the L2 block gas limit.
The deposit contract handles two special cases:
1. A contract creation deposit, which is indicated by setting the `isCreation` flag to `true`.
In the event that the `to` address is non-zero, the contract will revert.
2. A call from a contract account, in which case the `from` value is transformed to its L2
[alias][address-aliasing].
#### Address Aliasing
[address-aliasing]: #address-aliasing
If the caller is a contract, the address will be transformed by adding
`0x1111000000000000000000000000000000001111` to it. The math is `unchecked` and done on a
Solidity `uint160` so the value will overflow. This prevents attacks in which a
contract on L1 has the same address as a contract on L2 but doesn't have the same code. We can safely ignore this
for EOAs because they're guaranteed to have the same "code" (i.e. no code at all). This also makes
it possible for users to interact with contracts on L2 even when the Sequencer is down.
#### Deposit Contract Implementation: Optimism Portal
A reference implementation of the deposit contract can be found in [OptimismPortal.sol].
[OptimismPortal.sol]: ../packages/contracts-bedrock/src/L1/OptimismPortal.sol
# L2 Chain Derivation Specification
<!-- All glossary references in this file. -->
[g-derivation]: glossary.md#L2-chain-derivation
[g-payload-attr]: glossary.md#payload-attributes
[g-block]: glossary.md#block
[g-exec-engine]: glossary.md#execution-engine
[g-reorg]: glossary.md#chain-re-organization
[g-receipts]: glossary.md#receipt
[g-inception]: glossary.md#L2-chain-inception
[g-deposit-contract]: glossary.md#deposit-contract
[g-deposited]: glossary.md#deposited-transaction
[g-l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction
[g-l1-origin]: glossary.md#l1-origin
[g-user-deposited]: glossary.md#user-deposited-transaction
[g-deposits]: glossary.md#deposits
[g-deposit-contract]: glossary.md#deposit-contract
[g-l1-attr-predeploy]: glossary.md#l1-attributes-predeployed-contract
[g-depositing-call]: glossary.md#depositing-call
[g-depositing-transaction]: glossary.md#depositing-transaction
[g-sequencing]: glossary.md#sequencing
[g-sequencer]: glossary.md#sequencer
[g-sequencing-epoch]: glossary.md#sequencing-epoch
[g-sequencing-window]: glossary.md#sequencing-window
[g-sequencer-batch]: glossary.md#sequencer-batch
[g-l2-genesis]: glossary.md#l2-genesis-block
[g-l2-chain-inception]: glossary.md#L2-chain-inception
[g-l2-genesis-block]: glossary.md#l2-genesis-block
[g-batcher-transaction]: glossary.md#batcher-transaction
[g-avail-provider]: glossary.md#data-availability-provider
[g-batcher]: glossary.md#batcher
[g-l2-output]: glossary.md#l2-output-root
[g-fault-proof]: glossary.md#fault-proof
[g-channel]: glossary.md#channel
[g-channel-frame]: glossary.md#channel-frame
[g-rollup-node]: glossary.md#rollup-node
[g-channel-timeout]: glossary.md#channel-timeout
[g-block-time]: glossary.md#block-time
[g-time-slot]: glossary.md#time-slot
[g-consolidation]: glossary.md#unsafe-block-consolidation
[g-safe-l2-head]: glossary.md#safe-l2-head
[g-safe-l2-block]: glossary.md#safe-l2-block
[g-unsafe-l2-head]: glossary.md#unsafe-l2-head
[g-unsafe-l2-block]: glossary.md#unsafe-l2-block
[g-unsafe-sync]: glossary.md#unsafe-sync
[g-l1-origin]: glossary.md#l1-origin
[g-deposit-tx-type]: glossary.md#deposited-transaction-type
[g-finalized-l2-head]: glossary.md#finalized-l2-head
[g-system-config]: glossary.md#system-configuration
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [Eager Block Derivation](#eager-block-derivation)
- [Batch Submission](#batch-submission)
- [Sequencing & Batch Submission Overview](#sequencing--batch-submission-overview)
- [Batch Submission Wire Format](#batch-submission-wire-format)
- [Batcher Transaction Format](#batcher-transaction-format)
- [Frame Format](#frame-format)
- [Channel Format](#channel-format)
- [Batch Format](#batch-format)
- [Architecture](#architecture)
- [L2 Chain Derivation Pipeline](#l2-chain-derivation-pipeline)
- [L1 Traversal](#l1-traversal)
- [L1 Retrieval](#l1-retrieval)
- [Ecotone: Blob Retrieval](#ecotone-blob-retrieval)
- [Blob Encoding](#blob-encoding)
- [Frame Queue](#frame-queue)
- [Channel Bank](#channel-bank)
- [Pruning](#pruning)
- [Timeouts](#timeouts)
- [Reading](#reading)
- [Loading frames](#loading-frames)
- [Channel Reader (Batch Decoding)](#channel-reader-batch-decoding)
- [Batch Queue](#batch-queue)
- [Payload Attributes Derivation](#payload-attributes-derivation)
- [Engine Queue](#engine-queue)
- [Engine API usage](#engine-api-usage)
- [Bedrock, Canyon, Delta: API Usage](#bedrock-canyon-delta-api-usage)
- [Ecotone: API Usage](#ecotone-api-usage)
- [Forkchoice synchronization](#forkchoice-synchronization)
- [L1-consolidation: payload attributes matching](#l1-consolidation-payload-attributes-matching)
- [L1-sync: payload attributes processing](#l1-sync-payload-attributes-processing)
- [Processing unsafe payload attributes](#processing-unsafe-payload-attributes)
- [Resetting the Pipeline](#resetting-the-pipeline)
- [Finding the sync starting point](#finding-the-sync-starting-point)
- [Resetting derivation stages](#resetting-derivation-stages)
- [About reorgs Post-Merge](#about-reorgs-post-merge)
- [Deriving Payload Attributes](#deriving-payload-attributes)
- [Deriving the Transaction List](#deriving-the-transaction-list)
- [Network upgrade automation transactions](#network-upgrade-automation-transactions)
- [Ecotone](#ecotone)
- [L1Block Deployment](#l1block-deployment)
- [GasPriceOracle Deployment](#gaspriceoracle-deployment)
- [L1Block Proxy Update](#l1block-proxy-update)
- [GasPriceOracle Proxy Update](#gaspriceoracle-proxy-update)
- [GasPriceOracle Enable Ecotone](#gaspriceoracle-enable-ecotone)
- [Beacon block roots contract deployment (EIP-4788)](#beacon-block-roots-contract-deployment-eip-4788)
- [Building Individual Payload Attributes](#building-individual-payload-attributes)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# Overview
> **Note** the following assumes a single sequencer and batcher. In the future, the design will be adapted to
> accommodate multiple such entities.
[L2 chain derivation][g-derivation] — deriving L2 [blocks][g-block] from L1 data — is one of the main responsibilities
of the [rollup node][g-rollup-node], both in validator mode, and in sequencer mode (where derivation acts as a sanity
check on sequencing, and enables detecting L1 chain [re-organizations][g-reorg]).
The L2 chain is derived from the L1 chain. In particular, each L1 block following [L2 chain
inception][g-l2-chain-inception] is mapped to a [sequencing epoch][g-sequencing-epoch] comprising
at least one L2 block. Each L2 block belongs to exactly one epoch, and we call the corresponding L1
block its [L1 origin][g-l1-origin]. The epoch's number equals that of its L1 origin block.
To derive the L2 blocks of epoch number `E`, we need the following inputs:
- L1 blocks in the range `[E, E + SWS)`, called the [sequencing window][g-sequencing-window] of the epoch, and `SWS`
the sequencing window size. (Note that sequencing windows overlap.)
- [Batcher transactions][g-batcher-transaction] from blocks in the sequencing window.
- These transactions allow us to reconstruct the epoch's [sequencer batches][g-sequencer-batch], each of
which will produce one L2 block. Note that:
- The L1 origin will never contain any data needed to construct sequencer batches since
each batch [must contain](#batch-format) the L1 origin hash.
- An epoch may have no sequencer batches.
- [Deposits][g-deposits] made in the L1 origin (in the form of events emitted by the [deposit
contract][g-deposit-contract]).
- L1 block attributes from the L1 origin (to derive the [L1 attributes deposited transaction][g-l1-attr-deposit]).
- The state of the L2 chain after the last L2 block of the previous epoch, or the [L2 genesis state][g-l2-genesis]
if `E` is the first epoch.
To derive the whole L2 chain from scratch, we start with the [L2 genesis state][g-l2-genesis] and
the [L2 genesis block][g-l2-genesis-block] as the first L2 block. We then derive L2 blocks from each epoch in order,
starting at the first L1 block following [L2 chain inception][g-l2-chain-inception]. Refer to the
[Architecture section][architecture] for more information on how we implement this in practice.
The L2 chain may contain pre-Bedrock history, but the L2 genesis here refers to the Bedrock L2
genesis block.
Each L2 `block` with origin `l1_origin` is subject to the following constraints (whose values are
denominated in seconds):
- `block.timestamp = prev_l2_timestamp + l2_block_time`
- `prev_l2_timestamp` is the timestamp of the L2 block immediately preceding this one. If there
is no preceding block, then this is the genesis block, and its timestamp is explicitly
specified.
- `l2_block_time` is a configurable parameter of the time between L2 blocks (2s on Optimism).
- `l1_origin.timestamp <= block.timestamp <= max_l2_timestamp`, where
- `max_l2_timestamp = max(l1_origin.timestamp + max_sequencer_drift, prev_l2_timestamp + l2_block_time)`
- `max_sequencer_drift` is a configurable parameter that bounds how far the sequencer can get ahead of
the L1.
Finally, each epoch must have at least one L2 block.
The first constraint means there must be an L2 block every `l2_block_time` seconds following L2
chain inception.
The second constraint ensures that an L2 block timestamp never precedes its L1 origin timestamp,
and is never more than `max_sequencer_drift` ahead of it, except only in the unusual case where it
might prohibit an L2 block from being produced every l2_block_time seconds. (Such cases might arise
for example under a proof-of-work L1 that sees a period of rapid L1 block production.) In either
case, the sequencer enforces `len(batch.transactions) == 0` while `max_sequencer_drift` is
exceeded. See [Batch Queue](#batch-queue) for more details.
The final requirement that each epoch must have at least one L2 block ensures that all relevant
information from the L1 (e.g. deposits) is represented in the L2, even if it has no sequencer
batches.
Post-merge, Ethereum has a fixed 12s [block time][g-block-time], though some slots can be
skipped. Under a 2s L2 block time, we thus expect each epoch to typically contain `12/2 = 6` L2
blocks. The sequencer will however produce bigger epochs in order to maintain liveness in case of
either a skipped slot on the L1 or a temporary loss of connection to it. For the lost connection
case, smaller epochs might be produced after the connection was restored to keep L2 timestamps from
drifting further and further ahead.
## Eager Block Derivation
Deriving an L2 block requires that we have constructed its sequencer batch and derived all L2
blocks and state updates prior to it. This means we can typically derive the L2 blocks of an epoch
*eagerly* without waiting on the full sequencing window. The full sequencing window is required
before derivation only in the very worst case where some portion of the sequencer batch for the
first block of the epoch appears in the very last L1 block of the window. Note that this only
applies to *block* derivation. Sequencer batches can still be derived and tentatively queued
without deriving blocks from them.
------------------------------------------------------------------------------------------------------------------------
# Batch Submission
## Sequencing & Batch Submission Overview
The [sequencer][g-sequencer] accepts L2 transactions from users. It is responsible for building blocks out of these. For
each such block, it also creates a corresponding [sequencer batch][g-sequencer-batch]. It is also responsible for
submitting each batch to a [data availability provider][g-avail-provider] (e.g. Ethereum calldata), which it does via
its [batcher][g-batcher] component.
The difference between an L2 block and a batch is subtle but important: the block includes an L2 state root, whereas the
batch only commits to transactions at a given L2 timestamp (equivalently: L2 block number). A block also includes a
reference to the previous block (\*).
(\*) This matters in some edge case where a L1 reorg would occur and a batch would be reposted to the L1 chain but not
the preceding batch, whereas the predecessor of an L2 block cannot possibly change.
This means that even if the sequencer applies a state transition incorrectly, the transactions in the batch will still
be considered part of the canonical L2 chain. Batches are still subject to validity checks (i.e. they have to be encoded
correctly), and so are individual transactions within the batch (e.g. signatures have to be valid). Invalid batches and
invalid individual transactions within an otherwise valid batch are discarded by correct nodes.
If the sequencer applies a state transition incorrectly and posts an [output root][g-l2-output], then this output root
will be incorrect. The incorrect output root which will be challenged by a [fault proof][g-fault-proof], then replaced
by a correct output root **for the existing sequencer batches.**
Refer to the [Batch Submission specification][batcher-spec] for more information.
[batcher-spec]: batcher.md
## Batch Submission Wire Format
[wire-format]: #batch-submission-wire-format
Batch submission is closely tied to L2 chain derivation because the derivation process must decode the batches that have
been encoded for the purpose of batch submission.
The [batcher][g-batcher] submits [batcher transactions][g-batcher-transaction] to a [data availability
provider][g-avail-provider]. These transactions contain one or multiple [channel frames][g-channel-frame], which are
chunks of data belonging to a [channel][g-channel].
A [channel][g-channel] is a sequence of [sequencer batches][g-sequencer-batch] (for any L2 blocks) compressed
together. The reason to group multiple batches together is simply to obtain a better compression rate, hence reducing
data availability costs.
Channels might be too large to fit in a single [batcher transaction][g-batcher-transaction], hence we need to split it
into chunks known as [channel frames][g-channel-frame]. A single batcher transaction can also carry multiple frames
(belonging to the same or to different channels).
This design gives use the maximum flexibility in how we aggregate batches into channels, and split channels over batcher
transactions. It notably allows us to maximize data utilisation in a batcher transaction: for instance it allows us to
pack the final (small) frame of a window with large frames from the next window.
In the future this channel identification feature also allows the [batcher][g-batcher] to employ multiple signers
(private keys) to submit one or multiple channels in parallel (1).
(1) This helps alleviate issues where, because of transaction nonce values affecting the L2 tx-pool and thus inclusion:
multiple transactions made by the same signer are stuck waiting on the inclusion of a previous transaction.
Also note that we use a streaming compression scheme, and we do not need to know how many blocks a channel will end up
containing when we start a channel, or even as we send the first frames in the channel.
And by splitting channels across multiple data transactions, the L2 can have larger block data than the
data-availability layer may support.
All of this is illustrated in the following diagram. Explanations below.
![batch derivation chain diagram](./assets/batch-deriv-chain.svg)
The first line represents L1 blocks with their numbers. The boxes under the L1 blocks represent [batcher
transactions][g-batcher-transaction] included within the block. The squiggles under the L1 blocks represent
[deposits][g-deposits] (more specifically, events emitted by the [deposit contract][g-deposit-contract]).
Each colored chunk within the boxes represents a [channel frame][g-channel-frame]. So `A` and `B` are
[channels][g-channel] whereas `A0`, `A1`, `B0`, `B1`, `B2` are frames. Notice that:
- multiple channels are interleaved
- frames do not need to be transmitted in order
- a single batcher transaction can carry frames from multiple channels
In the next line, the rounded boxes represent individual [sequencer batches][g-sequencer-batch] that were extracted from
the channels. The four blue/purple/pink were derived from channel `A` while the other were derived from channel `B`.
These batches are here represented in the order they were decoded from batches (in this case `B` is decoded first).
> **Note** The caption here says "Channel B was seen first and will be decoded into batches first", but this is not a
> requirement. For instance, it would be equally acceptable for an implementation to peek into the channels and decode
> the one that contains the oldest batches first.
The rest of the diagram is conceptually distinct from the first part and illustrates L2 chain derivation after the
channels have been reordered.
The first line shows batcher transactions. Note that in this case, there exists an ordering of the batches that makes
all frames within the channels appear contiguously. This is not true in general. For instance, in the second
transaction, the position of `A1` and `B0` could have been inverted for exactly the same result — no changes needed in
the rest of the diagram.
The second line shows the reconstructed channels in proper order. The third line shows the batches extracted from the
channel. Because the channels are ordered and the batches within a channel are sequential, this means the batches are
ordered too. The fourth line shows the [L2 block][g-block] derived from each batch. Note that we have a 1-1 batch to
block mapping here but, as we'll see later, empty blocks that do not map to batches can be inserted in cases where there
are "gaps" in the batches posted on L1.
The fifth line shows the [L1 attributes deposited transaction][g-l1-attr-deposit] which, within each L2 block, records
information about the L1 block that matches the L2 block's epoch. The first number denotes the epoch/L1x number, while
the second number (the "sequence number") denotes the position within the epoch.
Finally, the sixth line shows [user-deposited transactions][g-user-deposited] derived from the [deposit
contract][g-deposit-contract] event mentioned earlier.
Note the `101-0` L1 attributes transaction on the bottom right of the diagram. Its presence there is only possible if
frame `B2` indicates that it is the last frame within the channel and (2) no empty blocks must be inserted.
The diagram does not specify the sequencing window size in use, but from this we can infer that it must be at least 4
blocks, because the last frame of channel `A` appears in block 102, but belong to epoch 99.
As for the comment on "security types", it explains the classification of blocks as used on L1 and L2.
- [Unsafe L2 blocks][g-unsafe-l2-block]:
- [Safe L2 blocks][g-safe-l2-block]:
- Finalized L2 blocks: refer to block that have been derived from [finalized][g-finalized-l2-head] L1 data.
These security levels map to the `headBlockHash`, `safeBlockHash` and `finalizedBlockHash` values transmitted when
interacting with the [execution-engine API][exec-engine].
### Batcher Transaction Format
Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++` denotes concatenation).
| `version_byte` | `rollup_payload` |
|----------------|------------------------------------------------|
| 0 | `frame ...` (one or more frames, concatenated) |
Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node).
All frames in a batcher transaction must be parseable. If any one frame fails to parse, the all frames in the
transaction are rejected.
Batch transactions are authenticated by verifying that the `to` address of the transaction matches the batch inbox
address, and the `from` address matches the batch-sender address in the [system configuration][g-system-config] at the
time of the L1 block that the transaction data is read from.
### Frame Format
A [channel frame][g-channel-frame] is encoded as:
```text
frame = channel_id ++ frame_number ++ frame_data_length ++ frame_data ++ is_last
channel_id = bytes16
frame_number = uint16
frame_data_length = uint32
frame_data = bytes
is_last = bool
```
Where `uint32` and `uint16` are all big-endian unsigned integers. Type names should be interpreted to and
encoded according to [the Solidity ABI][solidity-abi].
[solidity-abi]: https://docs.soliditylang.org/en/v0.8.16/abi-spec.html
All data in a frame is fixed-size, except the `frame_data`. The fixed overhead is `16 + 2 + 4 + 1 = 23 bytes`.
Fixed-size frame metadata avoids a circular dependency with the target total data length,
to simplify packing of frames with varying content length.
where:
- `channel_id` is an opaque identifier for the channel. It should not be reused and is suggested to be random; however,
outside of timeout rules, it is not checked for validity
- `frame_number` identifies the index of the frame within the channel
- `frame_data_length` is the length of `frame_data` in bytes. It is capped to 1,000,000 bytes.
- `frame_data` is a sequence of bytes belonging to the channel, logically after the bytes from the previous frames
- `is_last` is a single byte with a value of 1 if the frame is the last in the channel, 0 if there are frames in the
channel. Any other value makes the frame invalid (it must be ignored by the rollup node).
[batcher-spec]: batching.md
### Channel Format
A channel is encoded as `channel_encoding`, defined as:
```text
rlp_batches = []
for batch in batches:
rlp_batches.append(batch)
channel_encoding = compress(rlp_batches)
```
where:
- `batches` is the input, a sequence of batches byte-encoded as per the next section ("Batch Encoding")
- `rlp_batches` is the concatenation of the RLP-encoded batches
- `compress` is a function performing compression, using the ZLIB algorithm (as specified in [RFC-1950][rfc1950]) with
no dictionary
- `channel_encoding` is the compressed version of `rlp_batches`
[rfc1950]: https://www.rfc-editor.org/rfc/rfc1950.html
When decompressing a channel, we limit the amount of decompressed data to `MAX_RLP_BYTES_PER_CHANNEL` (currently
10,000,000 bytes), in order to avoid "zip-bomb" types of attack (where a small compressed input decompresses to a
humongous amount of data). If the decompressed data exceeds the limit, things proceeds as though the channel contained
only the first `MAX_RLP_BYTES_PER_CHANNEL` decompressed bytes. The limit is set on RLP decoding, so all batches that
can be decoded in `MAX_RLP_BYTES_PER_CHANNEL` will be accepted even if the size of the channel is greater than
`MAX_RLP_BYTES_PER_CHANNEL`. The exact requirement is that `length(input) <= MAX_RLP_BYTES_PER_CHANNEL`.
While the above pseudocode implies that all batches are known in advance, it is possible to perform streaming
compression and decompression of RLP-encoded batches. This means it is possible to start including channel frames in a
[batcher transaction][g-batcher-transaction] before we know how many batches (and how many frames) the channel will
contain.
### Batch Format
[batch-format]: #batch-format
Recall that a batch contains a list of transactions to be included in a specific L2 block.
A batch is encoded as `batch_version ++ content`, where `content` depends on the `batch_version`:
| `batch_version` | `content` |
|-----------------|------------------------------------------------------------------------------------|
| 0 | `rlp_encode([parent_hash, epoch_number, epoch_hash, timestamp, transaction_list])` |
where:
- `batch_version` is a single byte, prefixed before the RLP contents, alike to transaction typing.
- `rlp_encode` is a function that encodes a batch according to the [RLP format], and `[x, y, z]` denotes a list
containing items `x`, `y` and `z`
- `parent_hash` is the block hash of the previous L2 block
- `epoch_number` and `epoch_hash` are the number and hash of the L1 block corresponding to the [sequencing
epoch][g-sequencing-epoch] of the L2 block
- `timestamp` is the timestamp of the L2 block
- `transaction_list` is an RLP-encoded list of [EIP-2718] encoded transactions.
[RLP format]: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/
[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
Unknown versions make the batch invalid (it must be ignored by the rollup node), as do malformed contents.
The `epoch_number` and the `timestamp` must also respect the constraints listed in the [Batch Queue][batch-queue]
section, otherwise the batch is considered invalid and will be ignored.
------------------------------------------------------------------------------------------------------------------------
# Architecture
[architecture]: #architecture
The above primarily describes the general encodings used in L2 chain derivation,
primarily how batches are encoded within [batcher transactions][g-batcher-transaction].
This section describes how the L2 chain is produced from the L1 batches using a pipeline architecture.
A verifier may implement this differently, but must be semantically equivalent to not diverge from the L2 chain.
## L2 Chain Derivation Pipeline
[pipeline]: #l2-chain-derivation-pipeline
Our architecture decomposes the derivation process into a pipeline made up of the following stages:
1. L1 Traversal
2. L1 Retrieval
3. Frame Queue
4. Channel Bank
5. Channel Reader (Batch Decoding)
6. Batch Queue
7. Payload Attributes Derivation
8. Engine Queue
The data flows from the start (outer) of the pipeline towards the end (inner).
From the innermost stage the data is pulled from the outermost stage.
However, data is *processed* in reverse order. Meaning that if there is any data to be processed in the last stage, it
will be processed first. Processing proceeds in "steps" that can be taken at each stage. We try to take as many steps as
possible in the last (most inner) stage before taking any steps in its outer stage, etc.
This ensures that we use the data we already have before pulling more data and minimizes the latency of data traversing
the derivation pipeline.
Each stage can maintain its own inner state as necessary. In particular, each stage maintains a L1 block reference
(number + hash) to the latest L1 block such that all data originating from previous blocks has been fully processed, and
the data from that block is being or has been processed. This allows the innermost stage to account for finalization of
the L1 data-availability used to produce the L2 chain, to reflect in the L2 chain forkchoice when the L2 chain inputs
become irreversible.
Let's briefly describe each stage of the pipeline.
### L1 Traversal
In the *L1 Traversal* stage, we simply read the header of the next L1 block. In normal operations, these will be new
L1 blocks as they get created, though we can also read old blocks while syncing, or in case of an L1 [re-org][g-reorg].
Upon traversal of the L1 block, the [system configuration][g-system-config] copy used by the L1 retrieval stage is
updated, such that the batch-sender authentication is always accurate to the exact L1 block that is read by the stage.
### L1 Retrieval
In the *L1 Retrieval* stage, we read the block we get from the outer stage (L1 traversal), and
extract data from its [batcher transactions][g-batcher-transaction]. A batcher
transaction is one with the following properties:
- The [`to`] field is equal to the configured batcher inbox address.
- The sender, as recovered from the transaction signature (`v`, `r`, and `s`), is the batcher
address loaded from the system config matching the L1 block of the data.
Each batcher transaction is versioned and contains a series of [channel frames][g-channel-frame] to
be read by the Frame Queue, see [Batch Submission Wire Format][wire-format]. Each batcher
transaction in the block is processed in the order they appear in the block by passing its calldata
on to the next phase.
[`to`]: https://github.com/ethereum/execution-specs/blob/3fe6514f2d9d234e760d11af883a47c1263eff51/src/ethereum/frontier/fork_types.py#L52C31-L52C31
#### Ecotone: Blob Retrieval
With the Ecotone upgrade the retrieval stage is extended to support an additional DA source:
[EIP-4844] blobs. After the Ecotone upgrade we modify the iteration over batcher transactions to
treat transactions of transaction-type == `0x03` (`BLOB_TX_TYPE`) differently. If the batcher
transaction is a blob transaction, then its calldata MUST be ignored should it be present. Instead:
- For each blob hash in `blob_versioned_hashes`, retrieve the blob that matches it. A blob may be
retrieved from any of a number different sources. Retrieval from a local beacon-node, through
the `/eth/v1/beacon/blob_sidecars/` endpoint, with `indices` filter to skip unrelated blobs, is
recommended. For each retrieved blob:
- The blob SHOULD (MUST, if the source is untrusted) be cryptographically verified against its
versioned hash.
- If the blob has a [valid encoding](#blob-encoding), decode it into its continuous byte-string
and pass that on to the next phase. Otherwise the blob is ignored.
Note that batcher transactions of type blob must be processed in the same loop as other batcher
transactions to preserve the invariant that batches are always processed in the order they appear
in the block. We ignore calldata in blob transactions so that it may be used in the future for
batch metadata or other purposes.
##### Blob Encoding
Each blob in a [EIP-4844] transaction really consists of `FIELD_ELEMENTS_PER_BLOB = 4096` field elements.
Each field element is a number in a prime field of
`BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513`.
This number does not represent a full `uint256`: `math.log2(BLS_MODULUS) = 254.8570894...`
The [L1 consensus-specs](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/polynomial-commitments.md)
describe the encoding of this polynomial.
The field elements are encoded as big-endian integers (`KZG_ENDIANNESS = big`).
To save computational overhead, only `254` bits per field element are used for rollup data.
`127` bytes of application-layer rollup data is encoded at a time, into 4 adjacent field elements of the blob:
```python
# read(N): read the next N bytes from the application-layer rollup-data. The next read starts where the last stopped.
# write(V): append V (one or more bytes) to the raw blob.
bytes tailA = read(31)
byte x = read(1)
byte A = x & 0b0011_1111
write(A)
write(tailA)
bytes tailB = read(31)
byte y = read(1)
byte B = (y & 0b0000_1111) | (x & 0b1100_0000) >> 2)
write(B)
write(tailB)
bytes tailC = read(31)
byte z = read(1)
byte C = z & 0b0011_1111
write(C)
write(tailC)
bytes tailD = read(31)
byte D = ((z & 0b1100_0000) >> 2) | ((y & 0b1111_0000) >> 4)
write(D)
write(tailD)
```
Each written field element looks like this:
- Starts with one of the prepared 6-bit left-padded byte values, to keep the field element within valid range.
- Followed by 31 bytes of application-layer data, to fill the low 31 bytes of the field element.
The written output should look like this:
```text
<----- element 0 -----><----- element 1 -----><----- element 2 -----><----- element 3 ----->
| byte A | tailA... || byte B | tailB... || byte C | tailC... || byte D | tailD... |
```
The above is repeated 1024 times, to fill all `4096` elements,
with a total of `(4 * 31 + 3) * 1024 = 130048` bytes of data.
When decoding a blob, the top-most two bits of each field-element must be 0,
to make the encoding/decoding bijective.
The first byte of rollup-data (second byte in first field element) is used as a version-byte.
In version `0`, the next 3 bytes of data are used to encode the length of the rollup-data, as big-endian `uint24`.
Any trailing data, past the length delimiter, must be 0, to keep the encoding/decoding bijective.
If the length is larger than `130048 - 4`, the blob is invalid.
If any of the encoding is invalid, the blob as whole must be ignored.
[EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
### Frame Queue
The Frame Queue buffers one data-transaction at a time,
decoded into [channel frames][g-channel-frame], to be consumed by the next stage.
See [Batcher transaction format](#batcher-transaction-format) and [Frame format](#frame-format) specifications.
### Channel Bank
The *Channel Bank* stage is responsible for managing buffering from the channel bank that was written to by the L1
retrieval stage. A step in the channel bank stage tries to read data from channels that are "ready".
Channels are currently fully buffered until read or dropped,
streaming channels may be supported in a future version of the ChannelBank.
To bound resource usage, the Channel Bank prunes based on channel size, and times out old channels.
Channels are recorded in FIFO order in a structure called the *channel queue*. A channel is added to the channel
queue the first time a frame belonging to the channel is seen.
#### Pruning
After successfully inserting a new frame, the ChannelBank is pruned:
channels are dropped in FIFO order, until `total_size <= MAX_CHANNEL_BANK_SIZE`, where:
- `total_size` is the sum of the sizes of each channel, which is the sum of all buffered frame data of the channel,
with an additional frame-overhead of `200` bytes per frame.
- `MAX_CHANNEL_BANK_SIZE` is a protocol constant of 100,000,000 bytes.
#### Timeouts
The L1 origin that the channel was opened in is tracked with the channel as `channel.open_l1_block`,
and determines the maximum span of L1 blocks that the channel data is retained for, before being pruned.
A channel is timed out if: `current_l1_block.number > channel.open_l1_block.number + CHANNEL_TIMEOUT`, where:
- `current_l1_block` is the L1 origin that the stage is currently traversing.
- `CHANNEL_TIMEOUT` is a rollup-configurable, expressed in number of L1 blocks.
New frames for timed-out channels are dropped instead of buffered.
#### Reading
Upon reading, while the first opened channel is timed-out, remove it from the channel-bank.
Prior to the Canyon network upgrade, once the first opened channel, if any, is not timed-out and is ready,
then it is read and removed from the channel-bank. After the Canyon network upgrade, the entire channel bank
is scanned in FIFO order (by open time) & the first ready (i.e. not timed-out) channel will be returned.
The canyon behavior will activate when frames from a L1 block whose timestamp is greater than or equal to the
canyon time first enter the channel queue.
A channel is ready if:
- The channel is closed
- The channel has a contiguous sequence of frames until the closing frame
If no channel is ready, the next frame is read and ingested into the channel bank.
#### Loading frames
When a channel ID referenced by a frame is not already present in the Channel Bank,
a new channel is opened, tagged with the current L1 block, and appended to the channel-queue.
Frame insertion conditions:
- New frames matching timed-out channels that have not yet been pruned from the channel-bank are dropped.
- Duplicate frames (by frame number) for frames that have not been pruned from the channel-bank are dropped.
- Duplicate closes (new frame `is_last == 1`, but the channel has already seen a closing frame and has not yet been
pruned from the channel-bank) are dropped.
If a frame is closing (`is_last == 1`) any existing higher-numbered frames are removed from the channel.
Note that while this allows channel IDs to be reused once they have been pruned from the channel-bank, it is recommended
that batcher implementations use unique channel IDs.
### Channel Reader (Batch Decoding)
In this stage, we decompress the channel we pull from the last stage, and then parse
[batches][g-sequencer-batch] from the decompressed byte stream.
See [Batch Format][batch-format] for decompression and decoding specification.
### Batch Queue
[batch-queue]: #batch-queue
During the *Batch Buffering* stage, we reorder batches by their timestamps. If batches are missing for some [time
slots][g-time-slot] and a valid batch with a higher timestamp exists, this stage also generates empty batches to fill
the gaps.
Batches are pushed to the next stage whenever there is one sequential batch directly following the timestamp
of the current [safe L2 head][g-safe-l2-head] (the last block that can be derived from the canonical L1 chain).
The parent hash of the batch must also match the hash of the current safe L2 head.
Note that the presence of any gaps in the batches derived from L1 means that this stage will need to buffer for a whole
[sequencing window][g-sequencing-window] before it can generate empty batches (because the missing batch(es) could have
data in the last L1 block of the window in the worst case).
A batch can have 4 different forms of validity:
- `drop`: the batch is invalid, and will always be in the future, unless we reorg. It can be removed from the buffer.
- `accept`: the batch is valid and should be processed.
- `undecided`: we are lacking L1 information until we can proceed batch filtering.
- `future`: the batch may be valid, but cannot be processed yet and should be checked again later.
The batches are processed in order of the inclusion on L1: if multiple batches can be `accept`-ed the first is applied.
An implementation can defer `future` batches a later derivation step to reduce validation work.
The batches validity is derived as follows:
Definitions:
- `batch` as defined in the [Batch format section][batch-format].
- `epoch = safe_l2_head.l1_origin` a [L1 origin][g-l1-origin] coupled to the batch, with properties:
`number` (L1 block number), `hash` (L1 block hash), and `timestamp` (L1 block timestamp).
- `inclusion_block_number` is the L1 block number when `batch` was first *fully* derived,
i.e. decoded and output by the previous stage.
- `next_timestamp = safe_l2_head.timestamp + block_time` is the expected L2 timestamp the next batch should have,
see [block time information][g-block-time].
- `next_epoch` may not be known yet, but would be the L1 block after `epoch` if available.
- `batch_origin` is either `epoch` or `next_epoch`, depending on validation.
Note that processing of a batch can be deferred until `batch.timestamp <= next_timestamp`,
since `future` batches will have to be retained anyway.
Rules, in validation order:
- `batch.timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process.
- `batch.timestamp < next_timestamp` -> `drop`: i.e. the batch must not be too old.
- `batch.parent_hash != safe_l2_head.hash` -> `drop`: i.e. the parent hash must be equal to the L2 safe head block hash.
- `batch.epoch_num + sequence_window_size < inclusion_block_number` -> `drop`: i.e. the batch must be included timely.
- `batch.epoch_num < epoch.number` -> `drop`: i.e. the batch origin is not older than that of the L2 safe head.
- `batch.epoch_num == epoch.number`: define `batch_origin` as `epoch`.
- `batch.epoch_num == epoch.number+1`:
- If `next_epoch` is not known -> `undecided`:
i.e. a batch that changes the L1 origin cannot be processed until we have the L1 origin data.
- If known, then define `batch_origin` as `next_epoch`
- `batch.epoch_num > epoch.number+1` -> `drop`: i.e. the L1 origin cannot change by more than one L1 block per L2 block.
- `batch.epoch_hash != batch_origin.hash` -> `drop`: i.e. a batch must reference a canonical L1 origin,
to prevent batches from being replayed onto unexpected L1 chains.
- `batch.timestamp < batch_origin.time` -> `drop`: enforce the min L2 timestamp rule.
- `batch.timestamp > batch_origin.time + max_sequencer_drift`: enforce the L2 timestamp drift rule,
but with exceptions to preserve above min L2 timestamp invariant:
- `len(batch.transactions) == 0`:
- `epoch.number == batch.epoch_num`:
this implies the batch does not already advance the L1 origin, and must thus be checked against `next_epoch`.
- If `next_epoch` is not known -> `undecided`:
without the next L1 origin we cannot yet determine if time invariant could have been kept.
- If `batch.timestamp >= next_epoch.time` -> `drop`:
the batch could have adopted the next L1 origin without breaking the `L2 time >= L1 time` invariant.
- `len(batch.transactions) > 0`: -> `drop`:
when exceeding the sequencer time drift, never allow the sequencer to include transactions.
- `batch.transactions`: `drop` if the `batch.transactions` list contains a transaction
that is invalid or derived by other means exclusively:
- any transaction that is empty (zero length byte string)
- any [deposited transactions][g-deposit-tx-type] (identified by the transaction type prefix byte)
If no batch can be `accept`-ed, and the stage has completed buffering of all batches that can fully be read from the L1
block at height `epoch.number + sequence_window_size`, and the `next_epoch` is available,
then an empty batch can be derived with the following properties:
- `parent_hash = safe_l2_head.hash`
- `timestamp = next_timestamp`
- `transactions` is empty, i.e. no sequencer transactions. Deposited transactions may be added in the next stage.
- If `next_timestamp < next_epoch.time`: the current L1 origin is repeated, to preserve the L2 time invariant.
- `epoch_num = epoch.number`
- `epoch_hash = epoch.hash`
- If the batch is the first batch of the epoch, that epoch is used instead of advancing the epoch to ensure that
there is at least one L2 block per epoch.
- `epoch_num = epoch.number`
- `epoch_hash = epoch.hash`
- Otherwise,
- `epoch_num = next_epoch.number`
- `epoch_hash = next_epoch.hash`
### Payload Attributes Derivation
In the *Payload Attributes Derivation* stage, we convert the batches we get from the previous stage into instances of
the [`PayloadAttributes`][g-payload-attr] structure. Such a structure encodes the transactions that need to figure into
a block, as well as other block inputs (timestamp, fee recipient, etc). Payload attributes derivation is detailed in the
section [Deriving Payload Attributes section][deriving-payload-attr] below.
This stage maintains its own copy of the [system configuration][g-system-config], independent of the L1 retrieval stage.
The system configuration is updated with L1 log events whenever the L1 epoch referenced by the batch input changes.
### Engine Queue
In the *Engine Queue* stage, the previously derived `PayloadAttributes` structures are buffered and sent to the
[execution engine][g-exec-engine] to be executed and converted into a proper L2 block.
The stage maintains references to three L2 blocks:
- The [finalized L2 head][g-finalized-l2-head]: everything up to and including this block can be fully derived from the
[finalized][l1-finality] (i.e. canonical and forever irreversible) part of the L1 chain.
- The [safe L2 head][g-safe-l2-head]: everything up to and including this block can be fully derived from the
currently canonical L1 chain.
- The [unsafe L2 head][g-unsafe-l2-head]: blocks between the safe and unsafe heads are [unsafe
blocks][g-unsafe-l2-block] that have not been derived from L1. These blocks either come from sequencing (in sequencer
mode) or from [unsafe sync][g-unsafe-sync] to the sequencer (in validator mode).
This is also known as the "latest" head.
Additionally, it buffers a short history of references to recently processed safe L2 blocks, along with references
from which L1 blocks each was derived.
This history does not have to be complete, but enables later L1 finality signals to be translated into L2 finality.
#### Engine API usage
To interact with the engine, the [execution engine API][exec-engine] is used, with the following JSON-RPC methods:
[exec-engine]: exec-engine.md
##### Bedrock, Canyon, Delta: API Usage
- [`engine_forkchoiceUpdatedV2`] — updates the forkchoice (i.e. the chain head) to `headBlockHash` if different, and
instructs the engine to start building an execution payload if the payload attributes parameter is not `null`.
- [`engine_getPayloadV2`] — retrieves a previously requested execution payload build.
- [`engine_newPayloadV2`] — executes an execution payload to create a block.
##### Ecotone: API Usage
- [`engine_forkchoiceUpdatedV3`] — updates the forkchoice (i.e. the chain head) to `headBlockHash` if different, and
instructs the engine to start building an execution payload if the payload attributes parameter is not `null`.
- [`engine_getPayloadV3`] — retrieves a previously requested execution payload build.
- `engine_newPayload`
- [`engine_newPayloadV2`] — executes a Bedrock/Canyon/Delta execution payload to create a block.
- [`engine_newPayloadV3`] — executes an Ecotone execution payload to create a block.
The current version of `op-node` uses the `v3` Engine API RPC methods as well as `engine_newPayloadV2`, due to
`engine_newPayloadV3` only supporting Ecotone execution payloads. Both `engine_forkchoiceUpdatedV3` and
`engine_getPayloadV3` are backwards compatible with Bedrock, Canyon & Delta payloads.
Prior versions of `op-node` used `v2` and `v1` methods.
[`engine_forkchoiceUpdatedV2`]: exec-engine.md#engine_forkchoiceupdatedv2
[`engine_forkchoiceUpdatedV3`]: exec-engine.md#engine_forkchoiceupdatedv3
[`engine_getPayloadV2`]: exec-engine.md#engine_getpayloadv2
[`engine_getPayloadV3`]: exec-engine.md#engine_getpayloadv3
[`engine_newPayloadV2`]: exec-engine.md#engine_newpayloadv2
[`engine_newPayloadV3`]: exec-engine.md#engine_newpayloadv3
The execution payload is an object of type [`ExecutionPayloadV3`][eth-payload].
[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md
The `ExecutionPayload` has the following requirements:
- Bedrock
- The withdrawals field MUST be nil
- The blob gas used field MUST be nil
- The blob gas limit field MUST be nil
- Canyon, Delta
- The withdrawals field MUST be non-nil
- The withdrawals field MUST be an empty list
- The blob gas used field MUST be nil
- The blob gas limit field MUST be nil
- Ecotone
- The withdrawals field MUST be non-nil
- The withdrawals field MUST be an empty list
- The blob gas used field MUST be 0
- The blob gas limit field MUST be 0
#### Forkchoice synchronization
If there are any forkchoice updates to be applied, before additional inputs are derived or processed, then these are
applied to the engine first.
This synchronization may happen when:
- A L1 finality signal finalizes one or more L2 blocks: updating the "finalized" L2 block.
- A successful consolidation of unsafe L2 blocks: updating the "safe" L2 block.
- The first thing after a derivation pipeline reset, to ensure a consistent execution engine forkchoice state.
The new forkchoice state is applied by calling [fork choice updated](#engine-api-usage) on the engine API.
On forkchoice-state validity errors the derivation pipeline must be reset to recover to consistent state.
#### L1-consolidation: payload attributes matching
If the unsafe head is ahead of the safe head, then [consolidation][g-consolidation] is attempted, verifying that
existing unsafe L2 chain matches the derived L2 inputs as derived from the canonical L1 data.
During consolidation, we consider the oldest unsafe L2 block, i.e. the unsafe L2 block directly after the safe head. If
the payload attributes match this oldest unsafe L2 block, then that block can be considered "safe" and becomes the new
safe head.
The following fields of the derived L2 payload attributes are checked for equality with the L2 block:
- Bedrock, Canyon, Delta, Ecotone Blocks
- `parent_hash`
- `timestamp`
- `randao`
- `fee_recipient`
- `transactions_list` (first length, then equality of each of the encoded transactions, including deposits)
- `gas_limit`
- Canyon, Delta, Ecotone Blocks
- `withdrawals` (first presence, then length, then equality of each of the encoded withdrawals)
- Ecotone Blocks
- `parent_beacon_block_root`
If consolidation succeeds, the forkchoice change will synchronize as described in the section above.
If consolidation fails, the L2 payload attributes will be processed immediately as described in the section below.
The payload attributes are chosen in favor of the previous unsafe L2 block, creating an L2 chain reorg on top of the
current safe block. Immediately processing the new alternative attributes enables execution engines like go-ethereum to
enact the change, as linear rewinds of the tip of the chain may not be supported.
#### L1-sync: payload attributes processing
[exec-engine-comm]: exec-engine.md#engine-api
If the safe and unsafe L2 heads are identical (whether because of failed consolidation or not), we send the L2 payload
attributes to the execution engine to be constructed into a proper L2 block.
This L2 block will then become both the new L2 safe and unsafe head.
If a payload attributes created from a batch cannot be inserted into the chain because of a validation error (i.e. there
was an invalid transaction or state transition in the block) the batch should be dropped & the safe head should not be
advanced. The engine queue will attempt to use the next batch for that timestamp from the batch queue. If no valid batch
is found, the rollup node will create a deposit only batch which should always pass validation because deposits are
always valid.
Interaction with the execution engine via the execution engine API is detailed in the [Communication with the Execution
Engine][exec-engine-comm] section.
The payload attributes are then processed with a sequence of:
- [Engine: Fork choice updated](#engine-api-usage) with current forkchoice state of the stage, and the attributes to
start block building.
- Non-deterministic sources, like the tx-pool, must be disabled to reconstruct the expected block.
- [Engine: Get Payload](#engine-api-usage) to retrieve the payload, by the payload-ID in the result of the previous
step.
- [Engine: New Payload](#engine-api-usage) to import the new payload into the execution engine.
- [Engine: Fork Choice Updated](#engine-api-usage) to make the new payload canonical,
now with a change of both `safe` and `unsafe` fields to refer to the payload, and no payload attributes.
Engine API Error handling:
- On RPC-type errors the payload attributes processing should be re-attempted in a future step.
- On payload processing errors the attributes must be dropped, and the forkchoice state must be left unchanged.
- Eventually the derivation pipeline will produce alternative payload attributes, with or without batches.
- If the payload attributes only contained deposits, then it is a critical derivation error if these are invalid.
- On forkchoice-state validity errors the derivation pipeline must be reset to recover to consistent state.
#### Processing unsafe payload attributes
If no forkchoice updates or L1 data remain to be processed, and if the next possible L2 block is already available
through an unsafe source such as the sequencer publishing it via the p2p network, then it is optimistically processed as
an "unsafe" block. This reduces later derivation work to just consolidation with L1 in the happy case, and enables the
user to see the head of the L2 chain faster than the L1 may confirm the L2 batches.
To process unsafe payloads, the payload must:
- Have a block number higher than the current safe L2 head.
- The safe L2 head may only be reorged out due to L1 reorgs.
- Have a parent blockhash that matches the current unsafe L2 head.
- This prevents the execution engine individually syncing a larger gap in the unsafe L2 chain.
- This prevents unsafe L2 blocks from reorging other previously validated L2 blocks.
- This check may change in the future versions to adopt e.g. the L1 snap-sync protocol.
The payload is then processed with a sequence of:
- Bedrock/Canyon/Delta Payloads
- `engine_newPayloadV2`: process the payload. It does not become canonical yet.
- `engine_forkchoiceUpdatedV2`: make the payload the canonical unsafe L2 head, and keep the safe/finalized L2 heads.
- Ecotone Payloads
- `engine_newPayloadV3`: process the payload. It does not become canonical yet.
- `engine_forkchoiceUpdatedV3`: make the payload the canonical unsafe L2 head, and keep the safe/finalized L2 heads.
Engine API Error handling:
- On RPC-type errors the payload processing should be re-attempted in a future step.
- On payload processing errors the payload must be dropped, and not be marked as canonical.
- On forkchoice-state validity errors the derivation pipeline must be reset to recover to consistent state.
### Resetting the Pipeline
It is possible to reset the pipeline, for instance if we detect an L1 [reorg (reorganization)][g-reorg].
**This enables the rollup node to handle L1 chain reorg events.**
Resetting will recover the pipeline into a state that produces the same outputs as a full L2 derivation process,
but starting from an existing L2 chain that is traversed back just enough to reconcile with the current L1 chain.
Note that this algorithm covers several important use-cases:
- Initialize the pipeline without starting from 0, e.g. when the rollup node restarts with an existing engine instance.
- Recover the pipeline if it becomes inconsistent with the execution engine chain, e.g. when the engine syncs/changes.
- Recover the pipeline when the L1 chain reorganizes, e.g. a late L1 block is orphaned, or a larger attestation failure.
- Initialize the pipeline to derive a disputed L2 block with prior L1 and L2 history inside a fault-proof program.
Handling these cases also means a node can be configured to eagerly sync L1 data with 0 confirmations,
as it can undo the changes if the L1 later does recognize the data as canonical, enabling safe low-latency usage.
The Engine Queue is first reset, to determine the L1 and L2 starting points to continue derivation from.
After this, the other stages are reset independent of each other.
#### Finding the sync starting point
To find the starting point, there are several steps, relative to the head of the chain traversing back:
1. Find the current L2 forkchoice state
- If no `finalized` block can be found, start at the Bedrock genesis block.
- If no `safe` block can be found, fallback to the `finalized` block.
- The `unsafe` block should always be available and consistent with the above
(it may not be in rare engine-corruption recovery cases, this is being reviewed).
2. Find the first L2 block with plausible L1 reference to be the new `unsafe` starting point,
starting from previous `unsafe`, back to `finalized` and no further.
- Plausible iff: the L1 origin of the L2 block is known and canonical, or unknown and has a block-number ahead of L1.
3. Find the first L2 block with an L1 reference older than the sequencing window, to be the new `safe` starting point,
starting at the above plausible `unsafe` head, back to `finalized` and no further.
- If at any point the L1 origin is known but not canonical, the `unsafe` head is revised to parent of the current.
- The highest L2 block with known canonical L1 origin is remembered as `highest`.
- If at any point the L1 origin in the block is corrupt w.r.t. derivation rules, then error. Corruption includes:
- Inconsistent L1 origin block number or parent-hash with parent L1 origin
- Inconsistent L1 sequence number (always changes to `0` for a L1 origin change, or increments by `1` if not)
- If the L1 origin of the L2 block `n` is older than the L1 origin of `highest` by more than a sequence window,
and `n.sequence_number == 0`, then the parent L2 block of `n` will be the `safe` starting point.
4. The `finalized` L2 block persists as the `finalized` starting point.
5. Find the first L2 block with an L1 reference older than the channel-timeout
- The L1 origin referenced by this block which we call `l2base` will be the `base` for the L2 pipeline derivation:
By starting here, the stages can buffer any necessary data, while dropping incomplete derivation outputs until
L1 traversal has caught up with the actual L2 safe head.
While traversing back the L2 chain, an implementation may sanity-check that the starting point is never set too far
back compared to the existing forkchoice state, to avoid an intensive reorg because of misconfiguration.
Implementers note: step 1-4 are known as `FindL2Heads`. Step 5 is currently part of the Engine Queue reset.
This may change to isolate the starting-point search from the bare reset logic.
#### Resetting derivation stages
1. L1 Traversal: start at L1 `base` as first block to be pulled by next stage.
2. L1 Retrieval: empty previous data, and fetch the `base` L1 data, or defer the fetching work to a later pipeline step.
3. Frame Queue: empty the queue.
4. Channel Bank: empty the channel bank.
5. Channel Reader: reset any batch decoding state.
6. Batch Queue: empty the batch queue, use `base` as initial L1 point of reference.
7. Payload Attributes Derivation: empty any batch/attributes state.
8. Engine Queue:
- Initialize L2 forkchoice state with syncing start point state. (`finalized`/`safe`/`unsafe`)
- Initialize the L1 point of reference of the stage to `base`.
- Require a forkchoice update as first task
- Reset any finality data
Where necessary, stages starting at `base` can initialize their system-config from data encoded in the `l2base` block.
#### About reorgs Post-Merge
Note that post-[merge], the depth of reorgs will be bounded by the [L1 finality delay][l1-finality]
(2 L1 beacon epochs, or approximately 13 minutes, unless more than 1/3 of the network consistently disagrees).
New L1 blocks may be finalized every L1 beacon epoch (approximately 6.4 minutes), and depending on these
finality-signals and batch-inclusion, the derived L2 chain will become irreversible as well.
Note that this form of finalization only affects inputs, and nodes can then subjectively say the chain is irreversible,
by reproducing the chain from these irreversible inputs and the set protocol rules and parameters.
This is however completely unrelated to the outputs posted on L1, which require a form of proof like a fault-proof or
zk-proof to finalize. Optimistic-rollup outputs like withdrawals on L1 are only labeled "finalized" after passing a week
without dispute (fault proof challenge window), a name-collision with the proof-of-stake finalization.
[merge]: https://ethereum.org/en/upgrades/merge/
[l1-finality]: https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/#finality
------------------------------------------------------------------------------------------------------------------------
# Deriving Payload Attributes
[deriving-payload-attr]: #deriving-payload-attributes
For every L2 block derived from L1 data, we need to build [payload attributes][g-payload-attr],
represented by an [expanded version][expanded-payload] of the [`PayloadAttributesV2`][eth-payload] object,
which includes additional `transactions` and `noTxPool` fields.
This process happens during the payloads-attributes queue ran by a verifier node, as well as during block-production
ran by a sequencer node (the sequencer may enable the tx-pool usage if the transactions are batch-submitted).
[expanded-payload]: exec-engine.md#extended-payloadattributesv1
[eth-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#payloadattributesv1
## Deriving the Transaction List
For each L2 block to be created by the sequencer, we start from a [sequencer batch][g-sequencer-batch] matching the
target L2 block number. This could potentially be an empty auto-generated batch, if the L1 chain did not include a batch
for the target L2 block number. [Remember][batch-format] that the batch includes a [sequencing
epoch][g-sequencing-epoch] number, an L2 timestamp, and a transaction list.
This block is part of a [sequencing epoch][g-sequencing-epoch],
whose number matches that of an L1 block (its *[L1 origin][g-l1-origin]*).
This L1 block is used to derive L1 attributes and (for the first L2 block in the epoch) user deposits.
Therefore, a [`PayloadAttributesV2`][expanded-payload] object must include the following transactions:
- one or more [deposited transactions][g-deposited], of two kinds:
- a single *[L1 attributes deposited transaction][g-l1-attr-deposit]*, derived from the L1 origin.
- for the first L2 block in the epoch, zero or more *[user-deposited transactions][g-user-deposited]*, derived from
the [receipts][g-receipts] of the L1 origin.
- zero or more [network upgrade automation transactions]: special transactions to perform network upgrades.
- zero or more *[sequenced transactions][g-sequencing]*: regular transactions signed by L2 users, included in the
sequencer batch.
Transactions **must** appear in this order in the payload attributes.
The L1 attributes are read from the L1 block header, while deposits are read from the L1 block's [receipts][g-receipts].
Refer to the [**deposit contract specification**][deposit-contract-spec] for details on how deposits are encoded as log
entries.
[deposit-contract-spec]: deposits.md#deposit-contract
### Network upgrade automation transactions
[network upgrade automation transactions]: #network-upgrade-automation-transactions
Some network upgrades require automated contract changes or deployments at specific blocks.
To automate these, without adding persistent changes to the execution-layer,
special transactions may be inserted as part of the derivation process.
#### Ecotone
The Ecotone hardfork activation block, contains the following transactions in this order:
- L1 Attributes Transaction, using the pre-Ecotone `setL1BlockValues`
- User deposits from L1
- Network Upgrade Transactions
- L1Block deployment
- GasPriceOracle deployment
- Update L1Block Proxy ERC-1967 Implementation Slot
- Update GasPriceOracle Proxy ERC-1967 Implementation Slot
- GasPriceOracle Enable Ecotone
- Beacon block roots contract deployment (EIP-4788)
To not modify or interrupt the system behavior around gas computation, this block will not include any sequenced
transactions by setting `noTxPool: true`.
##### L1Block Deployment
The `L1Block` contract is upgraded to process the new Ecotone L1-data-fee parameters and L1 blob base-fee.
A deposit transaction is derived with the following attributes:
- `from`: `0x4210000000000000000000000000000000000000`
- `to`: `null`
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `375,000`
- `data`: `0x60806040523480156100105...` ([full bytecode](./bytecode/ecotone-l1-block-deployment.txt))
- `sourceHash`: `0x877a6077205782ea15a6dc8699fa5ebcec5e0f4389f09cb8eda09488231346f8`,
computed with the "Upgrade-deposited" type, with `intent = "Ecotone: L1 Block Deployment"
This results in the Ecotone L1Block contract being deployed to `0x07dbe8500fc591d1852B76feE44d5a05e13097Ff`, to verify:
```bash
cast compute-address --nonce=0 0x4210000000000000000000000000000000000000
Computed Address: 0x07dbe8500fc591d1852B76feE44d5a05e13097Ff
```
Verify `sourceHash`:
```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: L1 Block Deployment"))
# 0x877a6077205782ea15a6dc8699fa5ebcec5e0f4389f09cb8eda09488231346f8
```
Verify `data`:
```bash
git checkout 5996d0bc1a4721f2169ba4366a014532f31ea932
pnpm clean && pnpm install && pnpm build
jq -r ".bytecode.object" packages/contracts-bedrock/forge-artifacts/L1Block.sol/L1Block.json
```
This transaction MUST deploy a contract with the following code hash
`0xc88a313aa75dc4fbf0b6850d9f9ae41e04243b7008cf3eadb29256d4a71c1dfd`.
##### GasPriceOracle Deployment
The `GasPriceOracle` contract is upgraded to support the new Ecotone L1-data-fee parameters. Post fork this contract
will use the blob base fee to compute the gas price for L1-data-fee transactions.
A deposit transaction is derived with the following attributes:
- `from`: `0x4210000000000000000000000000000000000001`
- `to`: `null`,
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `1,000,000`
- `data`: `0x60806040523480156100...` ([full bytecode](./bytecode/ecotone-gas-price-oracle-deployment.txt))
- `sourceHash`: `0xa312b4510adf943510f05fcc8f15f86995a5066bd83ce11384688ae20e6ecf42`
computed with the "Upgrade-deposited" type, with `intent = "Ecotone: Gas Price Oracle Deployment"
This results in the Ecotone GasPriceOracle contract being deployed to `0xb528D11cC114E026F138fE568744c6D45ce6Da7A`,
to verify:
```bash
cast compute-address --nonce=0 0x4210000000000000000000000000000000000001
Computed Address: 0xb528D11cC114E026F138fE568744c6D45ce6Da7A
```
Verify `sourceHash`:
```bash
❯ cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: Gas Price Oracle Deployment"))
# 0xa312b4510adf943510f05fcc8f15f86995a5066bd83ce11384688ae20e6ecf42
```
Verify `data`:
```bash
git checkout 5996d0bc1a4721f2169ba4366a014532f31ea932
pnpm clean && pnpm install && pnpm build
jq -r ".bytecode.object" packages/contracts-bedrock/forge-artifacts/GasPriceOracle.sol/GasPriceOracle.json
```
This transaction MUST deploy a contract with the following code hash
`0x8b71360ea773b4cfaf1ae6d2bd15464a4e1e2e360f786e475f63aeaed8da0ae5`.
##### L1Block Proxy Update
This transaction updates the L1Block Proxy ERC-1967 implementation slot to point to the new L1Block deployment.
A deposit transaction is derived with the following attributes:
- `from`: `0x0000000000000000000000000000000000000000`
- `to`: `0x4200000000000000000000000000000000000015` (L1Block Proxy)
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `50,000`
- `data`: `0x3659cfe600000000000000000000000007dbe8500fc591d1852b76fee44d5a05e13097ff`
- `sourceHash`: `0x18acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc`
computed with the "Upgrade-deposited" type, with `intent = "Ecotone: L1 Block Proxy Update"
Verify data:
```bash
cast concat-hex $(cast sig "upgradeTo(address)") $(cast abi-encode "upgradeTo(address)" 0x07dbe8500fc591d1852B76feE44d5a05e13097Ff)
0x3659cfe600000000000000000000000007dbe8500fc591d1852b76fee44d5a05e13097ff
```
Verify `sourceHash`:
```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: L1 Block Proxy Update"))
# 0x18acb38c5ff1c238a7460ebc1b421fa49ec4874bdf1e0a530d234104e5e67dbc
```
##### GasPriceOracle Proxy Update
This transaction updates the GasPriceOracle Proxy ERC-1967 implementation slot to point to the new GasPriceOracle
deployment.
A deposit transaction is derived with the following attributes:
- `from`: `0x0000000000000000000000000000000000000000`
- `to`: `0x420000000000000000000000000000000000000F` (Gas Price Oracle Proxy)
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `50,000`
- `data`: `0x3659cfe6000000000000000000000000b528d11cc114e026f138fe568744c6d45ce6da7a`
- `sourceHash`: `0xee4f9385eceef498af0be7ec5862229f426dec41c8d42397c7257a5117d9230a`
computed with the "Upgrade-deposited" type, with `intent = "Ecotone: Gas Price Oracle Proxy Update"`
Verify data:
```bash
cast concat-hex $(cast sig "upgradeTo(address)") $(cast abi-encode "upgradeTo(address)" 0xb528D11cC114E026F138fE568744c6D45ce6Da7A)
0x3659cfe6000000000000000000000000b528d11cc114e026f138fe568744c6d45ce6da7a
```
Verify `sourceHash`:
```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: Gas Price Oracle Proxy Update"))
# 0xee4f9385eceef498af0be7ec5862229f426dec41c8d42397c7257a5117d9230a
```
##### GasPriceOracle Enable Ecotone
This transaction informs the GasPriceOracle to start using the Ecotone gas calculation formula.
A deposit transaction is derived with the following attributes:
- `from`: `0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001` (Depositer Account)
- `to`: `0x420000000000000000000000000000000000000F` (Gas Price Oracle Proxy)
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `80,000`
- `data`: `0x22b90ab3`
- `sourceHash`: `0x0c1cb38e99dbc9cbfab3bb80863380b0905290b37eb3d6ab18dc01c1f3e75f93`,
computed with the "Upgrade-deposited" type, with `intent = "Ecotone: Gas Price Oracle Set Ecotone"
Verify data:
```bash
cast sig "setEcotone()"
0x22b90ab3
```
Verify `sourceHash`:
```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: Gas Price Oracle Set Ecotone"))
# 0x0c1cb38e99dbc9cbfab3bb80863380b0905290b37eb3d6ab18dc01c1f3e75f93
```
##### Beacon block roots contract deployment (EIP-4788)
[EIP-4788] introduces a "Beacon block roots" contract, that processes and exposes the beacon-block-root values.
at address `BEACON_ROOTS_ADDRESS = 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`.
For deployment, [EIP-4788] defines a pre-[EIP-155] legacy transaction, sent from a key that is derived such that the
transaction signature validity is bound to message-hash, which is bound to the input-data, containing the init-code.
However, this type of transaction requires manual deployment and gas-payments.
And since the processing is an integral part of the chain processing, and has to be repeated for every OP-Stack chain,
the deployment is approached differently here.
Some chains may already have a user-submitted instance of the [EIP-4788] transaction.
This is cryptographically guaranteed to be correct, but may result in the upgrade transaction
deploying a second contract, with the next nonce. The result of this deployment can be ignored.
A Deposit transaction is derived with the following attributes:
- `from`: `0x0B799C86a49DEeb90402691F1041aa3AF2d3C875`, as specified in the EIP.
- `to`: null
- `mint`: `0`
- `value`: `0`
- `gasLimit`: `0x3d090`, as specified in the EIP.
- `isCreation`: `true`
- `data`:
`0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500`
- `isSystemTx`: `false`, as per the Regolith upgrade, even the system-generated transactions spend gas.
- `sourceHash`: `0x69b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c`,
computed with the "Upgrade-deposited" type, with `intent = "Ecotone: beacon block roots contract deployment"`
The contract address upon deployment is computed as `rlp([sender, nonce])`, which will equal:
- `BEACON_ROOTS_ADDRESS` if deployed
- a different address (`0xE3aE1Ae551eeEda337c0BfF6C4c7cbA98dce353B`) if `nonce = 1`:
when a user already submitted the EIP transaction before the upgrade.
Verify `BEACON_ROOTS_ADDRESS`:
```bash
cast compute-address --nonce=0 0x0B799C86a49DEeb90402691F1041aa3AF2d3C875
# Computed Address: 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02
```
Verify `sourceHash`:
```bash
cast keccak $(cast concat-hex 0x0000000000000000000000000000000000000000000000000000000000000002 $(cast keccak "Ecotone: beacon block roots contract deployment"))
# 0x69b763c48478b9dc2f65ada09b3d92133ec592ea715ec65ad6e7f3dc519dc00c
```
[EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788
[EIP-155]: https://eips.ethereum.org/EIPS/eip-155
## Building Individual Payload Attributes
[payload attributes]: #building-individual-payload-attributes
After deriving the transactions list, the rollup node constructs a [`PayloadAttributesV2`][extended-attributes] as
follows:
- `timestamp` is set to the batch's timestamp.
- `random` is set to the `prev_randao` L1 block attribute.
- `suggestedFeeRecipient` is set to the Sequencer Fee Vault address. See [Fee Vaults] specification.
- `transactions` is the array of the derived transactions: deposited transactions and sequenced transactions, all
encoded with [EIP-2718].
- `noTxPool` is set to `true`, to use the exact above `transactions` list when constructing the block.
- `gasLimit` is set to the current `gasLimit` value in the [system configuration][g-system-config] of this payload.
- `withdrawals` is set to nil prior to Canyon and an empty array after Canyon
[extended-attributes]: exec-engine.md#extended-payloadattributesv1
[Fee Vaults]: exec-engine.md#fee-vaults
# Dispute Game Interface
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [Types](#types)
- [`DisputeGameFactory` Interface](#disputegamefactory-interface)
- [`DisputeGame` Interface](#disputegame-interface)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
A dispute game is played between multiple parties when contesting the truthiness
of a claim. In the context of an optimistic rollup, claims are made about the
state of the layer two network to enable withdrawals to the layer one. A proposer
makes a claim about the layer two state such that they can withdraw and a
challenger can dispute the validity of the claim. The security of the layer two
comes from the ability of fraudulent withdrawals being able to be disputed.
A dispute game interface is defined to allow for multiple implementations of
dispute games to exist. If multiple dispute games run in production, it gives
a similar security model as having multiple protocol clients, as a bug in a
single dispute game will not result in the bug becoming consensus.
## Types
For added context, we define a few types that are used in the following snippets.
```solidity
/// @notice A `Claim` type represents a 32 byte hash or other unique identifier for a claim about
/// a certain piece of information.
type Claim is bytes32;
/// @notice A custom type for a generic hash.
type Hash is bytes32;
/// @notice A dedicated timestamp type.
type Timestamp is uint64;
/// @notice A `GameType` represents the type of game being played.
type GameType is uint8;
/// @title GameTypes
/// @notice A library that defines the IDs of games that can be played.
library GameTypes {
/// @dev A dispute game type the uses the cannon vm.
GameType internal constant CANNON = GameType.wrap(0);
/// @dev A dispute game type that performs output bisection and then uses the cannon vm.
GameType internal constant OUTPUT_CANNON = GameType.wrap(1);
/// @notice A dispute game type that performs output bisection and then uses an alphabet vm.
/// Not intended for production use.
GameType internal constant OUTPUT_ALPHABET = GameType.wrap(254);
/// @notice A dispute game type that uses an alphabet vm.
/// Not intended for production use.
GameType internal constant ALPHABET = GameType.wrap(255);
}
/// @notice The current status of the dispute game.
enum GameStatus {
/// @dev The game is currently in progress, and has not been resolved.
IN_PROGRESS,
/// @dev The game has concluded, and the `rootClaim` was challenged successfully.
CHALLENGER_WINS,
/// @dev The game has concluded, and the `rootClaim` could not be contested.
DEFENDER_WINS
}
```
## `DisputeGameFactory` Interface
The dispute game factory is responsible for creating new `DisputeGame` contracts
given a `GameType` and a root `Claim`. Challenger agents listen to the `DisputeGameCreated` events in order to
keep up with on-going disputes in the protocol and participate accordingly.
A [`clones-with-immutable-args`](https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args) factory
(originally by @wighawag, but forked by @Saw-mon-and-Natalie) is used to create Clones. Each `GameType` has
a corresponding implementation within the factory, and when a new game is created, the factory creates a
clone of the `GameType`'s pre-deployed implementation contract.
The `rootClaim` of created dispute games can either be a claim that the creator agrees or disagrees with.
This is an implementation detail that is left up to the `IDisputeGame` to handle within its `resolve` function.
When the `DisputeGameFactory` creates a new `DisputeGame` contract, it calls `initialize()` on the clone to
set up the game.
```solidity
/// @title IDisputeGameFactory
/// @notice The interface for a DisputeGameFactory contract.
interface IDisputeGameFactory {
/// @notice Emitted when a new dispute game is created
/// @param disputeProxy The address of the dispute game proxy
/// @param gameType The type of the dispute game proxy's implementation
/// @param rootClaim The root claim of the dispute game
event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);
/// @notice Emitted when a new game implementation added to the factory
/// @param impl The implementation contract for the given `GameType`.
/// @param gameType The type of the DisputeGame.
event ImplementationSet(address indexed impl, GameType indexed gameType);
/// @notice Emitted when a game type's initialization bond is updated
/// @param gameType The type of the DisputeGame.
/// @param newBond The new bond (in wei) for initializing the game type.
event InitBondUpdated(GameType indexed gameType, uint256 indexed newBond);
/// @notice The total number of dispute games created by this factory.
/// @return gameCount_ The total number of dispute games created by this factory.
function gameCount() external view returns (uint256 gameCount_);
/// @notice `games` queries an internal mapping that maps the hash of
/// `gameType ++ rootClaim ++ extraData` to the deployed `DisputeGame` clone.
/// @dev `++` equates to concatenation.
/// @param _gameType The type of the DisputeGame - used to decide the proxy implementation
/// @param _rootClaim The root claim of the DisputeGame.
/// @param _extraData Any extra data that should be provided to the created dispute game.
/// @return proxy_ The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent.
/// @return timestamp_ The timestamp of the creation of the dispute game.
function games(
GameType _gameType,
Claim _rootClaim,
bytes calldata _extraData
)
external
view
returns (IDisputeGame proxy_, Timestamp timestamp_);
/// @notice `gameAtIndex` returns the dispute game contract address and its creation timestamp
/// at the given index. Each created dispute game increments the underlying index.
/// @param _index The index of the dispute game.
/// @return gameType_ The type of the DisputeGame - used to decide the proxy implementation.
/// @return timestamp_ The timestamp of the creation of the dispute game.
/// @return proxy_ The clone of the `DisputeGame` created with the given parameters.
/// Returns `address(0)` if nonexistent.
function gameAtIndex(uint256 _index)
external
view
returns (GameType gameType_, Timestamp timestamp_, IDisputeGame proxy_);
/// @notice `gameImpls` is a mapping that maps `GameType`s to their respective
/// `IDisputeGame` implementations.
/// @param _gameType The type of the dispute game.
/// @return impl_ The address of the implementation of the game type.
/// Will be cloned on creation of a new dispute game with the given `gameType`.
function gameImpls(GameType _gameType) external view returns (IDisputeGame impl_);
/// @notice Returns the required bonds for initializing a dispute game of the given type.
/// @param _gameType The type of the dispute game.
/// @return bond_ The required bond for initializing a dispute game of the given type.
function initBonds(GameType _gameType) external view returns (uint256 bond_);
/// @notice Creates a new DisputeGame proxy contract.
/// @param _gameType The type of the DisputeGame - used to decide the proxy implementation.
/// @param _rootClaim The root claim of the DisputeGame.
/// @param _extraData Any extra data that should be provided to the created dispute game.
/// @return proxy_ The address of the created DisputeGame proxy.
function create(
GameType _gameType,
Claim _rootClaim,
bytes calldata _extraData
)
external
payable
returns (IDisputeGame proxy_);
/// @notice Sets the implementation contract for a specific `GameType`.
/// @dev May only be called by the `owner`.
/// @param _gameType The type of the DisputeGame.
/// @param _impl The implementation contract for the given `GameType`.
function setImplementation(GameType _gameType, IDisputeGame _impl) external;
/// @notice Sets the bond (in wei) for initializing a game type.
/// @dev May only be called by the `owner`.
/// @param _gameType The type of the DisputeGame.
/// @param _initBond The bond (in wei) for initializing a game type.
function setInitBond(GameType _gameType, uint256 _initBond) external;
/// @notice Returns a unique identifier for the given dispute game parameters.
/// @dev Hashes the concatenation of `gameType . rootClaim . extraData`
/// without expanding memory.
/// @param _gameType The type of the DisputeGame.
/// @param _rootClaim The root claim of the DisputeGame.
/// @param _extraData Any extra data that should be provided to the created dispute game.
/// @return uuid_ The unique identifier for the given dispute game parameters.
function getGameUUID(
GameType _gameType,
Claim _rootClaim,
bytes memory _extraData
)
external
pure
returns (Hash uuid_);
}
```
## `DisputeGame` Interface
The dispute game interface defines a generic, black-box dispute. It exposes stateful information such as the status of
the dispute, when it was created, as well as the bootstrap data and dispute type. This interface exposes one state
mutating function, `resolve`, which when implemented should deterministically yield an opinion about the `rootClaim`
and reflect the opinion by updating the `status` to `CHALLENGER_WINS` or `DEFENDER_WINS`.
Clones of the `IDisputeGame`'s `initialize` functions will be called by the `DisputeGameFactory` atomically upon
creation.
```solidity
/// @title IDisputeGame
/// @notice The generic interface for a DisputeGame contract.
interface IDisputeGame is IInitializable {
/// @notice Emitted when the game is resolved.
/// @param status The status of the game after resolution.
event Resolved(GameStatus indexed status);
/// @notice Returns the timestamp that the DisputeGame contract was created at.
/// @return createdAt_ The timestamp that the DisputeGame contract was created at.
function createdAt() external view returns (Timestamp createdAt_);
/// @notice Returns the current status of the game.
/// @return status_ The current status of the game.
function status() external view returns (GameStatus status_);
/// @notice Getter for the game type.
/// @dev The reference impl should be entirely different depending on the type (fault, validity)
/// i.e. The game type should indicate the security model.
/// @return gameType_ The type of proof system being used.
function gameType() external view returns (GameType gameType_);
/// @notice Getter for the root claim.
/// @dev `clones-with-immutable-args` argument #1
/// @return rootClaim_ The root claim of the DisputeGame.
function rootClaim() external pure returns (Claim rootClaim_);
/// @notice Getter for the extra data.
/// @dev `clones-with-immutable-args` argument #2
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
function extraData() external pure returns (bytes memory extraData_);
/// @notice If all necessary information has been gathered, this function should mark the game
/// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of
/// the resolved game. It is at this stage that the bonds should be awarded to the
/// necessary parties.
/// @dev May only be called if the `status` is `IN_PROGRESS`.
/// @return status_ The status of the game after resolution.
function resolve() external returns (GameStatus status_);
/// @notice A compliant implementation of this interface should return the components of the
/// game UUID's preimage provided in the cwia payload. The preimage of the UUID is
/// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes
/// concatenation.
/// @return gameType_ The type of proof system being used.
/// @return rootClaim_ The root claim of the DisputeGame.
/// @return extraData_ Any extra data supplied to the dispute game contract by the creator.
function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_);
}
```
# L2 Execution Engine
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [1559 Parameters](#1559-parameters)
- [Deposited transaction processing](#deposited-transaction-processing)
- [Deposited transaction boundaries](#deposited-transaction-boundaries)
- [Fees](#fees)
- [Fee Vaults](#fee-vaults)
- [Priority fees (Sequencer Fee Vault)](#priority-fees-sequencer-fee-vault)
- [Base fees (Base Fee Vault)](#base-fees-base-fee-vault)
- [L1-Cost fees (L1 Fee Vault)](#l1-cost-fees-l1-fee-vault)
- [Pre-Ecotone](#pre-ecotone)
- [Ecotone L1-Cost fee changes (EIP-4844 DA)](#ecotone-l1-cost-fee-changes-eip-4844-da)
- [Engine API](#engine-api)
- [`engine_forkchoiceUpdatedV2`](#engine_forkchoiceupdatedv2)
- [Extended PayloadAttributesV2](#extended-payloadattributesv2)
- [`engine_forkchoiceUpdatedV3`](#engine_forkchoiceupdatedv3)
- [Extended PayloadAttributesV3](#extended-payloadattributesv3)
- [`engine_newPayloadV2`](#engine_newpayloadv2)
- [`engine_newPayloadV3`](#engine_newpayloadv3)
- [`engine_getPayloadV2`](#engine_getpayloadv2)
- [`engine_getPayloadV3`](#engine_getpayloadv3)
- [Extended Response](#extended-response)
- [`engine_signalSuperchainV1`](#engine_signalsuperchainv1)
- [Networking](#networking)
- [Sync](#sync)
- [Happy-path sync](#happy-path-sync)
- [Worst-case sync](#worst-case-sync)
- [Ecotone: disable Blob-transactions](#ecotone-disable-blob-transactions)
- [Ecotone: Beacon Block Root](#ecotone-beacon-block-root)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
This document outlines the modifications, configuration and usage of a L1 execution engine for L2.
## 1559 Parameters
The execution engine must be able to take a per chain configuration which specifies the EIP-1559 Denominator
and EIP-1559 elasticity. After Canyon it should also take a new value `EIP1559DenominatorCanyon` and use that as
the denominator in the 1559 formula rather than the prior denominator.
The formula for EIP-1559 is not otherwise modified.
## Deposited transaction processing
The Engine interfaces abstract away transaction types with [EIP-2718][eip-2718].
To support rollup functionality, processing of a new Deposit [`TransactionType`][eip-2718-transactions]
is implemented by the engine, see the [deposits specification][deposit-spec].
This type of transaction can mint L2 ETH, run EVM,
and introduce L1 information to enshrined contracts in the execution state.
[deposit-spec]: deposits.md
### Deposited transaction boundaries
Transactions cannot be blindly trusted, trust is established through authentication.
Unlike other transaction types deposits are not authenticated by a signature:
the rollup node authenticates them, outside of the engine.
To process deposited transactions safely, the deposits MUST be authenticated first:
- Ingest directly through trusted Engine API
- Part of sync towards a trusted block hash (trusted through previous Engine API instruction)
Deposited transactions MUST never be consumed from the transaction pool.
*The transaction pool can be disabled in a deposits-only rollup*
## Fees
Sequenced transactions (i.e. not applicable to deposits) are charged with 3 types of fees:
priority fees, base fees, and L1-cost fees.
### Fee Vaults
The three types of fees are collected in 3 distinct L2 fee-vault deployments for accounting purposes:
fee payments are not registered as internal EVM calls, and thus distinguished better this way.
These are hardcoded addresses, pointing at pre-deployed proxy contracts.
The proxies are backed by vault contract deployments, based on `FeeVault`, to route vault funds to L1 securely.
| Vault Name | Predeploy |
|---------------------|----------------------------------------------------------|
| Sequencer Fee Vault | [`SequencerFeeVault`](./predeploys.md#SequencerFeeVault) |
| Base Fee Vault | [`BaseFeeVault`](./predeploys.md#BaseFeeVault) |
| L1 Fee Vault | [`L1FeeVault`](./predeploys.md#L1FeeVault) |
### Priority fees (Sequencer Fee Vault)
Priority fees follow the [eip-1559] specification, and are collected by the fee-recipient of the L2 block.
The block fee-recipient (a.k.a. coinbase address) is set to the Sequencer Fee Vault address.
### Base fees (Base Fee Vault)
Base fees largely follow the [eip-1559] specification, with the exception that base fees are not burned,
but add up to the Base Fee Vault ETH account balance.
### L1-Cost fees (L1 Fee Vault)
The protocol funds batch-submission of sequenced L2 transactions by charging L2 users an additional fee
based on the estimated batch-submission costs.
This fee is charged from the L2 transaction-sender ETH balance, and collected into the L1 Fee Vault.
The exact L1 cost function to determine the L1-cost fee component of a L2 transaction depends on
the upgrades that are active.
#### Pre-Ecotone
Before Ecotone activation, L1 cost is calculated as:
`(rollupDataGas + l1FeeOverhead) * l1BaseFee * l1FeeScalar / 1e6` (big-int computation, result
in Wei and `uint256` range)
Where:
- `rollupDataGas` is determined from the *full* encoded transaction
(standard EIP-2718 transaction encoding, including signature fields):
- Before Regolith fork: `rollupDataGas = zeroes * 4 + (ones + 68) * 16`
- The addition of `68` non-zero bytes is a remnant of a pre-Bedrock L1-cost accounting function,
which accounted for the worst-case non-zero bytes addition to complement unsigned transactions, unlike Bedrock.
- With Regolith fork: `rollupDataGas = zeroes * 4 + ones * 16`
- `l1FeeOverhead` is the Gas Price Oracle `overhead` value.
- `l1FeeScalar` is the Gas Price Oracle `scalar` value.
- `l1BaseFee` is the L1 base fee of the latest L1 origin registered in the L2 chain.
Note that the `rollupDataGas` uses the same byte cost accounting as defined in [eip-2028],
except the full L2 transaction now counts towards the bytes charged in the L1 calldata.
This behavior matches pre-Bedrock L1-cost estimation of L2 transactions.
Compression, batching, and intrinsic gas costs of the batch transactions are accounted for by the protocol
with the Gas Price Oracle `overhead` and `scalar` parameters.
The Gas Price Oracle `l1FeeOverhead` and `l1FeeScalar`, as well as the `l1BaseFee` of the L1 origin,
can be accessed in two interchangeable ways:
- read from the deposited L1 attributes (`l1FeeOverhead`, `l1FeeScalar`, `basefee`) of the current L2 block
- read from the L1 Block Info contract (`0x4200000000000000000000000000000000000015`)
- using the respective solidity `uint256`-getter functions (`l1FeeOverhead`, `l1FeeScalar`, `basefee`)
- using direct storage-reads:
- L1 basefee as big-endian `uint256` in slot `1`
- Overhead as big-endian `uint256` in slot `5`
- Scalar as big-endian `uint256` in slot `6`
#### Ecotone L1-Cost fee changes (EIP-4844 DA)
Ecotone allows posting batches via Blobs which are subject to a new fee market. To account for this feature,
L1 cost is computed as:
`(zeroes*4 + ones*16) * (16*l1BaseFee*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 16e6`
Where:
- the computation is an unlimited precision integer computation, with the result in Wei and having
`uint256` range.
- zeoroes and ones are the count of zero and non-zero bytes respectively in the *full* encoded
signed transaction.
- `l1BaseFee` is the L1 base fee of the latest L1 origin registered in the L2 chain.
- `l1BlobBaseFee` is the blob gas price, computed as described in [EIP-4844][4844-gas] from the
header of the latest registered L1 origin block.
Conceptually what the above function captures is the formula below, where `compressedTxSize =
(zeroes*4 + ones*16) / 16` can be thought of as a rough approximation of how many bytes the
transaction occupies in a compressed batch.
`(compressedTxSize) * (16*l1BaseFee*lBaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar) / 1e6`
The precise cost function used by Ecotone at the top of this section preserves precision under
integer arithmetic by postponing the inner division by 16 until the very end.
[4844-gas]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4844.md#gas-accounting
The two base fee values and their respective scalars can be accessed in two interchangeable ways:
- read from the deposited L1 attributes (`l1BaseFeeScalar`, `l1BlobBaseFeeScalar`, `basefee`,
`blobBaseFee`) of the current L2 block
- read from the L1 Block Info contract (`0x4200000000000000000000000000000000000015`)
- using the respective solidity getter functions
- using direct storage-reads:
- basefee `uint256` in slot `1`
- blobBaseFee `uint256` in slot `7`
- l1BaseFeeScalar big-endian `uint32` slot `3` at offset `12`
- l1BlobBaseFeeScalar big-endian `uint32` in slot `3` at offset `8`
## Engine API
### `engine_forkchoiceUpdatedV2`
This updates which L2 blocks the engine considers to be canonical (`forkchoiceState` argument),
and optionally initiates block production (`payloadAttributes` argument).
Within the rollup, the types of forkchoice updates translate as:
- `headBlockHash`: block hash of the head of the canonical chain. Labeled `"unsafe"` in user JSON-RPC.
Nodes may apply L2 blocks out of band ahead of time, and then reorg when L1 data conflicts.
- `safeBlockHash`: block hash of the canonical chain, derived from L1 data, unlikely to reorg.
- `finalizedBlockHash`: irreversible block hash, matches lower boundary of the dispute period.
To support rollup functionality, one backwards-compatible change is introduced
to [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2]: the extended `PayloadAttributesV2`
#### Extended PayloadAttributesV2
[`PayloadAttributesV2`][PayloadAttributesV2] is extended to:
```js
PayloadAttributesV2: {
timestamp: QUANTITY
random: DATA (32 bytes)
suggestedFeeRecipient: DATA (20 bytes)
withdrawals: array of WithdrawalV1
transactions: array of DATA
noTxPool: bool
gasLimit: QUANTITY or null
}
```
The type notation used here refers to the [HEX value encoding] used by the [Ethereum JSON-RPC API
specification][JSON-RPC-API], as this structure will need to be sent over JSON-RPC. `array` refers
to a JSON array.
Each item of the `transactions` array is a byte list encoding a transaction: `TransactionType ||
TransactionPayload` or `LegacyTransaction`, as defined in [EIP-2718][eip-2718].
This is equivalent to the `transactions` field in [`ExecutionPayloadV2`][ExecutionPayloadV2]
The `transactions` field is optional:
- If empty or missing: no changes to engine behavior. The sequencers will (if enabled) build a block
by consuming transactions from the transaction pool.
- If present and non-empty: the payload MUST be produced starting with this exact list of transactions.
The [rollup driver][rollup-driver] determines the transaction list based on deterministic L1 inputs.
The `noTxPool` is optional as well, and extends the `transactions` meaning:
- If `false`, the execution engine is free to pack additional transactions from external sources like the tx pool
into the payload, after any of the `transactions`. This is the default behavior a L1 node implements.
- If `true`, the execution engine must not change anything about the given list of `transactions`.
If the `transactions` field is present, the engine must execute the transactions in order and return `STATUS_INVALID`
if there is an error processing the transactions. It must return `STATUS_VALID` if all of the transactions could
be executed without error. **Note**: The state transition rules have been modified such that deposits will never fail
so if `engine_forkchoiceUpdatedV2` returns `STATUS_INVALID` it is because a batched transaction is invalid.
The `gasLimit` is optional w.r.t. compatibility with L1, but required when used as rollup.
This field overrides the gas limit used during block-building.
If not specified as rollup, a `STATUS_INVALID` is returned.
[rollup-driver]: rollup-node.md
### `engine_forkchoiceUpdatedV3`
See [`engine_forkchoiceUpdatedV2`](#engine_forkchoiceUpdatedV2) for a description of the forkchoice updated method.
To support rollup functionality, one backwards-compatible change is introduced
to [`engine_forkchoiceUpdatedV3`][engine_forkchoiceUpdatedV3]: the extended `PayloadAttributesV3`
#### Extended PayloadAttributesV3
[`PayloadAttributesV3`][PayloadAttributesV3] is extended to:
```js
PayloadAttributesV3: {
timestamp: QUANTITY
random: DATA (32 bytes)
suggestedFeeRecipient: DATA (20 bytes)
withdrawals: array of WithdrawalV1
parentBeaconBlockRoot: DATA (32 bytes)
transactions: array of DATA
noTxPool: bool
gasLimit: QUANTITY or null
}
```
The requirements of this object are the same as extended [`PayloadAttributesV2`][#extended-payloadattributesv2] with
the addition of `parentBeaconBlockRoot` which is the parent beacon block root from the L1 origin block of the L2 block.
The `parentBeaconBlockRoot` must be nil for Bedrock/Canyon/Delta payloads.
Starting at Ecotone, the `parentBeaconBlockRoot` must be set to the L1 origin `parentBeaconBlockRoot`,
or a zero `bytes32` if the Dencun functionality with `parentBeaconBlockRoot` is not active on L1.
### `engine_newPayloadV2`
No modifications to [`engine_newPayloadV2`][engine_newPayloadV2].
Applies a L2 block to the engine state.
### `engine_newPayloadV3`
[`engine_newPayloadV3`][engine_newPayloadV3] applies an Ecotone L2 block to the engine state. There are no
modifications to this API. The additional parameters should be set as follows:
- `expectedBlobVersionedHashes` MUST be an empty array.
- `parentBeaconBlockRoot` MUST be the parent beacon block root from the L1 origin block of the L2 block.
### `engine_getPayloadV2`
No modifications to [`engine_getPayloadV2`][engine_getPayloadV2].
Retrieves a payload by ID, prepared by `engine_forkchoiceUpdatedV2` when called with `payloadAttributes`.
### `engine_getPayloadV3`
[`engine_getPayloadV3`][engine_getPayloadV3] retrieves a payload by ID, prepared by `engine_forkchoiceUpdatedV3`
when called with `payloadAttributes`.
#### Extended Response
The [response][GetPayloadV3Response] is extended to:
```js
{
executionPayload: ExecutionPayload
blockValue: QUANTITY
blobsBundle: BlobsBundle
shouldOverrideBuilder: BOOLEAN
parentBeaconBlockRoot: DATA (32 bytes)
}
```
[GetPayloadV3Response]: https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#response-2
For Bedrock and Canyon `parentBeaconBlockRoot` MUST be nil and in Ecotone it MUST be set to the parentBeaconBlockRoot
from the L1 Origin block of the L2 block.
### `engine_signalSuperchainV1`
Optional extension to the Engine API. Signals superchain information to the Engine:
V1 signals which protocol version is recommended and required.
Types:
```javascript
SuperchainSignal: {
recommended: ProtocolVersion
required: ProtocolVersion
}
```
`ProtocolVersion`: encoded for RPC as defined in
[Protocol Version format specification](./superchain-upgrades.md#protocol-version-format).
Parameters:
- `signal`: `SuperchainSignal`, the signaled superchain information.
Returns:
- `ProtocolVersion`: the latest supported OP-Stack protocol version of the execution engine.
The execution engine SHOULD warn the user when the recommended version is newer than
the current version supported by the execution engine.
The execution engine SHOULD take safety precautions if it does not meet the required protocol version.
This may include halting the engine, with consent of the execution engine operator.
## Networking
The execution engine can acquire all data through the rollup node, as derived from L1:
*P2P networking is strictly optional.*
However, to not bottleneck on L1 data retrieval speed, the P2P network functionality SHOULD be enabled, serving:
- Peer discovery ([Disc v5][discv5])
- [`eth/66`][eth66]:
- Transaction pool (consumed by sequencer nodes)
- State sync (happy-path for fast trustless db replication)
- Historical block header and body retrieval
- *New blocks are acquired through the consensus layer instead (rollup node)*
No modifications to L1 network functionality are required, except configuration:
- [`networkID`][network-id]: Distinguishes the L2 network from L1 and testnets.
Equal to the [`chainID`][chain-id] of the rollup network.
- Activate Merge fork: Enables Engine API and disables propagation of blocks,
as block headers cannot be authenticated without consensus layer.
- Bootnode list: DiscV5 is a shared network,
[bootstrap][discv5-rationale] is faster through connecting with L2 nodes first.
[discv5]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md
[eth66]: https://github.com/ethereum/devp2p/blob/master/caps/eth.md
[network-id]: https://github.com/ethereum/devp2p/blob/master/caps/eth.md#status-0x00
[chain-id]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
[discv5-rationale]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5-rationale.md
## Sync
The execution engine can operate sync in different ways:
- Happy-path: rollup node informs engine of the desired chain head as determined by L1, completes through engine P2P.
- Worst-case: rollup node detects stalled engine, completes sync purely from L1 data, no peers required.
The happy-path is more suitable to bring new nodes online quickly,
as the engine implementation can sync state faster through methods like [snap-sync][snap-sync].
[snap-sync]: https://github.com/ethereum/devp2p/blob/master/caps/snap.md
### Happy-path sync
1. The rollup node informs the engine of the L2 chain head, unconditionally (part of regular node operation):
- Bedrock / Canyon / Delta Payloads
- [`engine_newPayloadV2`][engine_newPayloadV2] is called with latest L2 block received from P2P.
- [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2] is called with the current
`unsafe`/`safe`/`finalized` L2 block hashes.
- Ecotone Payloads
- [`engine_newPayloadV3`][engine_newPayloadV3] is called with latest L2 block received from P2P.
- [`engine_forkchoiceUpdatedV3`][engine_forkchoiceUpdatedV3] is called with the current
`unsafe`/`safe`/`finalized` L2 block hashes.
2. The engine requests headers from peers, in reverse till the parent hash matches the local chain
3. The engine catches up:
a) A form of state sync is activated towards the finalized or head block hash
b) A form of block sync pulls block bodies and processes towards head block hash
The exact P2P based sync is out of scope for the L2 specification:
the operation within the engine is the exact same as with L1 (although with an EVM that supports deposits).
### Worst-case sync
1. Engine is out of sync, not peered and/or stalled due other reasons.
2. The rollup node maintains latest head from engine (poll `eth_getBlockByNumber` and/or maintain a header subscription)
3. The rollup node activates sync if the engine is out of sync but not syncing through P2P (`eth_syncing`)
4. The rollup node inserts blocks, derived from L1, one by one, potentially adapting to L1 reorg(s),
as outlined in the [rollup node spec].
[rollup node spec]: rollup-node.md
## Ecotone: disable Blob-transactions
[EIP-4844] introduces Blob transactions: featuring all the functionality of an [EIP-1559] transaction,
plus a list of "blobs": "Binary Large Object", i.e. a dedicated data type for serving Data-Availability as base-layer.
With the Ecotone upgrade, all Cancun L1 execution features are enabled, with [EIP-4844] as exception:
as a L2, the OP-Stack does not serve blobs, and thus disables this new transaction type.
EIP-4844 is disabled as following:
- Transaction network-layer announcements, announcing blob-type transactions, are ignored.
- Transactions of the blob-type, through the RPC or otherwise, are not allowed into the transaction pool.
- Block-building code does not select EIP-4844 transactions.
- An L2 block state-transition with EIP-4844 transactions is invalid.
The [BLOBBASEFEE opcode](https://eips.ethereum.org/EIPS/eip-7516) is present but its semantics are
altered because there are no blobs processed by L2. The opcode will always push a value of 1 onto
the stack.
## Ecotone: Beacon Block Root
[EIP-4788] introduces a "beacon block root" into the execution-layer block-header and EVM.
This block root is an [SSZ hash-tree-root] of the consensus-layer contents of the previous consensus block.
With the adoption of [EIP-4399] in the Bedrock upgrade the OP-Stack already includes the `PREVRANDAO` of L1.
And thus with [EIP-4788] the L1 beacon block root is made available.
For the Ecotone upgrade, this entails that:
- The `parent_beacon_block_root` of the L1 origin is now embedded in the L2 block header.
- The "Beacon roots contract" is deployed at Ecotone upgrade-time, or embedded at genesis if activated at genesis.
- The block state-transition process now includes the same special beacon-block-root EVM processing as L1 ethereum.
[SSZ hash-tree-root]: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#merkleization
[EIP-4399]: https://eips.ethereum.org/EIPS/eip-4399
[EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788
[EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
[eip-1559]: https://eips.ethereum.org/EIPS/eip-1559
[eip-2028]: https://eips.ethereum.org/EIPS/eip-2028
[eip-2718]: https://eips.ethereum.org/EIPS/eip-2718
[eip-2718-transactions]: https://eips.ethereum.org/EIPS/eip-2718#transactions
[exec-api-data]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#structures
[l1-api-spec]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md
[PayloadAttributesV3]: https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#payloadattributesv3
[PayloadAttributesV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#PayloadAttributesV2
[ExecutionPayloadV1]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#ExecutionPayloadV1
[engine_forkchoiceUpdatedV3]: https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#engine_forkchoiceupdatedv3
[engine_forkchoiceUpdatedV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_forkchoiceupdatedv2
[engine_newPayloadV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2
[engine_newPayloadV3]: https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#engine_newpayloadv3
[engine_getPayloadV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_getpayloadv2
[engine_getPayloadV3]: https://github.com/ethereum/execution-apis/blob/a0d03086564ab1838b462befbc083f873dcf0c0f/src/engine/cancun.md#engine_getpayloadv3
[HEX value encoding]: https://eth.wiki/json-rpc/API#hex-value-encoding
[JSON-RPC-API]: https://github.com/ethereum/execution-apis
# Fault Dispute Game
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [Definitions](#definitions)
- [Virtual Machine (VM)](#virtual-machine-vm)
- [PreimageOracle](#preimageoracle)
- [Execution Trace](#execution-trace)
- [Claims](#claims)
- [DAG](#dag)
- [Subgame](#subgame)
- [Game Tree](#game-tree)
- [Position](#position)
- [GAME_DURATION](#game_duration)
- [Game Mechanics](#game-mechanics)
- [Actors](#actors)
- [Moves](#moves)
- [Attack](#attack)
- [Defend](#defend)
- [Step](#step)
- [Step Types](#step-types)
- [PreimageOracle Interaction](#preimageoracle-interaction)
- [Team Dynamics](#team-dynamics)
- [Game Clock](#game-clock)
- [Resolution](#resolution)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- Glossary References -->
[g-output-root]: glossary.md#L2-output-root
## Overview
The Fault Dispute Game (FDG) is a specific type of [dispute game](./dispute-game-interface.md) that verifies the
validity of a root claim by iteratively bisecting over [output roots][g-output-root] and execution traces of single
block state transitions down to a single instruction step. It relies on a Virtual Machine (VM) to falsify invalid
claims made at a single instruction step.
Actors, i.e. Players, interact with the game by making claims that dispute other claims in the FDG.
Each claim made narrows the range over the entire historical state of L2, until the source of dispute is a single
state transition. Once a time limit is reached, the dispute game is _resolved_, based on claims made that are disputed
and which aren't, to determine the winners of the game.
## Definitions
### Virtual Machine (VM)
This is a state transition function (STF) that takes a _pre-state_ and computes the post-state.
The VM may access data referenced during the STF and as such, it also accepts a _proof_ of this data.
Typically, the pre-state contains a commitment to the _proof_ to verify the integrity of the data referenced.
Mathematically, we define the STF as $VM(S_i,P_i)$ where
- $S_i$ is the pre-state
- $P_i$ is an optional proof needed for the transition from $S_i$ to $S_{i+1}$.
### PreimageOracle
This is a pre-image data store. It is often used by VMs to read external data during its STF.
Before successfully executing a VM STF, it may be necessary to preload the PreimageOracle with pertinent data.
The method for key-based retrieval of these pre-images varies according to the specific VM.
### Execution Trace
An execution trace $T$ is a sequence $(S_0,S_1,S_2,...,S_n)$ where each $S_i$ is a VM state and
for each $i$, $0 \le i \lt n$, $S_{n+1} = VM(S_i, P_i)$.
Every execution trace has a unique starting state, $S_0$, that's preset to a FDG implementation.
We refer to this state as the **ABSOLUTE_PRESTATE**.
### Claims
Claims assert an [output root][g-output-root] or the state of the FPVM at a given instruction. This is represented as
`ClaimHash`, a `bytes32` representing either an [output root][g-output-root] or a commitment to the last VM state in a
trace. A FDG is initialized with an output root that corresponds to the state of L2 at a given L2 block number, and
execution trace subgames at `SPLIT_DEPTH + 1` are initialized with a claim that commits to the entire execution trace
between two consecutive output roots (a block `n -> n+1` state transition). As we'll see later, there can be multiple
claims, committing to different output roots and FPVM states in the FDG.
### DAG
A Directed Acyclic Graph $G = (V,E)$ representing the relationship between claims, where:
- $V$ is the set of nodes, each representing a claim. Formally, $V = \{C_1,C_2,...,C_n\}$,
where $C_i$ is a claim.
- $E$ is the set of _directed_ edges. An edge $(C_i,C_j)$ exists if $C_j$ is a direct dispute
against $C_i$ through either an "Attack" or "Defend" [move](#moves).
### Subgame
A sub-game is a DAG of depth 1, where the root of the DAG is a `Claim` and the children are `Claim`s that counter the
root. A good mental model around this structure is that it is a fundamental dispute between two parties over a single
piece of information. These subgames are chained together such that a child within a subgame is the root of its own
subgame, which is visualized in the [resolution](#resolution) section. There are two types of sub-games in the fault
dispute game:
1. Output Roots
1. Execution Trace Commitments
At and above the split depth, all subgame roots correspond to [output roots][g-output-root], or commitments to the full
state of L2 at a given L2 block number. Below the split depth, subgame roots correspond to commitments to the fault
proof VM's state at a given instruction step.
### Game Tree
The Game Tree is a binary tree of positions. Every claim in the DAG references a position in the Game Tree.
The Game Tree has a split depth and maximum depth, `SPLIT_DEPTH` and `MAX_GAME_DEPTH` respectively, that are both
preset to an FDG implementation. The split depth defines the maximum depth at which claims about
[output roots][g-output-root] can occur, and below it, execution trace bisection occurs. Thus, the Game Tree contains
$2^{d-1}$ positions, where $d$ is the `MAX_GAME_DEPTH` (unless $d=0$, in which case there's only 1 position).
The full game tree, with a layer of the tree allocated to output bisection, and sub-trees after an arbitrary split
depth, looks like:
![ob-tree](./assets/ob-tree.png)
### Position
A position represents the location of a claim in the Game Tree. This is represented by a
"generalized index" (or **gindex**) where the high-order bit is the level in the tree and the remaining
bits is a unique bit pattern, allowing a unique identifier for each node in the tree.
The **gindex** of a position $n$ can be calculated as $2^{d(n)} + idx(n)$, where:
- $d(n)$ is a function returning the depth of the position in the Game Tree
- $idx(n)$ is a function returning the index of the position at its depth (starting from the left).
Positions at the deepest level of the game tree correspond to indices in the execution trace, whereas claims at the
split depth represent single L2 blocks' [output roots][g-output-root].
Positions higher up the game tree also cover the deepest, right-most positions relative to the current position.
We refer to this coverage as the **trace index** of a Position.
> This means claims commit to an execution trace that terminates at the same index as their Position's trace index.
> That is, for a given trace index $n$, its ClaimHash corresponds to the $S_n$ th state in the trace.
Note that there can be multiple positions covering the same _trace index_.
### GAME_DURATION
This is an immutable, preset to a FDG implementation, representing the duration of the game. Each top level team will
receive half of this duration on their initial chess clocks.
## Game Mechanics
### Actors
The game involves two types of participants (or Players): **Challengers** and **Defenders**.
These players are grouped into separate teams, each employing distinct strategies to interact with the game.
Team members share a common goal regarding the game's outcome. Players interact with the game primarily through
_moves_.
### Moves
A Move is a challenge against an existing claim and must include an alternate claim asserting a different trace.
Moves can either be attacks or defenses and serve to update to DAG by adding nodes and edges targeting the disputed
claim.
Moves within the fault dispute game can claim two separate values: [output roots][g-output-root] and execution trace
commitments. At and above the `SPLIT_DEPTH`, claims correspond to output roots, while below the split depth, they
correspond to execution trace commitments.
Initially, claims added to the DAG are _uncontesteed_ (i.e. not **countered**). Once a move targets a claim, that claim
is considered countered.
The status of a claim &mdash; whether it's countered or not &mdash; helps determine its validity and, ultimately, the
game's winner.
#### Attack
A logical move made when a claim is disagreed with.
A claim at the relative attack position to a node, `n`, in the Game Tree commits to half
of the trace of the `n`’s claim.
The attack position relative to a node can be calculated by multiplying its gindex by 2.
To illustrate this, here's a Game Tree highlighting an attack on a Claim positioned at 6.
![Attacking node 6](assets/attack.png)
Attacking the node at 6 moves creates a new claim positioned at 12.
#### Defend
The logical move against a claim when you agree with both it and its parent.
A defense at the relative position to a node, `n``, in the Game Tree commits to the first half of n + 1’s trace range.
![Defend at 4](assets/defend.png)
Note that because of this, some nodes may never exist within the Game Tree.
However, they're not necessary as these nodes have complimentary, valid positions
with the same trace index within the tree. For example, a Position with gindex 5 has the same
trace index as another Position with gindex 2. We can verify that all trace indices have valid moves within the game:
![Game Tree Showing All Valid Move Positions](assets/valid-moves.png)
There may be multiple claims at the same position, so long as their `ClaimHash` are unique.
Each move adds new claims to the Game Tree at strictly increasing depth.
Once a claim is at `MAX_GAME_DEPTH`, the only way to dispute such claims is to **step**.
### Step
At `MAX_GAME_DEPTH`, the position of claims correspond to indices of an execution trace.
It's at this point that the FDG is able to query the VM to determine the validity of claims,
by checking the states they're committing to.
This is done by applying the VM's STF to the state a claim commits to.
If the STF post-state does not match the claimed state, the challenge succeeds.
```solidity
/// @notice Perform an instruction step via an on-chain fault proof processor.
/// @dev This function should point to a fault proof processor in order to execute
/// a step in the fault proof program on-chain. The interface of the fault proof
/// processor contract should adhere to the `IBigStepper` interface.
/// @param _claimIndex The index of the challenged claim within `claimData`.
/// @param _isAttack Whether or not the step is an attack or a defense.
/// @param _stateData The stateData of the step is the preimage of the claim at the given
/// prestate, which is at `_stateIndex` if the move is an attack and `_claimIndex` if
/// the move is a defense. If the step is an attack on the first instruction, it is
/// the absolute prestate of the fault proof VM.
/// @param _proof Proof to access memory nodes in the VM's merkle state tree.
function step(uint256 _claimIndex, bool _isAttack, bytes calldata _stateData, bytes calldata _proof) external;
```
### Step Types
Similar to moves, there are two ways to step on a claim; attack or defend.
These determine the pre-state input to the VM STF and the expected output.
- **Attack Step** - Challenges a claim by providing a pre-state, proving an invalid state transition.
It uses the previous state in the execution trace as input and expects the disputed claim's state as output.
There must exist a claim in the DAG that commits to the input.
- **Defense Step** - Challenges a claim by proving it was an invalid attack,
thereby defending the disputed ancestor's claim. It uses the disputed claim's state as input and expects
the next state in the execution trace as output. There must exist a claim in the DAG that commits to the
expected output.
The FDG step handles the inputs to the VM and asserts the expected output.
A step that successfully proves an invalid post-state (when attacking) or pre-state (when defending) is a
successful counter against the disputed claim.
Players interface with `step` by providing an indicator of attack and state data (including any proofs)
that corresponds to the expected pre/post state (depending on whether it's an attack or defend).
The FDG will assert that an existing claim commits to the state data provided by players.
### PreimageOracle Interaction
Certain steps (VM state transitions) require external data to be available by the `PreimageOracle`.
To ensure a successful state transition, players should provide this data in advance.
The FDG provides the following interface to manage data loaded to the `PreimageOracle`:
```solidity
/// @notice Posts the requested local data to the VM's `PreimageOralce`.
/// @param _ident The local identifier of the data to post.
/// @param _execLeafIdx The index of the leaf claim in an execution subgame that requires the local data for a step.
/// @param _partOffset The offset of the data to post.
function addLocalData(uint256 _ident, uint256 _execLeafIdx, uint256 _partOffset) external;
```
The `addLocalData` function loads local data into the VM's `PreimageOracle`. This data consists of bootstrap data for
the program. There are multiple sets of local preimage keys that belong to the `FaultDisputeGame` contract due to the
ability for players to bisect to any block $n \rightarrow n + 1$ state transition since the configured genesis, the
`_execLeafIdx` parameter enables a search for the starting / disputed outputs to be performed such that the contract
can write to and reference unique local keys in the `PreimageOracle` for each of these $n \rightarrow n + 1$
transitions.
| Identifier | Description |
| ---------- | ------------------------------------------------------ |
| `0` | Parent L1 head hash at the time of the proposal |
| `1` | Starting output root hash (commits to block # `n`) |
| `2` | Disputed output root hash (commits to block # `n + 1`) |
| `3` | Starting L2 block number (block # `n`) |
| `4` | Chain ID |
For global `keccak256` preimages, there are two routes for players to submit:
1. Small preimages atomically.
2. Large preimages via streaming.
Global `keccak256` preimages are non-context specific and can be submitted directly to the `PreimageOracle` via the
`loadKeccak256PreimagePart` function, which takes the part offset as well as the full preimage. In the event that the
preimage is too large to be submitted through calldata in a single block, challengers must resort to the streaming
option.
**Large Preimage Proposals**
Large preimage proposals allow for submitters to stream in a large preimage over multiple transactions, along-side
commitments to the intermediate state of the `keccak256` function after absorbing/permuting the $1088$ bit block.
This data is progressively merkleized on-chain as it is streamed in, with each leaf constructed as follows:
```solidity
/// @notice Returns a leaf hash to add to a preimage proposal merkle tree.
/// @param input A single 136 byte chunk of the input.
/// @param blockIndex The index of the block that `input` corresponds to in the full preimage's absorbtion.
/// @param stateCommitment The hash of the full 5x5 state matrix *after* absorbing and permuting `input`.
function hashLeaf(
bytes memory input,
uint256 blockIndex,
bytes32 stateCommitment
) internal view returns (bytes32 leaf) {
require(input.length == 136, "input must be exactly the size of the keccak256 rate");
leaf = keccak256(abi.encodePacked(input, blockIndex, stateCommitment));
}
```
Once the full preimage and all intermediate state commitments have been posted, the large preimage proposal enters a
challenge period. During this time, a challenger can reconstruct the merkle tree that was progressively built on-chain
locally by scanning the block bodies that contain the proposer's leaf preimages. If they detect that a commitment to
the intermediate state of the hash function is incorrect at any step, they may perform a single-step dispute for the
proposal in the `PreimageOracle`. This involves:
1. Creating a merkle proof for the agreed upon prestate leaf (not necessary if the invalid leaf is the first one, the
setup state of the matrix is constant.) within the proposal's merkle root.
2. Creating a merkle proof for the disputed post state leaf within the proposal's merkle root.
3. Computing the state matrix at the agreed upon prestate (not necessary if the invalid leaf is the first one, the
setup state of the matrix is constant.)
The challenger then submits this data to the `PreimageOracle`, where the post state leaf's claimed input is absored into
the pre state leaf's state matrix and the SHA3 permutation is executed on-chain. After that, the resulting state matrix
is hashed and and compared with the proposer's claim in the post state leaf. If the hash does not match, the proposal
is marked as challenged, and it may not be finalized. If, after the challenge period is concluded, a proposal has no
challenges, it may be finalized and the preimage part may be placed into the authorized mappings for the FPVM to read.
### Team Dynamics
Challengers seek to dispute the root claim, while Defenders aim to support it.
Both types of actors will move accordingly to support their team. For Challengers, this means
attacking the root claim and disputing claims positioned at even depths in the Game Tree.
Defenders do the opposite by disputing claims positioned at odd depths.
Players on either team are motivated to support the actions of their teammates.
This involves countering disputes against claims made by their team (assuming these claims are honest).
Uncontested claims are likely to result in a loss, as explained later under [Resolution](#resolution).
### Game Clock
Every claim in the game has a Clock. A claim's inherits the clock of its grandparent claim in the
DAG (and so on). Akin to a chess clock, it keeps track of the total time each team takes to make
moves, preventing delays.
Making a move resumes the clock for the disputed claim and puases it for the newly added one.
A move against a particular claim is no longer possible once the parent of the disputed claim's Clock
has exceeded half of the `GAME_DURATION`. By which point, the claim's clock has _expired_.
### Resolution
Resolving the FDG determines which team won the game. To do this, we use the internal sub game structure.
Each claim within the game is the root of its own sub game. These subgames are modeled as nested DAGs, each with a max
depth of 1. In order for a claim to be considered countered, only one of its children must be uncountered. Subgames
can also not be resolved until all of their children, which are subgames themselves, have been resolved and
the potential opponent's chess clock has run out. Because each claim is the root of its own sub-game,
truth percolates upwards towards the root claim by resolving each individual sub-game bottom-up.
In a game like the one below, we can resolve up from the deepest subgames. Here, we'd resolve `b0`
to uncountered and `a0` to countered by walking up from their deepest children, and once all children of the
root game are recursively resolved, we can resolve the root to countered due to `b0` remaining uncountered.
<!-- https://gist.github.com/clabby/e98bdd80ef3c038424f3372b70e34e08 -->
<!-- markdownlint-disable no-inline-html -->
<https://github.com/ethereum-optimism/optimism/assets/8406232/d2b708a0-539e-439d-96bd-c2f66f3a45f8>
Another example is this game, which has a slightly different structure. Here, the root claim will also
be countered due to `b0` remaining uncountered.
<!--
digraph G {
rankdir=LR
newrank=true
node [shape=plaintext]
subgraph cluster_01 {
label = "Legend";
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
<tr><td align="right" port="i1">bisection</td></tr>
<tr><td align="right" port="i2">resolution</td></tr>
</table>>]
key2 [label=<<table border="0" cellpadding="" cellspacing="0" cellborder="0">
<tr><td port="i1">&nbsp;</td></tr>
<tr><td port="i2">&nbsp;</td></tr>
</table>>]
key:i1:e -> key2:i1:w [color=green]
key:i2:e -> key2:i2:w [color=coral1, style=dotted]
}
subgraph cluster_0 {
color=cornflowerblue;
node [style=filled];
a0 -> a1 [color=green];
a1 -> a0 [color=coral1, style=dotted];
subgraph cluster_0_0 {
label = "subgame #5";
color=purple;
a1 -> a2 [color=green];
a2 -> a1 [color=coral1, style=dotted];
subgraph cluster_0_1 {
label = "subgame #6";
color=magenta;
a2 -> a3 [color=green];
a3 -> a2 [color=coral1, style=dotted];
a2 -> a4 [color=green];
a4 -> a2 [color=coral1, style=dotted];
subgraph cluster_0_2 {
label = "subgame #7";
color=lightpink;
a3
}
subgraph cluster_0_3 {
label = "subgame #8";
color=lightpink;
a4 -> a5 [color=green];
a5 -> a4 [color=coral1, style=dotted];
subgraph cluster_0_4 {
label = "subgame #9";
color=palegreen;
a5
}
}
}
}
label = "subgame #4";
}
subgraph cluster_1 {
node [style=filled];
label = "subgame #1";
color=cornflowerblue
b0 -> b1 [color=green];
b1 -> b0 [color=coral1, style=dotted];
subgraph cluster_1_0 {
label = "subgame #2";
color=purple;
b1 -> b2 [color=green];
b2 -> b1 [color=coral1, style=dotted];
subgraph cluster_1_1 {
label = "subgame #3";
edge [style=invis]
color=magenta;
b2
}
}
}
Root -> a0 [color=green];
Root -> b0 [color=green];
a0 -> Root [color=coral1, style=dotted];
b0 -> Root [color=coral1, style=dotted];
Root [shape=Mdiamond];
}
-->
<!-- markdownlint-disable no-inline-html -->
<p align="center">
<img src="https://github.com/ethereum-optimism/optimism/assets/8406232/9b20ba8d-0b64-47b3-9962-5533f7eb4ef7" width=60%>
</p>
Given these rules, players are motivated to move quickly to challenge all dishonest claims.
Each move bisects the historical state of L2 and eventually, `MAX_GAME_DEPTH` is reached where disputes
can be settled conclusively. Dishonest players are disincentivized to participate, via backwards induction,
as an invalid claim won't remain uncontested. Further incentives can be added to the game by requiring
claims to be bonded, while rewarding game winners using the bonds of dishonest claims.
# Fault Proof
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [Pre-image Oracle](#pre-image-oracle)
- [Pre-image key types](#pre-image-key-types)
- [Type `0`: Zero key](#type-0-zero-key)
- [Type `1`: Local key](#type-1-local-key)
- [Type `2`: Global keccak256 key](#type-2-global-keccak256-key)
- [Type `3`: Global generic key](#type-3-global-generic-key)
- [Type `4-128`: reserved range](#type-4-128-reserved-range)
- [Type `129-255`: application usage](#type-129-255-application-usage)
- [Bootstrapping](#bootstrapping)
- [Hinting](#hinting)
- [Pre-image communication](#pre-image-communication)
- [Fault Proof Program](#fault-proof-program)
- [Prologue](#prologue)
- [Main content](#main-content)
- [Epilogue](#epilogue)
- [Pre-image hinting routes](#pre-image-hinting-routes)
- [`l1-block-header <blockhash>`](#l1-block-header-blockhash)
- [`l1-transactions <blockhash>`](#l1-transactions-blockhash)
- [`l1-receipts <blockhash>`](#l1-receipts-blockhash)
- [`l2-block-header <blockhash>`](#l2-block-header-blockhash)
- [`l2-transactions <blockhash>`](#l2-transactions-blockhash)
- [`l2-code <codehash>`](#l2-code-codehash)
- [`l2-state-node <nodehash>`](#l2-state-node-nodehash)
- [`l2-output <outputroot>`](#l2-output-outputroot)
- [Fault Proof VM](#fault-proof-vm)
- [Fault Proof Interactive Dispute Game](#fault-proof-interactive-dispute-game)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
A fault proof, also known as fraud proof or interactive game, consists of 3 components:
- [Program]: given a commitment to all rollup inputs (L1 data) and the dispute, verify the dispute statelessly.
- [VM]: given a stateless program and its inputs, trace any instruction step, and prove it on L1.
- [Interactive Dispute Game]: bisect a dispute down to a single instruction, and resolve the base-case using the VM.
Each of these 3 components may have different implementations, which can be combined into different proof stacks,
and contribute to proof diversity when resolving a dispute.
"Stateless execution" of the program, and its individual instructions, refers to reproducing
the exact same computation by authenticating the inputs with a [Pre-image Oracle][oracle].
![Diagram of Program and VM architecture](./assets/fault-proof.svg)
## Pre-image Oracle
[oracle]: #Pre-image-Oracle
The pre-image oracle is the only form of communication between
the [Program] (in the [Client](#client) role) and the [VM] (in the [Server](#server) role).
The program uses the pre-image oracle to query any input data that is understood to be available to the user:
- The initial inputs to bootstrap the program. See [Bootstrapping](#bootstrapping).
- External data not already part of the program code. See [Pre-image hinting routes](#pre-image-hinting-routes).
The communication happens over a simple request-response wire protocol,
see [Pre-image communication](#pre-image-communication).
### Pre-image key types
Pre-images are identified by a `bytes32` type-prefixed key:
- The first byte identifies the type of request.
- The remaining 31 bytes identify the pre-image key.
#### Type `0`: Zero key
The zero prefix is illegal. This ensures all pre-image keys are non-zero,
enabling storage lookup optimizations and avoiding easy mistakes with invalid zeroed keys in the EVM.
#### Type `1`: Local key
Information specific to the dispute: the remainder of the key may be an index, a string, a hash, etc.
Only the contract(s) managing this dispute instance may serve the value for this key:
it is localized and context-dependent.
This type of key is used for program bootstrapping, to identify the initial input arguments by index or name.
#### Type `2`: Global keccak256 key
This type of key uses a global pre-image store contract, and is fully context-independent and permissionless.
I.e. every key must have a single unique value, regardless of chain history or time.
Using a global store reduces duplicate pre-image registration work,
and avoids unnecessary contract redeployments per dispute.
This global store contract should be non-upgradeable.
Since `keccak256` is a safe 32-byte hash input, the first byte is overwritten with a `2` to derive the key,
while keeping the rest of the key "readable" (matching the original hash).
#### Type `3`: Global generic key
Reserved. This scheme allows for unlimited application-layer pre-image types without fault-proof VM redeployments.
This is a generic version of a global key store: `key = 0x03 ++ keccak256(x, sender)[1:]`, where:
- `x` is a `bytes32`, which can be a hash of an arbitrary-length type of cryptographically secure commitment.
- `sender` is a `bytes32` identifying the pre-image inserter address (left-padded to 32 bytes)
This global store contract should be non-upgradeable.
The global contract is permissionless: users can standardize around external contracts that verify pre-images
(i.e. a specific `sender` will always be trusted for a specific kind of pre-image).
The external contract verifies the pre-image before inserting it into the global store for usage by all
fault proof VMs without requiring the VM or global store contract to be changed.
Users may standardize around upgradeable external pre-image contracts,
in case the implementation of the verification of the pre-image is expected to change.
The store update function is `update(x bytes32, offset uint64, span uint8, value bytes32)`:
- `x` is the `bytes32` `x` that the pre-image `key` is computed with.
- Only part of the pre-image, starting at `offset`, and up to (incl.) 32 bytes `span` can be inserted at a time.
- Pre-images may have an undefined length (e.g. a stream), we only need to know how many bytes of `value` are usable.
- The key and offset will be hashed together to uniquely store the `value` and `span`, for later pre-image serving.
This enables fault proof programs to adopt any new pre-image schemes without VM update or contract redeployment.
It is up to the user to index the special pre-image values by this key scheme,
as there is no way to revert it to the original commitment without knowing said commitment or value.
#### Type `4-128`: reserved range
Range start and end both inclusive.
This range of key types is reserved for future usage by the core protocol.
E.g. version changes, contract migrations, chain-data, additional core features, etc.
`128` specifically (`1000 0000` in binary) is reserved for key-type length-extension
(reducing the content part to `30` or less key bytes), if the need arises.
#### Type `129-255`: application usage
This range of key types may be used by forks or customized versions of the fault proof protocol.
### Bootstrapping
Initial inputs are deterministic, but not necessarily singular or global:
there may be multiple different disputes at the same time, each with its own disputed claims and L1 context.
To bootstrap, the program requests the initial inputs from the VM, using pre-image key type `1`.
The VM is aware of the external context, and maps requested pre-image keys based on their type, i.e.
a local lookup for type `1`, or global one for `2`, and optionally support other key-types.
### Hinting
There is one more form of optional communication between client and server: pre-image hinting.
Hinting is optional, and *is a no-op* in a L1 VM implementation.
The hint itself comes at very low cost onchain: the hint can be a single `write` sys-call,
which is instant as the memory to write as hint does not actually need to be loaded as part of the onchain proof.
Hinting allows the program, when generating a proof offchain,
to instruct the VM what data it is interested in.
The VM can choose to execute the requested hint at any time: either locally (for standard requests),
or in a modular form by redirecting the hint to tooling that may come with the VM program.
Hints do not have to be executed directly: they may first just be logged to show the intents of the program,
and the latest hint may be buffered for lazy execution, or dropped entirely when in read-only mode (like onchain).
When the pre-image oracle serves a request, and the request cannot be served from an existing collection of pre-images
(e.g. a local pre-image cache) then the VM can execute the hint to retrieve the missing pre-image(s).
It is the responsibility of the program to provide sufficient hinting for every pre-image request.
Some hints may have to be repeated: the VM only has to execute the last hint when handling a missing pre-image.
Note that hints may produce multiple pre-images:
e.g. a hint for an ethereum block with transaction list may prepare pre-images for the header,
each of the transactions, and the intermediate merkle-nodes that form the transactions-list Merkle Patricia Trie.
Hinting is implemented with a request-acknowledgement wire-protocol over a blocking two-way stream:
```text
<request> := <length prefix> <hint bytes>
<response> := <ack>
<length prefix> := big-endian uint32 # length of <hint bytes>
<hint bytes> := byte sequence
<ack> := 1-byte zero value
```
The ack informs the client that the hint has been processed. Servers may respond to hints and pre-image (see below)
requests asynchronously as they are on separate streams. To avoid requesting pre-images that are not yet fetched,
clients should request the pre-image only after it has observed the hint acknowledgement.
### Pre-image communication
Pre-images are communicated with a minimal wire-protocol over a blocking two-way stream.
This protocol can be implemented with blocking read/write syscalls.
```text
<request> := <bytes32> # the type-prefixed pre-image key
<response> := <length prefix> <pre-image bytes>
<length prefix> := big-endian uint64 # length of <pre-image bytes>, note: uint64
```
The `<length prefix>` here may be arbitrarily high:
the client can stop reading at any time if the required part of the pre-image has been read.
After the client writes new `<request>` bytes, the server should be prepared to respond with
the pre-image starting from `offset == 0` upon `read` calls.
The server may limit `read` results artificially to only a small amount of bytes at a time,
even though the full pre-image is ready: this is expected regular IO protocol,
and the client will just have to continue to read the small results at a time,
until 0 bytes are read, indicating EOF.
This enables the server to serve e.g. at most 32 bytes at a time or align reads with VM memory structure,
to limit the amount of VM state that changes per syscall instruction,
and thus keep the proof size per instruction bounded.
## Fault Proof Program
[Program]: #Fault-Proof-Program
The Fault Proof Program defines the verification of claims of the state-transition outputs
of the L2 rollup as a pure function of L1 data.
The `op-program` is the reference implementation of the program, based on `op-node` and `op-geth` implementations.
The program consists of:
- Prologue: load the inputs, given minimal bootstrapping, with possible test-overrides.
- Main content: process the L2 state-transition, i.e. derive the state changes from the L1 inputs.
- Epilogue: inspect the state changes to verify the claim.
### Prologue
The program is bootstrapped with two primary inputs:
- `l1_head`: the L1 block hash that will be perceived as the tip of the L1 chain,
authenticating all prior L1 history.
- `dispute`: identity of the claim to verify.
Bootstrapping happens through special input requests to the host of the program.
Additionally, there are *implied* inputs, which are *derived from the above primary inputs*,
but can be overridden for testing purposes:
- `l2_head`: the L2 block hash that will be perceived as the previously agreed upon tip of the L2 chain,
authenticating all prior L2 history.
- Chain configurations: chain configuration may be baked into the program,
or determined from attributes of the identified `dispute` on L1.
- `l1_chain_config`: The chain-configuration of the L1 chain (also known as `l1_genesis.json`)
- `l2_chain_config`: The chain-configuration of the L2 chain (also known as `l2_genesis.json`)
- `rollup_config`: The rollup configuration used by the rollup-node (also known as `rollup.json`)
The implied inputs rely on L1-introspection to load attributes of the `dispute` through the
[dispute game interface](./dispute-game-interface.md), in the L1 history up and till the specified `l1_head`.
The `dispute` may be the claim itself, or a pointer to specific prior claimed data in L1,
depending on the dispute game interface.
Implied inputs are loaded in a "prologue" before the actual core state-transition function executes.
During testing a simplified prologue that loads the overrides may be used.
> Note: only the test-prologues are currently supported, since the dispute game interface is actively changing.
### Main content
To verify a claim about L2 state, the program first reproduces
the L2 state by applying L1 data to prior agreed L2 history.
This process is also known as the [L2 derivation process](./derivation.md),
and matches the processing in the [rollup node](./rollup-node.md) and [execution-engine](./exec-engine.md).
The difference is that rather than retrieving inputs from an RPC and applying state changes to disk,
the inputs are loaded through the [pre-image oracle][oracle] and the changes accumulate in memory.
The derivation executes with two data-sources:
- Interface to read-only L1 chain, backed by the pre-image oracle:
- The `l1_head` determines the view over the available L1 data: no later L1 data is available.
- The implementation of the chain traverses the header-chain from the `l1_head` down to serve by-number queries.
- The `l1_head` is the L1 unsafe head, safe head, and finalized head.
- Interface to L2 engine API
- Prior L2 chain history is backed by the pre-image oracle, similar to the L1 chain:
- The initial `l2_head` determines the view over the initial available L2 history: no later L2 data is available.
- The implementation of the chain traverses the header-chain from the `l2_head` down to serve by-number queries.
- The `l2_head` is the initial L2 unsafe head, safe head, and finalized head.
- New L2 chain history accumulates in memory.
- Although the pre-image oracle can be used to retrieve data by hash if memory is limited,
the program should prefer to keep the newly created chain data in memory, to minimize pre-image oracle access.
- The L2 unsafe head, safe head, and finalized L2 head will potentially change as derivation progresses.
- L2 state consists of the diff of changes in memory,
and any unchanged state nodes accessible through the read-only L2 history view.
See [Pre-image routes](#pre-image-routes) for specifications of the pre-image oracle backing of these data sources.
Using these data-sources, the derivation pipeline is processed till we hit one of two conditions:
- `EOF`: when we run out of L1 data, the L2 chain will not change further, and the epilogue can start.
- Eager epilogue condition: depending on the type of claim to verify,
if the L2 result is irreversible (i.e. no later L1 inputs can override it),
the processing may end early when the result is ready.
E.g. when asserting state at a specific L2 block, rather than the very tip of the L2 chain.
### Epilogue
While the main-content produces the disputed L2 state already,
the epilogue concludes what this means for the disputed claim.
The program produces a binary output to verify the claim, using a standard single-byte Unix exit-code:
- a `0` for success, i.e. the claim is correct.
- a non-zero code for failure, i.e. the claim is incorrect.
- `1` should be preferred for identifying an incorrect claim.
- Other non-zero exit codes may indicate runtime failure,
e.g. a bug in the program code may resolve in a kind of `panic` or unexpected error.
Safety should be preferred over liveness in this case, and the `claim` will fail.
To assert the disputed claim, the epilogue, like the main content,
can introspect L1 and L2 chain data and post-process it further,
to then make a statement about the claim with the final exit code.
A disputed output-root may be disproven by first producing the output-root, and then comparing it:
1. Retrieve the output attributes from the L2 chain view: the state-root, block-hash, withdrawals storage-root.
2. Compute the output-root, as the [proposer should compute it](./proposals.md#l2-output-commitment-construction).
3. If the output-root matches the `claim`, exit with code 0. Otherwise, exit with code 1.
> Note: the dispute game interface is actively changing, and may require additional claim assertions.
> the output-root epilogue may be replaced or extended for general L2 message proving.
### Pre-image hinting routes
The fault proof program implements hint handling for the VM to use,
as well as any program testing outside of VM environment.
This can be exposed via a CLI, or alternative inter-process API.
Every instance of `<blockhash>` in the below routes is `0x`-prefixed, lowercase, hex-encoded.
#### `l1-block-header <blockhash>`
Requests the host to prepare the L1 block header RLP pre-image of the block `<blockhash>`.
#### `l1-transactions <blockhash>`
Requests the host to prepare the list of transactions of the L1 block with `<blockhash>`:
prepare the RLP pre-images of each of them, including transactions-list MPT nodes.
#### `l1-receipts <blockhash>`
Requests the host to prepare the list of receipts of the L1 block with `<blockhash>`:
prepare the RLP pre-images of each of them, including receipts-list MPT nodes.
#### `l2-block-header <blockhash>`
Requests the host to prepare the L2 block header RLP pre-image of the block `<blockhash>`.
#### `l2-transactions <blockhash>`
Requests the host to prepare the list of transactions of the L2 block with `<blockhash>`:
prepare the RLP pre-images of each of them, including transactions-list MPT nodes.
#### `l2-code <codehash>`
Requests the host to prepare the L2 smart-contract code with the given `<codehash>`.
#### `l2-state-node <nodehash>`
Requests the host to prepare the L2 MPT node preimage with the given `<nodehash>`.
#### `l2-output <outputroot>`
Requests the host to prepare the L2 Output at the l2 output root `<outputroot>`.
The L2 Output is the preimage of a [computed output root](./proposals.md#l2-output-commitment-construction).
## Fault Proof VM
[VM]: #Fault-Proof-VM
A fault proof VM implements:
- a smart-contract to verify a single execution-trace step, e.g. a single MIPS instruction.
- a CLI command to generate a proof of a single execution-trace step.
- a CLI command to compute a VM state-root at step N
A fault proof VM relies on a fault proof program to provide an interface
for fetching any missing pre-images based on hints.
The VM emulates the program, as prepared for the VM target architecture,
and generates the state-root or instruction proof data as requested through the VM CLI.
Refer to the documentation of the fault proof VM for further usage information.
Fault Proof VMs:
- [Cannon]: big-endian 32-bit MIPS proof, by OP Labs, in active development.
- [Asterisc]: little-endian 64-bit RISC-V proof, by `@protolambda`, in active development.
[Cannon]: https://github.com/ethereum-optimism/cannon
[Asterisc]: https://github.com/protolambda/asterisc
## Fault Proof Interactive Dispute Game
[Interactive Dispute Game]: #Fault-Proof-Interactive-Dispute-Game
The interactive dispute game allows actors to resolve a dispute with an onchain challenge-response game
that bisects to a disagreed block $n \rarrow n + 1$ state transition, and then over the execution trace of the VM which
models this state transition, bounded with a base-case that proves a single VM trace step.
The game is multi-player: different non-aligned actors may participate when bonded.
Response time is allocated based on the remaining time in the branch of the tree and alignment with the claim.
The allocated response time is limited by the dispute-game window,
and any additional time necessary based on L1 fee changes when bonds are insufficient.
> Note: the timed, bonded, bisection dispute game is in development.
> Also see [fault dispute-game specs](./fault-dispute-game.md) for fault dispute game system specifications,
> And [dispute-game-interface specs](./dispute-game-interface.md) for dispute game interface specifications.
# Glossary
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [General Terms](#general-terms)
- [Layer 1 (L1)](#layer-1-l1)
- [Layer 2 (L2)](#layer-2-l2)
- [Block](#block)
- [EOA](#eoa)
- [Merkle Patricia Trie](#merkle-patricia-trie)
- [Chain Re-Organization](#chain-re-organization)
- [Predeployed Contract ("Predeploy")](#predeployed-contract-predeploy)
- [Preinstalled Contract ("Preinstall")](#preinstalled-contract-preinstall)
- [Receipt](#receipt)
- [Transaction Type](#transaction-type)
- [Fork Choice Rule](#fork-choice-rule)
- [Priority Gas Auction](#priority-gas-auction)
- [Sequencing](#sequencing)
- [Sequencer](#sequencer)
- [Sequencing Window](#sequencing-window)
- [Sequencing Epoch](#sequencing-epoch)
- [L1 Origin](#l1-origin)
- [Deposits](#deposits)
- [Deposited Transaction](#deposited-transaction)
- [L1 Attributes Deposited Transaction](#l1-attributes-deposited-transaction)
- [User-Deposited Transaction](#user-deposited-transaction)
- [Depositing Call](#depositing-call)
- [Depositing Transaction](#depositing-transaction)
- [Depositor](#depositor)
- [Deposited Transaction Type](#deposited-transaction-type)
- [Deposit Contract](#deposit-contract)
- [Withdrawals](#withdrawals)
- [Relayer](#relayer)
- [Finalization Period](#finalization-period)
- [Batch Submission](#batch-submission)
- [Data Availability](#data-availability)
- [Data Availability Provider](#data-availability-provider)
- [Sequencer Batch](#sequencer-batch)
- [Channel](#channel)
- [Channel Frame](#channel-frame)
- [Batcher](#batcher)
- [Batcher Transaction](#batcher-transaction)
- [Channel Timeout](#channel-timeout)
- [L2 Output Root Proposals](#l2-output-root-proposals)
- [Proposer](#proposer)
- [L2 Chain Derivation](#l2-chain-derivation)
- [L2 Derivation Inputs](#l2-derivation-inputs)
- [System Configuration](#system-configuration)
- [Payload Attributes](#payload-attributes)
- [L2 Genesis Block](#l2-genesis-block)
- [L2 Chain Inception](#l2-chain-inception)
- [Safe L2 Block](#safe-l2-block)
- [Safe L2 Head](#safe-l2-head)
- [Unsafe L2 Block](#unsafe-l2-block)
- [Unsafe L2 Head](#unsafe-l2-head)
- [Unsafe Block Consolidation](#unsafe-block-consolidation)
- [Finalized L2 Head](#finalized-l2-head)
- [Other L2 Chain Concepts](#other-l2-chain-concepts)
- [Address Aliasing](#address-aliasing)
- [Rollup Node](#rollup-node)
- [Rollup Driver](#rollup-driver)
- [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract)
- [L2 Output Root](#l2-output-root)
- [L2 Output Oracle Contract](#l2-output-oracle-contract)
- [Validator](#validator)
- [Fault Proof](#fault-proof)
- [Time Slot](#time-slot)
- [Block Time](#block-time)
- [Unsafe Sync](#unsafe-sync)
- [Execution Engine Concepts](#execution-engine-concepts)
- [Execution Engine](#execution-engine)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
------------------------------------------------------------------------------------------------------------------------
# General Terms
## Layer 1 (L1)
[L1]: glossary.md#layer-1-L1
Refers the Ethereum blockchain, used in contrast to [layer 2][L2], which refers to Optimism.
## Layer 2 (L2)
[L2]: glossary.md#layer-2-L2
Refers to the Optimism blockchain (specified in this repository), used in contrast to [layer 1][L1], which
refers to the Ethereum blockchain.
## Block
[block]: glossary.md#block
Can refer to an [L1] block, or to an [L2] block, which are structured similarly.
A block is a sequential list of transactions, along with a couple of properties stored in the *header* of the block. A
description of these properties can be found in code comments [here][nano-header], or in the [Ethereum yellow paper
(pdf)][yellow], section 4.3.
It is useful to distinguish between input block properties, which are known before executing the transactions in the
block, and output block properties, which are derived after executing the block's transactions. These include various
[Merkle Patricia Trie roots][mpt] that notably commit to the L2 state and to the log events emitted during execution.
## EOA
[EOA]: glossary.md#EOA
"Externally Owned Account", an Ethereum term to designate addresses operated by users, as opposed to contract addresses.
## Merkle Patricia Trie
[mpt]: glossary.md#merkle-patricia-trie
A [Merkle Patricia Trie (MPT)][mpt-details] is a sparse trie, which is a tree-like structure that maps keys to values.
The root hash of a MPT is a commitment to the contents of the tree, which allows a
proof to be constructed for any key-value mapping encoded in the tree. Such a proof is called a Merkle proof, and can be
verified against the Merkle root.
## Chain Re-Organization
[reorg]: glossary.md#chain-re-organization
A re-organization, or re-org for short, is whenever the head of a blockchain (its last block) changes (as dictated by
the [fork choice rule][fork-choice-rule]) to a block that is not a child of the previous head.
L1 re-orgs can happen because of network conditions or attacks. L2 re-orgs are a consequence of L1 re-orgs, mediated via
[L2 chain derivation][derivation].
## Predeployed Contract ("Predeploy")
[predeploy]: glossary.md#predeployed-contract-predeploy
A contract placed in the L2 genesis state (i.e. at the start of the chain).
All predeploy contracts are specified in the [predeploys specification][./predeploys.md].
## Preinstalled Contract ("Preinstall")
[preinstall]: glossary.md#preinstalled-contract-preinstall
A contract placed in the L2 genesis state (i.e. at the start of the chain). These contracts do not share the same
security guarantees as [predeploys](#predeployed-contract-predeploy), but are general use contracts made
available to improve the L2's UX.
All preinstall contracts are specified in the [preinstalls specification][./preinstalls.md].
## Receipt
[receipt]: glossary.md#receipt
A receipt is an output generated by a transaction, comprising a status code, the amount of gas used, a list of log
entries, and a [bloom filter] indexing these entries. Log entries are most notably used to encode [Solidity events].
Receipts are not stored in blocks, but blocks store a [Merkle Patricia Trie root][mpt] for a tree containing the receipt
for every transaction in the block.
Receipts are specified in the [yellow paper (pdf)][yellow] section 4.3.1.
## Transaction Type
[transaction-type]: glossary.md#transaction-type
Ethereum provides a mechanism (as described in [EIP-2718]) for defining different transaction types.
Different transaction types can contain different payloads, and be handled differently by the protocol.
[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
## Fork Choice Rule
[fork-choice-rule]: glossary.md#fork-choice-rule
The fork choice rule is the rule used to determine which block is to be considered as the head of a blockchain. On L1,
this is determined by the proof of stake rules.
L2 also has a fork choice rule, although the rules vary depending on whether we want the [safe L2 head][safe-l2-head],
the [unsafe L2 head][unsafe-l2-head] or the [finalized L2 head][finalized-l2-head].
## Priority Gas Auction
Transactions in ethereum are ordered by the price that the transaction pays to the miner. Priority Gas Auctions
(PGAs) occur when multiple parties are competing to be the first transaction in a block. Each party continuously
updates the gas price of their transaction. PGAs occur when there is value in submitting a transaction before other
parties (like being the first deposit or submitting a deposit before there is not more guaranteed gas remaining).
PGAs tend to have negative externalities on the network due to a large amount of transactions being submitted in a
very short amount of time.
------------------------------------------------------------------------------------------------------------------------
# Sequencing
[sequencing]: glossary.md#sequencing
Transactions in the rollup can be included in two ways:
- Through a [deposited transaction](#deposited-transaction), enforced by the system
- Through a regular transaction, embedded in a [sequencer batch](#sequencer-batch)
Submitting transactions for inclusion in a batch saves costs by reducing overhead, and enables the sequencer to
pre-confirm the transactions before the L1 confirms the data.
## Sequencer
[sequencer]: glossary.md#sequencer
A sequencer is either a [rollup node][rollup-node] ran in sequencer mode, or the operator of this rollup node.
The sequencer is a privileged actor, which receives L2 transactions from L2 users, creates L2 blocks using them, which
it then submits to [data availability provider][avail-provider] (via a [batcher]). It also submits [output
roots][l2-output] to L1.
## Sequencing Window
[sequencing-window]: glossary.md#sequencing-window
A sequencing window is a range of L1 blocks from which a [sequencing epoch][sequencing-epoch] can be derived.
A sequencing window whose first L1 block has number `N` contains [batcher transactions][batcher-transaction] for epoch
`N`. The window contains blocks `[N, N + SWS)` where `SWS` is the sequencer window size.
The current default `sws` is 3600 epochs.
Additionally, the first block in the window defines the [depositing transactions][depositing-tx] which determine the
[deposits] to be included in the first L2 block of the epoch.
## Sequencing Epoch
[sequencing-epoch]: glossary.md#sequencing-epoch
A sequencing epoch is sequential range of L2 blocks derived from a [sequencing window](#sequencing-window) of L1 blocks.
Each epoch is identified by an epoch number, which is equal to the block number of the first L1 block in the
sequencing window.
Epochs can have variable size, subject to some constraints. See the [L2 chain derivation specification][derivation-spec]
for more details.
## L1 Origin
[l1-origin]: glossary.md#l1-origin
The L1 origin of an L2 block is the L1 block corresponding to its [sequencing epoch][sequencing-epoch].
------------------------------------------------------------------------------------------------------------------------
# Deposits
[deposits]: glossary.md#deposits
In general, a deposit is an L2 transaction derived from an L1 block (by the [rollup driver]).
While transaction deposits are notably (but not only) used to "deposit" (bridge) ETH and tokens to L2, the word
*deposit* should be understood as "a transaction *deposited* to L2 from L1".
This term *deposit* is somewhat ambiguous as these "transactions" exist at multiple levels. This section disambiguates
all deposit-related terms.
Notably, a *deposit* can refer to:
- A [deposited transaction][deposited] (on L2) that is part of a [deposit block][deposit-block].
- A [depositing call][depositing-call] that causes a [deposited transaction][deposited] to be derived.
- The event/log data generated by the [depositing call][depositing-call], which is what the [rollup driver] reads to
derive the [deposited transaction][deposited].
We sometimes also talk about *user deposit* which is a similar term that explicitly excludes [L1 attributes deposited
transactions][l1-attr-deposit].
Deposits are specified in the [deposits specification][deposits-spec].
[deposits-spec]: deposits.md
## Deposited Transaction
[deposited]: glossary.md#deposited-transaction
A *deposited transaction* is a L2 transaction that was derived from L1 and included in a L2 block.
There are two kinds of deposited transactions:
- [L1 attributes deposited transaction][l1-attr-deposit], which submits the L1 block's attributes to the [L1 Attributes
Predeployed Contract][l1-attr-predeploy].
- [User-deposited transactions][user-deposited], which are transactions derived from an L1 call to the [deposit
contract][deposit-contract].
[deposits-spec]: deposits.md
## L1 Attributes Deposited Transaction
[l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction
An *L1 attributes deposited transaction* is [deposited transaction][deposited] that is used to register the L1 block
attributes (number, timestamp, ...) on L2 via a call to the [L1 Attributes Predeployed Contract][l1-attr-predeploy].
That contract can then be used to read the attributes of the L1 block corresponding to the current L2 block.
L1 attributes deposited transactions are specified in the [L1 Attributes Deposit][l1-attributes-tx-spec] section of the
deposits specification.
[l1-attributes-tx-spec]: deposits.md#l1-attributes-deposited-transaction
## User-Deposited Transaction
[user-deposited]: glossary.md#user-deposited-transaction
A *user-deposited transaction* is a [deposited transaction][deposited] which is derived from an L1 call to the [deposit
contract][deposit-contract] (a [depositing call][depositing-call]).
User-deposited transactions are specified in the [Transaction Deposits][tx-deposits-spec] section of the deposits
specification.
[tx-deposits-spec]: deposits.md#user-deposited-transactions
## Depositing Call
[depositing-call]: glossary.md#depositing-call
A *depositing call* is an L1 call to the [deposit contract][deposit-contract], which will be derived to a
[user-deposited transaction][user-deposited] by the [rollup driver].
This call specifies all the data (destination, value, calldata, ...) for the deposited transaction.
## Depositing Transaction
[depositing-tx]: glossary.md#depositing-transaction
A *depositing transaction* is an L1 transaction that makes one or more [depositing calls][depositing-call].
## Depositor
[depositor]: glossary.md#depositor
The *depositor* is the L1 account (contract or [EOA]) that makes (is the `msg.sender` of) the [depositing
call][depositing-call]. The *depositor* is **NOT** the originator of the depositing transaction (i.e. `tx.origin`).
## Deposited Transaction Type
[deposit-tx-type]: glossary.md#deposited-transaction-type
The *deposited transaction type* is an [EIP-2718] [transaction type][transaction-type], which specifies the input fields
and correct handling of a [deposited transaction][deposited].
See the [corresponding section][spec-deposit-tx-type] of the deposits spec for more information.
[spec-deposit-tx-type]: deposits.md#the-deposited-transaction-type
## Deposit Contract
[deposit-contract]: glossary.md#deposit-contract
The *deposit contract* is an [L1] contract to which [EOAs][EOA] and contracts may send [deposits]. The deposits are
emitted as log records (in Solidity, these are called *events*) for consumption by [rollup nodes][rollup-node].
Advanced note: the deposits are not stored in calldata because they can be sent by contracts, in which case the calldata
is part of the *internal* execution between contracts, and this intermediate calldata is not captured in one of the
[Merkle Patricia Trie roots][mpt] included in the L1 block.
cf. [Deposits Specification](deposits.md)
------------------------------------------------------------------------------------------------------------------------
# Withdrawals
> **TODO** expand this whole section to be clearer
[withdrawals]: glossary.md#withdrawals
In general, a withdrawal is a transaction sent from L2 to L1 that may transfer data and/or value.
The term *withdrawal* is somewhat ambiguous as these "transactions" exist at multiple levels. In order to differentiate
between the L1 and L2 components of a withdrawal we introduce the following terms:
- A *withdrawal initiating transaction* refers specifically to a transaction on L2 sent to the Withdrawals predeploy.
- A *withdrawal finalizing transaction* refers specifically to an L1 transaction which finalizes and relays the
withdrawal.
## Relayer
[relayer]: glossary.md#withdrawals
An EOA on L1 which finalizes a withdrawal by submitting the data necessary to verify its inclusion on L2.
## Finalization Period
[finalization-period]: glossary.md#finalization-period
The finalization period — sometimes also called *withdrawal delay* — is the minimum amount of time (in seconds) that
must elapse before a [withdrawal][withrawals] can be finalized.
The finalization period is necessary to afford sufficient time for [validators][validator] to make a [fault
proof][fault-proof].
> **TODO** specify current value for finalization period
------------------------------------------------------------------------------------------------------------------------
# Batch Submission
[batch-submission]: glossary.md#batch-submission
## Data Availability
[data-availability]: glossary.md#data-availability
Data availability is the guarantee that some data will be "available" (i.e. *retrievable*) during a reasonably long time
window. In Optimism's case, the data in question are [sequencer batches][sequencer-batch] that [validators][validator]
need in order to verify the sequencer's work and validate the L2 chain.
The [finalization period][finalization-period] should be taken as the lower bound on the availability window, since
that is when data availability is the most crucial, as it is needed to perform a [fault proof][fault-proof].
"Availability" **does not** mean guaranteed long-term storage of the data.
## Data Availability Provider
[avail-provider]: glossary.md#data-availability-provider
A data availability provider is a service that can be used to make data available. See the [Data
Availability][data-availability] for more information on what this means.
Ideally, a good data availability provider provides strong *verifiable* guarantees of data availability
Currently, the only supported data availability provider is Ethereum call data. [Ethereum data blobs][eip4844] will be
supported when they get deployed on Ethereum.
## Sequencer Batch
[sequencer-batch]: glossary.md#sequencer-batch
A sequencer batch is list of L2 transactions (that were submitted to a sequencer) tagged with an [epoch
number](#sequencing-epoch) and an L2 block timestamp (which can trivially be converted to a block number, given our
block time is constant).
Sequencer batches are part of the [L2 derivation inputs][deriv-inputs]. Each batch represents the inputs needed to build
**one** L2 block (given the existing L2 chain state) — except for the first block of each epoch, which also needs
information about deposits (cf. the section on [L2 derivation inputs][deriv-inputs]).
## Channel
[channel]: glossary.md#channel
A channel is a sequence of [sequencer batches][sequencer-batch] (for sequential blocks) compressed together. The reason
to group multiple batches together is simply to obtain a better compression rate, hence reducing data availability
costs.
A channel can be split in [frames][channel-frame] in order to be transmitted via [batcher
transactions][batcher-transaction]. The reason to split a channel into frames is that a channel might be too large to
include in a single batcher transaction.
A channel is uniquely identified by its timestamp (UNIX time at which the channel was created) and a random value. See
the [Frame Format][frame-format] section of the L2 Chain Derivation specification for more information.
[frame-format]: derivation.md#frame-format
On the side of the [rollup node][rollup-node] (which is the consumer of channels), a channel is considered to be
*opened* if its final frame (explicitly marked as such) has not been read, or closed otherwise.
## Channel Frame
[channel-frame]: glossary.md#channel-frame
A channel frame is a chunk of data belonging to a [channel]. [Batcher transactions][batcher-transaction] carry one or
multiple frames. The reason to split a channel into frames is that a channel might too large to include in a single
batcher transaction.
## Batcher
[batcher]: glossary.md#batcher
A batcher is a software component (independent program) that is responsible to make channels available on a data
availability provider. The batcher communicates with the rollup node in order to retrieve the channels. The channels are
then made available using [batcher transactions][batcher-transaction].
> **TODO** In the future, we might want to make the batcher responsible for constructing the channels, letting it only
> query the rollup node for L2 block inputs.
## Batcher Transaction
[batcher-transaction]: glossary.md#batcher-transaction
A batcher transaction is a transaction submitted by a [batcher] to a data availability provider, in order to make
channels available. These transactions carry one or more full frames, which may belong to different channels. A
channel's frame may be split between multiple batcher transactions.
When submitted to Ethereum calldata, the batcher transaction's receiver must be the sequencer inbox address. The
transaction must also be signed by a recognized batch submitter account. The recognized batch submitter account
is stored in the [System Configuration][system-config].
## Channel Timeout
[channel-timeout]: glossary.md#channel-timeout
The channel timeout is a duration (in L1 blocks) during which [channel frames][channel-frame] may land on L1 within
[batcher transactions][batcher-transaction].
The acceptable time range for the frames of a [channel][channel] is `[channel_id.timestamp, channel_id.timestamp +
CHANNEL_TIMEOUT]`. The acceptable L1 block range for these frames are any L1 block whose timestamp falls inside this
time range. (Note that `channel_id.timestamp` must be lower than the L1 block timestamp of any L1 block in which frames
of the channel are seen, or else these frames are ignored.)
The purpose of channel timeouts is dual:
- Avoid keeping old unclosed channel data around forever (an unclosed channel is a channel whose final frame was not
sent).
- Bound the number of L1 blocks we have to look back in order to decode [sequencer batches][sequencer-batch] from
channels. This is particularly relevant during L1 re-orgs, see the [Resetting Channel Buffering][reset-channel-buffer]
section of the L2 Chain Derivation specification for more information.
[reset-channel-buffer]: derivation.md#resetting-channel-buffering
> **TODO** specify `CHANNEL_TIMEOUT`
------------------------------------------------------------------------------------------------------------------------
# L2 Output Root Proposals
[l2-output-root-proposals]: glossary.md#l2-output-root-proposals
## Proposer
[proposer]: glossary.md#proposer
The proposer's role is to construct and submit output roots, which are commitments to the L2's state, to the
L2OutputOracle contract on L1 (the settlement layer). To do this, the proposer periodically queries the rollup node for
the latest output root derived from the latest finalized L1 block. It then takes the output root and submits it to the
L2OutputOracle contract on the settlement layer (L1).
------------------------------------------------------------------------------------------------------------------------
# L2 Chain Derivation
[derivation]: glossary.md#L2-chain-derivation
L2 chain derivation is a process that reads [L2 derivation inputs][deriv-inputs] from L1 in order to derive the L2
chain.
See the [L2 chain derivation specification][derivation-spec] for more details.
## L2 Derivation Inputs
[deriv-inputs]: glossary.md#l2-derivation-inputs
This term refers to data that is found in L1 blocks and is read by the [rollup node][rollup-node] to construct [payload
attributes][payload-attr].
L2 derivation inputs include:
- L1 block attributes
- block number
- timestamp
- basefee
- blob base fee
- [deposits] (as log data)
- [sequencer batches][sequencer-batch] (as transaction data)
- [System configuration][system-config] updates (as log data)
## System Configuration
[system-config]: glossary.md#system-configuration
This term refers to the collection of dynamically configurable rollup parameters maintained
by the [`SystemConfig`](./system_config.md) contract on L1 and read by the L2 [derivation] process.
These parameters enable keys to be rotated regularly and external cost parameters to be adjusted
without the network upgrade overhead of a hardfork.
## Payload Attributes
[payload-attr]: glossary.md#payload-attributes
This term refers to an object that can be derived from [L2 chain derivation inputs][deriv-inputs] found on L1, which are
then passed to the [execution engine][execution-engine] to construct L2 blocks.
The payload attributes object essentially encodes [a block without output properties][block].
Payload attributes are originally specified in the [Ethereum Engine API specification][engine-api], which we expand in
the [Execution Engine Specification](exec-engine.md).
See also the [Building The Payload Attributes][building-payload-attr] section of the rollup node specification.
[building-payload-attr]: rollup-node.md#building-the-payload-attributes
## L2 Genesis Block
[l2-genesis]: glossary.md#l2-genesis-block
The L2 genesis block is the first block of the L2 chain in its current version.
The state of the L2 genesis block comprises:
- State inherited from the previous version of the L2 chain.
- This state was possibly modified by "state surgeries". For instance, the migration to Bedrock entailed changes on
how native ETH balances were stored in the storage trie.
- [Predeployed contracts][predeploy]
The timestamp of the L2 genesis block must be a multiple of the [block time][block-time] (i.e. a even number, since the
block time is 2 seconds).
When updating the rollup protocol to a new version, we may perform a *squash fork*, a process that entails the creation
of a new L2 genesis block. This new L2 genesis block will have block number `X + 1`, where `X` is the block number of
the final L2 block before the update.
A squash fork is not to be confused with a *re-genesis*, a similar process that we employed in the past, which also
resets L2 block numbers, such that the new L2 genesis block has number 0. We will not employ re-genesis in the future.
Squash forks are superior to re-geneses because they avoid duplicating L2 block numbers, which breaks a lot of external
tools.
## L2 Chain Inception
[l2-chain-inception]: glossary.md#L2-chain-inception
The L1 block number at which the output roots for the [genesis block][l2-genesis] were proposed on the [output
oracle][output-oracle] contract.
In the current implementation, this is the L1 block number at which the output oracle contract was deployed or upgraded.
## Safe L2 Block
[safe-l2-block]: glossary.md#safe-l2-block
A safe L2 block is an L2 block that can be derived entirely from L1 by a [rollup node][rollup-node]. This can vary
between different nodes, based on their view of the L1 chain.
## Safe L2 Head
[safe-l2-head]: glossary.md#safe-l2-head
The safe L2 head is the highest [safe L2 block][safe-l2-block] that a [rollup node][rollup-node] knows about.
## Unsafe L2 Block
[unsafe-l2-block]: glossary.md#unsafe-l2-block
An unsafe L2 block is an L2 block that a [rollup node][rollup-node] knows about, but which was not derived from the L1
chain. In sequencer mode, this will be a block sequenced by the sequencer itself. In validator mode, this will be a
block acquired from the sequencer via [unsafe sync][unsafe-sync].
## Unsafe L2 Head
[unsafe-l2-head]: glossary.md#unsafe-l2-head
The unsafe L2 head is the highest [unsafe L2 block][unsafe-l2-block] that a [rollup node][rollup-node] knows about.
## Unsafe Block Consolidation
[consolidation]: glossary.md#unsafe-block-consolidation
Unsafe block consolidation is the process through which the [rollup node][rollup-node] attempts to move the [safe L2
head][safe-l2-head] a block forward, so that the oldest [unsafe L2 block][unsafe-l2-block] becomes the new safe L2 head.
In order to perform consolidation, the node verifies that the [payload attributes][payload-attr] derived from the L1
chain match the oldest unsafe L2 block exactly.
See the [Engine Queue section][engine-queue] of the L2 chain derivatiaon spec for more information.
[engine-queue]: derivation.md#engine-queue
## Finalized L2 Head
[finalized-l2-head]: glossary.md#finalized-l2-head
The finalized L2 head is the highest L2 block that can be derived from *[finalized][finality]* L1 blocks — i.e. L1
blocks older than two L1 epochs (64 L1 [time slots][time-slot]).
[finality]: https://hackmd.io/@prysmaticlabs/finality
------------------------------------------------------------------------------------------------------------------------
# Other L2 Chain Concepts
## Address Aliasing
[address-aliasing]: glossary.md#address-aliasing
When a contract submits a [deposit][deposits] from L1 to L2, its address (as returned by `ORIGIN` and `CALLER`) will be
aliased with a modified representation of the address of a contract.
- cf. [Deposit Specification](deposits.md#address-aliasing)
## Rollup Node
[rollup-node]: glossary.md#rollup-node
The rollup node is responsible for [deriving the L2 chain][derivation] from the L1 chain (L1 [blocks][block] and their
associated [receipts][receipt]).
The rollup node can run either in *validator* or *sequencer* mode.
In sequencer mode, the rollup node receives L2 transactions from users, which it uses to create L2 blocks. These are
then submitted to a [data availability provider][avail-provider] via [batch submission][batch-submission]. The L2 chain
derivation then acts as a sanity check and a way to detect L1 chain [re-orgs][reorg].
In validator mode, the rollup node performs derivation as indicated above, but is also able to "run ahead" of the L1
chain by getting blocks directly from the sequencer, in which case derivation serves to validate the sequencer's
behaviour.
A rollup node running in validator mode is sometimes called *a replica*.
> **TODO** expand this to include output root submission
See the [rollup node specification][rollup-node-spec] for more information.
## Rollup Driver
[rollup driver]: glossary.md#rollup-driver
The rollup driver is the [rollup node][rollup-node] component responsible for [deriving the L2 chain][derivation]
from the L1 chain (L1 [blocks][block] and their associated [receipts][receipt]).
> **TODO** delete this entry, alongside its reference — can be replaced by "derivation process" or "derivation logic"
> where needed
## L1 Attributes Predeployed Contract
[l1-attr-predeploy]: glossary.md#l1-attributes-predeployed-contract
A [predeployed contract][predeploy] on L2 that can be used to retrieve the L1 block attributes of L1 blocks with a given
block number or a given block hash.
cf. [L1 Attributes Predeployed Contract Specification](deposits.md#l1-attributes-predeployed-contract)
## L2 Output Root
[l2-output]: glossary.md#l2-output-root
A 32 byte value which serves as a commitment to the current state of the L2 chain.
cf. [Proposing L2 output commitments](proposals.md#l2-output-root-proposals-specification)
## L2 Output Oracle Contract
[output-oracle]: glossary.md#l2-output-oracle-contract
An L1 contract to which [L2 output roots][l2-output] are posted by the [sequencer].
## Validator
[validator]: glossary.md#validator
A validator is an entity (individual or organization) that runs a [rollup node][rollup-node] in validator mode.
Doing so grants a lot of benefits similar to running an Ethereum node, such as the ability to simulate L2 transactions
locally, without rate limiting.
It also lets the validator verify the work of the [sequencer], by re-deriving [output roots][l2-output] and comparing
them against those submitted by the sequencer. In case of a mismatch, the validator can perform a [fault
proof][fault-proof].
## Fault Proof
[fault-proof]: glossary.md#fault-proof
An on-chain *interactive* proof, performed by [validators][validator], that demonstrates that a [sequencer] provided
erroneous [output roots][l2-output].
cf. [Fault Proofs](./fault-proof.md)
## Time Slot
[time-slot]: glossary.md#time-slot
On L2, there is a block every 2 second (this duration is known as the [block time][block-time]).
We say that there is a "time slot" every multiple of 2s after the timestamp of the [L2 genesis block][l2-genesis].
On L1, post-[merge], the time slots are every 12s. However, an L1 block may not be produced for every time slot, in case
of even benign consensus issues.
## Block Time
[block-time]: glossary.md#block-time
The L2 block time is 2 second, meaning there is an L2 block at every 2s [time slot][time-slot].
Post-[merge], it could be said that the L1 block time is 12s as that is the L1 [time slot][time-slot]. However, in
reality the block time is variable as some time slots might be skipped.
Pre-merge, the L1 block time is variable, though it is on average 13s.
## Unsafe Sync
[unsafe-sync]: glossary.md#unsafe-sync
Unsafe sync is the process through which a [validator][validator] learns about [unsafe L2 blocks][unsafe-l2-block] from
the [sequencer][sequencer].
These unsafe blocks will later need to be confirmed by the L1 chain (via [unsafe block consolidation][consolidation]).
------------------------------------------------------------------------------------------------------------------------
# Execution Engine Concepts
## Execution Engine
[execution-engine]: glossary.md#execution-engine
The execution engine is responsible for executing transactions in blocks and computing the resulting state roots,
receipts roots and block hash.
Both L1 (post-[merge]) and L2 have an execution engine.
On L1, the executed blocks can come from L1 block synchronization; or from a block freshly minted by the execution
engine (using transactions from the L1 [mempool]), at the request of the L1 consensus layer.
On L2, the executed blocks are freshly minted by the execution engine at the request of the [rollup node][rollup-node],
using transactions [derived from L1 blocks][derivation].
In these specifications, "execution engine" always refer to the L2 execution engine, unless otherwise specified.
- cf. [Execution Engine Specification](exec-engine.md)
<!-- Internal Links -->
[derivation-spec]: derivation.md
[rollup-node-spec]: rollup-node.md
<!-- External Links -->
[mpt-details]: https://github.com/norswap/nanoeth/blob/d4c0c89cc774d4225d16970aa44c74114c1cfa63/src/com/norswap/nanoeth/trees/patricia/README.md
[trie]: https://en.wikipedia.org/wiki/Trie
[bloom filter]: https://en.wikipedia.org/wiki/Bloom_filter
[Solidity events]: https://docs.soliditylang.org/en/latest/contracts.html?highlight=events#events
[nano-header]: https://github.com/norswap/nanoeth/blob/cc5d94a349c90627024f3cd629a2d830008fec72/src/com/norswap/nanoeth/blocks/BlockHeader.java#L22-L156
[yellow]: https://ethereum.github.io/yellowpaper/paper.pdf
[engine-api]: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#PayloadAttributesV2
[merge]: https://ethereum.org/en/eth2/merge/
[mempool]: https://www.quicknode.com/guides/defi/how-to-access-ethereum-mempool
[L1 consensus layer]: https://github.com/ethereum/consensus-specs/#readme
[cannon]: https://github.com/ethereum-optimism/cannon
[eip4844]: https://www.eip4844.com/
# Guaranteed Gas Fee Market
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Gas Stipend](#gas-stipend)
- [Default Values](#default-values)
- [Limiting Guaranteed Gas](#limiting-guaranteed-gas)
- [Rationale for burning L1 Gas](#rationale-for-burning-l1-gas)
- [On Preventing Griefing Attacks](#on-preventing-griefing-attacks)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
[Deposited transactions](./glossary.md#deposited-transaction) are transactions on L2 that are
initiated on L1. The gas that they use on L2 is bought on L1 via a gas burn (or a direct payment
in the future). We maintain a fee market and hard cap on the amount of gas provided to all deposits
in a single L1 block.
The gas provided to deposited transactions is sometimes called "guaranteed gas". The gas provided to
deposited transactions is unique in the regard that it is not refundable. It cannot be refunded as
it is sometimes paid for with a gas burn and there may not be any ETH left to refund.
The **guaranteed gas** is composed of a gas stipend, and of any guaranteed gas the user would like
to purchase (on L1) on top of that.
Guaranteed gas on L2 is bought in the following manner. An L2 gas price is calculated via an
EIP-1559-style algorithm. The total amount of ETH required to buy that gas is then calculated as
(`guaranteed gas * L2 deposit base fee`). The contract then accepts that amount of ETH (in a future
upgrade) or (only method right now), burns an amount of L1 gas that corresponds to the L2 cost (`L2
cost / L1 base fee`). The L2 gas price for guaranteed gas is not synchronized with the base fee on
L2 and will likely be different.
## Gas Stipend
To offset the gas spent on the deposit event, we credit `gas spent * L1 base fee` ETH to the cost
of the L2 gas, where `gas spent` is the amount of L1 gas spent processing the deposit. If the ETH
value of this credit is greater than the ETH value of the requested guaranteed gas (`requested
guaranteed gas * L2 gas price`), no L1 gas is burnt.
## Default Values
| Variable | Value |
| --------------------------------- | ---------------------------------------------- |
| `MAX_RESOURCE_LIMIT` | 20,000,000 |
| `ELASTICITY_MULTIPLIER` | 10 |
| `BASE_FEE_MAX_CHANGE_DENOMINATOR` | 8 |
| `MINIMUM_BASE_FEE` | 1 gwei |
| `MAXIMUM_BASE_FEE` | type(uint128).max |
| `SYSTEM_TX_MAX_GAS` | 1,000,000 |
| `TARGET_RESOURCE_LIMIT` | `MAX_RESOURCE_LIMIT` / `ELASTICITY_MULTIPLIER` |
## Limiting Guaranteed Gas
The total amount of guaranteed gas that can be bought in a single L1 block must be limited to
prevent a denial of service attack against L2 as well as ensure the total amount of guaranteed gas
stays below the L2 block gas limit.
We set a guaranteed gas limit of `MAX_RESOURCE_LIMIT` gas per L1 block and a target of
`MAX_RESOURCE_LIMIT` / `ELASTICITY_MULTIPLIER` gas per L1 block. These numbers enabled
occasional large transactions while staying within our target and maximum gas usage on L2.
Because the amount of guaranteed L2 gas that can be purchased in a single block is now limited,
we implement an EIP-1559-style fee market to reduce congestion on deposits. By setting the limit
at a multiple of the target, we enable deposits to temporarily use more L2 gas at a greater cost.
```python
# Pseudocode to update the L2 deposit base fee and cap the amount of guaranteed gas
# bought in a block. Calling code must handle the gas burn and validity checks on
# the ability of the account to afford this gas.
# prev_base fee is a u128, prev_bought_gas and prev_num are u64s
prev_base_fee, prev_bought_gas, prev_num = <values from previous update>
now_num = block.number
# Clamp the full base fee to a specific range. The minimum value in the range should be around 100-1000
# to enable faster responses in the base fee. This replaces the `max` mechanism in the ethereum 1559
# implementation (it also serves to enable the base fee to increase if it is very small).
def clamp(v: i256, min: u128, max: u128) -> u128:
if v < i256(min):
return min
elif v > i256(max):
return max
else:
return u128(v)
# If this is a new block, update the base fee and reset the total gas
# If not, just update the total gas
if prev_num == now_num:
now_base_fee = prev_base_fee
now_bought_gas = prev_bought_gas + requested_gas
elif prev_num != now_num:
# Width extension and conversion to signed integer math
gas_used_delta = int128(prev_bought_gas) - int128(TARGET_RESOURCE_LIMIT)
# Use truncating (round to 0) division - solidity's default.
# Sign extend gas_used_delta & prev_base_fee to 256 bits to avoid overflows here.
base_fee_per_gas_delta = prev_base_fee * gas_used_delta / TARGET_RESOURCE_LIMIT / BASE_FEE_MAX_CHANGE_DENOMINATOR
now_base_fee_wide = prev_base_fee + base_fee_per_gas_delta
now_base_fee = clamp(now_base_fee_wide, min=MINIMUM_BASE_FEE, max=UINT_128_MAX_VALUE)
now_bought_gas = requested_gas
# If we skipped multiple blocks between the previous block and now update the base fee again.
# This is not exactly the same as iterating the above function, but quite close for reasonable
# gas target values. It is also constant time wrt the number of missed blocks which is important
# for keeping gas usage stable.
if prev_num + 1 < now_num:
n = now_num - prev_num - 1
# Apply 7/8 reduction to prev_base_fee for the n empty blocks in a row.
now_base_fee_wide = now_base_fee * pow(1-(1/BASE_FEE_MAX_CHANGE_DENOMINATOR), n)
now_base_fee = clamp(now_base_fee_wide, min=MINIMUM_BASE_FEE, max=type(uint128).max)
require(now_bought_gas < MAX_RESOURCE_LIMIT)
store_values(now_base_fee, now_bought_gas, now_num)
```
## Rationale for burning L1 Gas
There must be a sybil resistance mechanism for usage of the network. If it is very cheap to get
guaranteed gas on L2, then it would be possible to spam the network. Burning a dynamic amount
of gas on L1 acts as a sybil resistance mechanism as it becomes more expensive with more demand.
If we collect ETH directly to pay for L2 gas, every (indirect) caller of the deposit function will need
to be marked with the payable selector. This won't be possible for many existing projects. Unfortunately
this is quite wasteful. As such, we will provide two options to buy L2 gas:
1. Burn L1 Gas
2. Send ETH to the Optimism Portal (Not yet supported)
The payable version (Option 2) will likely have discount applied to it (or conversely, #1 has a
premium applied to it).
For the initial release of bedrock, only #1 is supported.
## On Preventing Griefing Attacks
The cost of purchasing all of the deposit gas in every block must be expensive
enough to prevent attackers from griefing all deposits to the network.
An attacker would observe a deposit in the mempool and frontrun it with a deposit
that purchases enough gas such that the other deposit reverts.
The smaller the max resource limit is, the easier this attack is to pull off.
This attack is mitigated by having a large resource limit as well as a large
elasticity multiplier. This means that the target resource usage is kept small,
giving a lot of room for the deposit base fee to rise when the max resource limit
is being purchased.
This attack should be too expensive to pull off in practice, but if an extremely
wealthy adversary does decide to grief network deposits for an extended period
of time, efforts will be placed to ensure that deposits are able to be processed
on the network.
# Honest Challenger (Fault Dispute Game)
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [FDG Responses](#fdg-responses)
- [Root Claims](#root-claims)
- [Counter Claims](#counter-claims)
- [Steps](#steps)
- [Resolution](#resolution)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
The honest challenger is an agent interacting in the [Fault Dispute Game](./fault-dispute-game.md)
(FDG) that supports honest claims and disputes false claims.
An honest challenger strives to ensure a correct, truthful, game resolution.
The honest challenger is also _rational_ as any deviation from its behavior will result in
negative outcomes.
This document specifies the expected behavior of an honest challenger.
## Overview
The Honest Challenger has two primary duties:
1. Support valid root claims in Fault Dispute Games.
2. Dispute invalid root claims in Fault Dispute Games.
The honest challenger polls the `DisputeGameFactory` contract for new and on-going Fault
Dispute Games.
For verifying the legitimacy of claims, it relies on a synced, trusted rollup node
as well as a trace provider (ex: [Cannon](./cannon-fault-proof-vm.md)).
The trace provider must be configured with the [ABSOLUTE_PRESTATE](./fault-dispute-game.md#execution-trace)
of the FDG being interacted with to generate the traces needed to make truthful claims.
## FDG Responses
### Root Claims
When a `FaultDisputeGame` is created, the honest challenger has two possible correct responses
to its root claim:
1. [**Attack**](./fault-dispute-game.md#attack) if they disagree with the root claim.
The root claim commits to the entire execution trace, so the first move here is to
attack with the [ClaimHash](./fault-dispute-game.md#claims) at the midpoint
instruction within their execution trace.
2. **Do Nothing** if they agree with the root claim. They do nothing because if the root
claim is left un-countered, the game resolves to their agreement.
NOTE: The honest challenger will still track this game in order to defend any subsequent
claims made against the root claim - in effect, "playing the game".
### Counter Claims
For every claim made in a dispute game with a [game tree](./fault-dispute-game.md#game-tree)
depth in the range of `[1, MAX_DEPTH]`, the honest challenger processes them and performs
a response.
To determine the appropriate response, the challenger first needs to know which
[_team_](./fault-dispute-game.md#team-dynamics) it belongs to.
This determines the set of claims it should respond to in the FDG.
If the agent determines itself to be a Defender, which aims to support the root claim,
then it must dispute claims positioned at odd depths in the game tree.
Otherwise, it disputes claims positioned at even depths in the game tree.
This means an honest challenger only responds to claims made by the opposing team.
The next step is to determine if the claim, now known to be for the opposing team,
disputes another claim the honest challenger _agrees_ with.
An honest challenger agrees with a claim iff every other claim along its path to the
root claim commits to a valid `ClaimHash`. Put differently, an honest challenger will
avoid countering a claim if it disagrees with the path of claims leading to that
specific claim. But if the honest challenger agrees with the path leading to the claim,
then the claim is countered.
The last step is to determine whether the claim has a valid commitment (i.e. `ClaimHash`).
If the `ClaimHash` matches the honest challenger's at the same trace index, then we
disagree with the claim's stance by moving to [defend](./fault-dispute-game.md#defend).
Otherwise, the claim is [attacked](./fault-dispute-game.md#attack).
The following pseudocode illustrates the response logic.
```python
class Team(Enum):
DEFENDER = 0
CHALLENGER = 1
class Claim:
parent: Claim
position: uint64
claim_hash: ClaimHash
MAX_TRACE = 2**MAX_GAME_DEPTH
def agree_with(claim: Claim, chal_trace: List[ClaimHash, MAX_TRACE]):
if chal_trace[claim.trace_index] != claim.claim_hash:
return False
grand_parent = claim.parent.parent if claim.parent is not None else None
if grand_parent is not None:
return agree_with(grand_parent)
return True
def respond(claim: Claim, chal: Team, chal_trace: List[ClaimHash, MAX_TRACE]):
if depth(claim.position) % 2 != chal.value:
if claim.parent is None or agree_with(claim.parent, chal_trace):
if chal_trace[trace_index(claim.position)] == claim.claim_hash:
defend()
else:
attack()
else: pass # avoid supporting invalid claims on the same team
```
In attack or defense, the honest challenger submit a `ClaimHash` corresponding to the
state identified by the trace index of their response position.
The honest challenger responds to claims as soon as possible to avoid the clock of its
counter-claim from expiring.
### Steps
At the max depth of the game, claims represent commitments to the state of the fault proof VM
at a single instruction step interval.
Because the game can no longer bisect further, when the honest challenger has a valid move
against these claims (valid defined by the response in [Counter Claims](#counter-claims)),
the only option for an honest challenger is to execute a VM step on-chain to disprove the claim at `MAX_GAME_DEPTH`.
Similar to the above section, the honest challenger will issue an
[attack step](./fault-dispute-game.md#step-types) when in response to such claims with
invalid `ClaimHash` commitments. Otherwise, it issues a _defense step_.
## Resolution
When the [chess clock](./fault-dispute-game.md#game-clock) of a
[subgame root](./fault-dispute-game.md#resolution) has run out, the subgame can be resolved.
The honest challenger should resolve all subgames in bottom-up order, until the subgame
rooted at the FDG root is resolved.
The honest challenger accomplishes this by calling the `resolveClaim` function on the
`FaultDisputeGame` contract. Once the root claim's subgame is resolved,
the challenger then finally calls the `resolve` function to resolve the entire game.
The `FaultDisputeGame` does not put a time cap on resolution - because of the liveness
assumption on honest challengers and the bonds attached to the claims they’ve countered,
challengers are economically incentivized to resolve the game promptly to capture the bonds.
# Introduction
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Foundations](#foundations)
- [What is Ethereum scalability?](#what-is-ethereum-scalability)
- [What is an Optimistic Rollup?](#what-is-an-optimistic-rollup)
- [What is EVM Equivalence?](#what-is-evm-equivalence)
- [🎶 All together now 🎶](#-all-together-now-)
- [Protocol Guarantees](#protocol-guarantees)
- [Network Participants](#network-participants)
- [Users](#users)
- [Sequencers](#sequencers)
- [Verifiers](#verifiers)
- [Key Interaction Diagrams](#key-interaction-diagrams)
- [Depositing and Sending Transactions](#depositing-and-sending-transactions)
- [Withdrawing](#withdrawing)
- [Next Steps](#next-steps)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Optimism is an _EVM equivalent_, _optimistic rollup_ protocol designed to _scale Ethereum_ while remaining maximally
compatible with existing Ethereum infrastructure. This document provides an overview of the protocol to provide context
for the rest of the specification.
## Foundations
### What is Ethereum scalability?
Scaling Ethereum means increasing the number of useful transactions the Ethereum network can process. Ethereum's
limited resources, specifically bandwidth, computation, and storage, constrain the number of transactions which can be
processed on the network. Of the three resources, computation and storage are currently the most significant
bottlenecks. These bottlenecks limit the supply of transactions, leading to extremely high fees. Scaling ethereum and
reducing fees can be achieved by better utilizing bandwidth, computation and storage.
### What is an Optimistic Rollup?
[Optimistic rollup](https://vitalik.ca/general/2021/01/05/rollup.html) is a layer 2 scalability technique which
increases the computation & storage capacity of Ethereum without sacrificing security or decentralization. Transaction
data is submitted on-chain but executed off-chain. If there is an error in the off-chain execution, a fault proof can
be submitted on-chain to correct the error and protect user funds. In the same way you don't go to court unless there
is a dispute, you don't execute transactions on on-chain unless there is an error.
### What is EVM Equivalence?
[EVM Equivalence](https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306) is complete compliance
with the state transition function described in the Ethereum yellow paper, the formal definition of the protocol. By
conforming to the Ethereum standard across EVM equivalent rollups, smart contract developers can write once and deploy
anywhere.
### 🎶 All together now 🎶
**Optimism is an _EVM equivalent_, _optimistic rollup_ protocol designed to _scale Ethereum_.**
## Protocol Guarantees
In order to scale Ethereum without sacrificing security, we must preserve 3 critical properties of Ethereum layer 1:
liveness, availability, and validity.
1. **Liveness** - Anyone must be able to extend the rollup chain by sending transactions at any time.
- There are two ways transactions can be sent to the rollup chain: 1) via the sequencer, and 2) directly on layer 1.
The sequencer provides low latency & low cost transactions, while sending transactions directly to layer 1 provides
censorship resistance.
1. **Availability** - Anyone must be able to download the rollup chain.
- All information required to derive the chain is embedded into layer 1 blocks. That way as long as the layer 1
chain is available, so is the rollup.
1. **Validity** - All transactions must be correctly executed and all withdrawals correctly processed.
- The rollup state and withdrawals are managed on an L1 contract called the `L2OutputOracle`. This oracle is
guaranteed to _only_ finalize correct (ie. valid) rollup block hashes given a **single honest verifier** assumption. If
there is ever an invalid block hash asserted on layer 1, an honest verifier will prove it is invalid and win a bond.
**Footnote**: There are two main ways to enforce validity of a rollup: fault proofs (optimistic rollup) and validity
proofs (zkRollup). For the purposes of this spec we only focus on fault proofs but it is worth noting that validity
proofs can also be plugged in once they have been made feasible.
## Network Participants
There are three actors in Optimism: users, sequencers, and verifiers.
![Network Overview](./assets/network-participants-overview.svg)
### Users
At the heart of the network are users (us!). Users can:
1. Deposit or withdraw arbitrary transactions on L2 by sending data to a contract on Ethereum mainnet.
2. Use EVM smart contracts on layer 2 by sending transactions to the sequencers.
3. View the status of transactions using block explorers provided by network verifiers.
### Sequencers
The sequencer is the primary block producer.
There may be one sequencer **or** many using a consensus protocol.
For 1.0.0, there is just one sequencer (currently operated under the oversight of the Optimism Foundation).
In general, specifications may use "the sequencer" to be a stand-in term
for the consensus protocol operated by multiple sequencers.
The sequencer:
1. Accepts user off-chain transactions
2. Observes on-chain transactions (primarily, deposit events coming from L1)
3. Consolidates both kinds of transactions into L2 blocks with a specific ordering.
4. Propagates consolidated L2 blocks to L1, by submitting two things as calldata to L1:
- The pending off-chain transactions accepted in step 1.
- Sufficient information about the ordering of the on-chain transactions to successfully reconstruct the blocks
from step 3., purely by watching L1.
The sequencer also provides access to block data as early as step 3., so that users may access real-time state in
advance of L1 confirmation if they so choose.
### Verifiers
Verifiers serve two purposes:
1. Serving rollup data to users; and
2. Verifying rollup integrity and disputing invalid assertions.
In order for the network to remain secure there must be **at least** one honest verifier who is able to verify the
integrity of the rollup chain & serve blockchain data to users.
## Key Interaction Diagrams
The following diagrams demonstrate how protocol components are utilized during key user interactions in order to
provide context when diving into any particular component specification.
### Depositing and Sending Transactions
Users will often begin their L2 journey by depositing ETH from L1.
Once they have ETH to pay fees, they'll start sending transactions on L2.
The following diagram demonstrates this interaction and all key Optimism components which are or should be utilized:
![Diagram of Depositing and Sending Transactions](./assets/sequencer-handling-deposits-and-transactions.svg)
Links to components mentioned in this diagram:
<!-- - Batch Inbox (WIP) -->
- [Rollup Node](./rollup-node.md)
- [Execution Engine](./exec-engine.md)
<!-- - Sequencer Batch Submitter (WIP) -->
- [L2 Output Oracle](./proposals.md#l2-output-oracle-smart-contract)
- [L2 Output Submitter](./proposals.md#proposing-l2-output-commitments)
<!-- - Fault Proof VM (WIP) -->
### Withdrawing
Just as important as depositing, it is critical that users can withdraw from the rollup. Withdrawals are initiated by
normal transactions on L2, but then completed using a transaction on L1 after the dispute period has elapsed.
![Diagram of Withdrawing](./assets/user-withdrawing-to-l1.svg)
Links to components mentioned in this diagram:
- [L2 Output Oracle](./proposals.md#l2-output-oracle-smart-contract)
## Next Steps
This is a choose your own adventure. Are you interested in how a verifier works under the hood? Maybe you want to dive
deep into the bit flippin' Fault Proof VM? All key components have been linked at least once in this doc, so you should
now have the context you need to dive in deeper. [The world is yours](https://www.youtube.com/watch?v=e5PnuIRnJW8)!
# Cross Domain Messengers
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Message Passing](#message-passing)
- [Upgradability](#upgradability)
- [Message Versioning](#message-versioning)
- [Message Version 0](#message-version-0)
- [Message Version 1](#message-version-1)
- [Backwards Compatibility Notes](#backwards-compatibility-notes)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
The cross domain messengers are responsible for providing a higher level API for
developers who are interested in sending cross domain messages. They allow for
the ability to replay cross domain messages and sit directly on top of the lower
level system contracts responsible for cross domain messaging on L1 and L2.
The `CrossDomainMessenger` is extended to create both an
`L1CrossDomainMessenger` as well as a `L2CrossDomainMessenger`.
These contracts are then extended with their legacy APIs to provide backwards
compatibility for applications that integrated before the Bedrock system
upgrade.
The `L2CrossDomainMessenger` is a predeploy contract located at
`0x4200000000000000000000000000000000000007`.
The base `CrossDomainMessenger` interface is:
```solidity
interface CrossDomainMessenger {
event FailedRelayedMessage(bytes32 indexed msgHash);
event RelayedMessage(bytes32 indexed msgHash);
event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
event SentMessageExtension1(address indexed sender, uint256 value);
function MESSAGE_VERSION() external view returns (uint16);
function MIN_GAS_CALLDATA_OVERHEAD() external view returns (uint64);
function MIN_GAS_CONSTANT_OVERHEAD() external view returns (uint64);
function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64);
function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64);
function OTHER_MESSENGER() external view returns (address);
function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64);
function failedMessages(bytes32) external view returns (bool);
function messageNonce() external view returns (uint256);
function relayMessage(
uint256 _nonce,
address _sender,
address _target,
uint256 _value,
uint256 _minGasLimit,
bytes memory _message
) external payable;
function sendMessage(address _target, bytes memory _message, uint32 _minGasLimit) external payable;
function successfulMessages(bytes32) external view returns (bool);
function xDomainMessageSender() external view returns (address);
}
```
## Message Passing
The `sendMessage` function is used to send a cross domain message. To trigger
the execution on the other side, the `relayMessage` function is called.
Successful messages have their hash stored in the `successfulMessages` mapping
while unsuccessful messages have their hash stored in the `failedMessages`
mapping.
The user experience when sending from L1 to L2 is a bit different than when
sending a transaction from L2 to L1. When going into L1 from L2, the user does
not need to call `relayMessage` on L2 themselves. The user pays for L2 gas on L1
and the transaction is automatically pulled into L2 where it is executed on L2.
When going from L2 into L1, the user proves their withdrawal on OptimismPortal,
then waits for the finalization window to pass, and then finalizes the withdrawal
on the OptimismPortal, which calls `relayMessage` on the
`L1CrossDomainMessenger` to finalize the withdrawal.
## Upgradability
The L1 and L2 cross domain messengers should be deployed behind upgradable
proxies. This will allow for updating the message version.
## Message Versioning
Messages are versioned based on the first 2 bytes of their nonce. Depending on
the version, messages can have a different serialization and hashing scheme.
The first two bytes of the nonce are reserved for version metadata because
a version field was not originally included in the messages themselves, but
a `uint256` nonce is so large that we can very easily pack additional data
into that field.
### Message Version 0
```solidity
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_message,
_messageNonce
);
```
### Message Version 1
```solidity
abi.encodeWithSignature(
"relayMessage(uint256,address,address,uint256,uint256,bytes)",
_nonce,
_sender,
_target,
_value,
_gasLimit,
_data
);
```
## Backwards Compatibility Notes
An older version of the messenger contracts had the concept of blocked messages
in a `blockedMessages` mapping. This functionality was removed from the
messengers because a smart attacker could get around any message blocking
attempts. It also saves gas on finalizing withdrawals.
The concept of a "relay id" and the `relayedMessages` mapping was removed.
It was built as a way to be able to fund third parties who relayed messages
on the behalf of users, but it was improperly implemented as it was impossible
to know if the relayed message actually succeeded.
<!-- DOCTOC SKIP -->
# Meta Processes
This directory describes processes that we use to lint/test the specification.
- [Linting](linting.md): how to lint source files.
- [Markdown Style Guide](markdown-style.md): how to format and structure Markdown files.
- [Devnet introduction](devnet.md): how to run a devnet.
<!-- DOCTOC SKIP -->
# Bedrock Local Devnet Setup
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Bedrock Local Devnet Setup](#bedrock-local-devnet-setup)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
You can spin up a local devnet via `docker compose`.
For convenience, we have defined `make` targets to start and stop the devnet with a single command.
To run the devnet, you will need `docker` installed.
Then, as a precondition, make sure that you have compiled the contracts by `cd`ing into `packages/contracts-bedrock`
and running `pnpm i` followed by `pnpm build`. You'll only need to do this if you change the contracts in the future.
Then, run the following:
```bash
make devnet-up # starts the devnet
make devnet-down # stops the devnet
make devnet-clean # removes the devnet by deleting images and persistent volumes
```
L1 is accessible at `http://localhost:8545`, and L2 is accessible at `http://localhost:9545`.
Any Ethereum tool - Metamask, `seth`, etc. - can use these endpoints.
Note that you will need to specify the L2 chain ID manually if you use Metamask. The devnet's L2 chain ID is 901.
The devnet comes with a pre-funded account you can use as a faucet:
- Address: `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266`
- Private key: `ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`
The faucet account exists on both L1 and L2. To deposit onto L2 from L1, you can use the `deposit` hardhat task.
Run the following from the `packages/contracts` directory:
```bash
npx hardhat deposit --amount-eth <amount in eth> --to <address>
````
You'll need a `.env` with the following contents:
```bash
L1_PROVIDER_URL=http://localhost:8545
L2_PROVIDER_URL=http://localhost:9545
PRIVATE_KEY=bf7604d9d3a1c7748642b1b7b05c2bd219c9faa91458b370f85e5a40f3b03af7
```
The batch submitter uses the account below to submit batches to L1:
- Address: `0xde3829a23df1479438622a08a116e8eb3f620bb5`
- Private key: `bf7604d9d3a1c7748642b1b7b05c2bd219c9faa91458b370f85e5a40f3b03af7`
# Linting
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Markdown](#markdown)
- [Go](#go)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Markdown
See
- [markdownlint rule reference](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md)
- [example .markdownlint.json file](https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc)
Justification for linting rules in [.markdownlint.json](/.markdownlint.json):
- *line_length* (`!strict && stern`): don't trip up on url lines
- *no-blanks-blockquote*: enable multiple consecutive blockquotes separated by white lines
- *single-title*: enable reusing `<h1>` for content
- *no-emphasis-as-heading*: enable emphasized paragraphs
```shell
pnpm i # Install dependencies
pnpm lint:specs:check # Run linter
pnpm lint:specs:fix # Fix lint issues
pnpm lint:specs:toc # Update TOC docs
# Check links
docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback --exclude twitter.com --exclude-mail /input/README.md "/input/specs/**/*.md"
```
To check links, you'll need to install [lychee]. The [version ran in CI][lychee-ci] is 0.8.1, but
you should install lychee 0.8.2 locally with `cargo install --version 0.8.2 lychee` (there are some
reported build problems with 0.8.1).
You can install cargo (the Rust package manager) via [rustup].
[lychee]: https://github.com/lycheeverse/lychee
[lychee-ci]: https://github.com/lycheeverse/lychee-action/blob/f76b8412c668f78311212d16d33c4784a7d8762c/Dockerfile
[rustup]: https://www.rust-lang.org/tools/install
To update the TOC, we run [doctoc], installed through the dev-dependencies in `package.json`.
[doctoc]: https://github.com/thlorenz/doctoc
## Go
See
- [golangci-lint docs](https://golangci-lint.run/usage/install/#local-installation)
- [golangci-lint github](https://github.com/golangci/golangci-lint)
- [github action github](https://github.com/golangci/golangci-lint-action)
Justification for linting rules:
- *asciicheck*: no symbol names with invisible unicode and such
- *goimports*: group local and external import
```shell
# Install linter globally (should not affect go.mod)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0
# run linter, add --fix option to fix problems (where supported)
golangci-lint run -E goimports,sqlclosecheck,bodyclose,asciicheck,misspell,errorlint --timeout 2m -e "errors.As" -e "errors.Is" ./...
```
# Markdown Style Guide
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Linting](#linting)
- [Links](#links)
- [Glossary](#glossary)
- [Internal (In-File) Links](#internal-in-file-links)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Linting
Respect the [linting rules] (you can run the linter with `pnpm lint`).
Notably:
- lines should be < 120 characters long
- in practice, some of our files are justified at 100 characters, some at 120
[linting rules]: linting.md#markdown
## Links
In general:
- Use link references preferentially.
- e.g. `[my text][link-ref]` and then on its own line `[link-ref]: https://mylink.com`
- e.g. `[my text]` and then on its own line: `[my text]: https://mylink.com`
- exceptions: where it fits neatly on a single line, in particular in lists of links
- Excepted for internal and glossary links (see below), add the link reference definition directly
after the paragraph where the link first appears.
### Glossary
- Use links to the [glossary] liberally.
- Include the references to all the glossary links at the top of the file, under the top-level
title.
- A glossary link reference should start with the `g-` prefix. This enables to see what links to the
glossary at a glance when editing the specification.
- e.g. `[g-block]: glossary.md#block`
- Example: [Rollup Node Specification source][rollup-node]
[glossary]: ../glossary.md
[rollup-node]: https://raw.githubusercontent.com/ethereum-optimism/optimistic-specs/main/specs/rollup-node.md
## Internal (In-File) Links
If linking to another heading to the same file, add the link reference directly under that heading.
This makes it easier to keep the heading and the link in-sync, and signals that the heading is being
linked to from elsewhere.
# Versioning
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Go modules](#go-modules)
- [versioning process](#versioning-process)
- [Typescript](#typescript)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Go modules
Go modules that are currently versioned:
```text
./op-service
./op-bindings
./op-batcher
./op-node
./op-proposer
./op-e2e
```
Go modules which are not yet versioned:
```text
./indexer (changesets)
./proxyd (changesets)
```
### versioning process
Since changesets versioning is not compatible with Go we are moving away from it.
Starting with new bedrock modules, Go-compatible tags will be used,
formatted as `modulename/vX.Y.Z` where `vX.Y.Z` is semver.
## Typescript
See Changesets.
# Optimism Overview
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Architecture Design Goals](#architecture-design-goals)
- [Components](#components)
- [L1 Components](#l1-components)
- [L2 Components](#l2-components)
- [Transaction/Block Propagation](#transactionblock-propagation)
- [Key Interactions In Depth](#key-interactions-in-depth)
- [Deposits](#deposits)
- [Block Derivation](#block-derivation)
- [Overview](#overview)
- [Epochs and the Sequencing Window](#epochs-and-the-sequencing-window)
- [Block Derivation Loop](#block-derivation-loop)
- [Engine API](#engine-api)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
This document is a high-level technical overview of the Optimism protocol. It aims to explain how the protocol works in
an informal manner, and direct readers to other parts of the specification so that they may learn more.
This document assumes you've read the [introduction](./introduction.md).
## Architecture Design Goals
- **Execution-Level EVM Equivalence:** The developer experience should be identical to L1 except where L2 introduces a
fundamental difference.
- No special compiler.
- No unexpected gas costs.
- Transaction traces work out-of-the-box.
- All existing Ethereum tooling works - all you have to do is change the chain ID.
- **Maximal compatibility with ETH1 nodes:** The implementation should minimize any differences with a vanilla Geth
node, and leverage as many existing L1 standards as possible.
- The execution engine/rollup node uses the ETH2 Engine API to build the canonical L2 chain.
- The execution engine leverages Geth's existing mempool and sync implementations, including snap sync.
- **Minimize state and complexity:**
- Whenever possible, services contributing to the rollup infrastructure are stateless.
- Stateful services can recover to full operation from a fresh DB using the peer-to-peer network and on-chain sync
mechanisms.
- Running a replica is as simple as running a Geth node.
## Components
![Components](./assets/components.svg)
### L1 Components
- **OptimismPortal**: A feed of L2 transactions which originated as smart contract calls in the L1 state.
- The `OptimismPortal` contract emits `TransactionDeposited` events, which the rollup driver reads in order to process
deposits.
- Deposits are guaranteed to be reflected in the L2 state within the _sequencing window_.
- Beware that _transactions_ are deposited, not tokens. However deposited transactions are a key part of implementing
token deposits (tokens are locked on L1, then minted on L2 via a deposited transaction).
- **BatchInbox**: An L1 address to which the Batch Submitter submits transaction batches.
- Transaction batches include L2 transaction calldata, timestamps, and ordering information.
- The BatchInbox is a regular EOA address. This lets us pass on gas cost savings by not executing any EVM code.
- **L2OutputOracle**: A smart contract that stores [L2 output roots](./glossary.md#l2-output) for use with withdrawals
and fault proofs.
### L2 Components
- **Rollup Node**:
- A standalone, stateless binary.
- Receives L2 transactions from users.
- Syncs and verifies rollup data on L1.
- Applies rollup-specific block production rules to synthesize blocks from L1.
- Appends blocks to the L2 chain using the Engine API.
- Handles L1 reorgs.
- Distributes unsubmitted blocks to other rollup nodes.
- **Execution Engine (EE)**:
- A vanilla Geth node with minor modifications to support Optimism.
- Maintains L2 state.
- Sync state to other L2 nodes for fast onboarding.
- Serves the Engine API to the rollup node.
- **Batch Submitter**
- A background process that submits [transaction batches](./glossary.md#sequencer-batch) to the `BatchInbox` address.
- **Output Submitter**
- A background process that submits L2 output commitments to the `L2OutputOracle`.
### Transaction/Block Propagation
**Spec links:**
- [Execution Engine](./exec-engine.md)
Since the EE uses Geth under the hood, Optimism uses Geth's built-in peer-to-peer network and transaction pool to
propagate transactions. The same network can also be used to propagate submitted blocks and support snap-sync.
Unsubmitted blocks, however, are propagated using a separate peer-to-peer network of Rollup Nodes. This is optional,
however, and is provided as a convenience to lower latency for verifiers and their JSON-RPC clients.
The below diagram illustrates how the sequencer and verifiers fit together:
![Propagation](./assets/propagation.svg)
## Key Interactions In Depth
### Deposits
**Spec links:**
- [Deposits](./deposits.md)
Optimism supports two types of deposits: user deposits, and L1 attributes deposits. To perform a user deposit, users
call the `depositTransaction` method on the `OptimismPortal` contract. This in turn emits `TransactionDeposited` events,
which the rollup node reads during block derivation.
L1 attributes deposits are used to register L1 block attributes (number, timestamp, etc.) on L2 via a call to the L1
Attributes Predeploy. They cannot be initiated by users, and are instead added to L2 blocks automatically by the rollup
node.
Both deposit types are represented by a single custom EIP-2718 transaction type on L2.
### Block Derivation
#### Overview
The rollup chain can be deterministically derived given an L1 Ethereum chain. The fact that the entire rollup chain can
be derived based on L1 blocks is _what makes Optimism a rollup_. This process can be represented as:
```text
derive_rollup_chain(l1_blockchain) -> rollup_blockchain
```
Optimism's block derivation function is designed such that it:
- Requires no state other than what is easily accessible using L1 and L2 execution engine APIs.
- Supports sequencers and sequencer consensus.
- Is resilient to sequencer censorship.
#### Epochs and the Sequencing Window
The rollup chain is subdivided into epochs. There is a 1:1 correspondence between L1 block numbers and epoch numbers.
For L1 block number `n`, there is a corresponding rollup epoch `n` which can only be derived after a _sequencing window_
worth of blocks has passed, i.e. after L1 block number `n + SEQUENCING_WINDOW_SIZE` is added to the L1 chain.
Each epoch contains at least one block. Every block in the epoch contains an L1 info transaction which contains
contextual information about L1 such as the block hash and timestamp. The first block in the epoch also contains all
deposits initiated via the `OptimismPortal` contract on L1. All L2 blocks can also contain _sequenced transactions_,
i.e. transactions submitted directly to the sequencer.
Whenever the sequencer creates a new L2 block for a given epoch, it must submit it to L1 as part of a _batch_, within
the epoch's sequencing window (i.e. the batch must land before L1 block `n + SEQUENCING_WINDOW_SIZE`). These batches are
(along with the `TransactionDeposited` L1 events) what allows the derivation of the L2 chain from the L1 chain.
The sequencer does not need for a L2 block to be batch-submitted to L1 in order to build on top of it. In fact, batches
typically contain multiple L2 blocks worth of sequenced transactions. This is what enables
_fast transaction confirmations_ on the sequencer.
Since transaction batches for a given epoch can be submitted anywhere within the sequencing window, verifiers must
search all blocks within the window for transaction batches. This protects against the uncertainty of transaction
inclusion of L1. This uncertainty is also why we need the sequencing window in the first place: otherwise the sequencer
could retroactively add blocks to an old epoch, and validators wouldn't know when they can finalize an epoch.
The sequencing window also prevents censorship by the sequencer: deposits made on a given L1 block will be included in
the L2 chain at worst after `SEQUENCING_WINDOW_SIZE` L1 blocks have passed.
The following diagram describes this relationship, and how L2 blocks are derived from L1 blocks (L1 info transactions
have been elided):
![Epochs and Sequencing Windows](./assets/sequencer-block-gen.svg)
#### Block Derivation Loop
A sub-component of the rollup node called the _rollup driver_ is actually responsible for performing block derivation.
The rollup driver is essentially an infinite loop that runs the block derivation function. For each epoch, the block
derivation function performs the following steps:
1. Downloads deposit and transaction batch data for each block in the sequencing window.
2. Converts the deposit and transaction batch data into payload attributes for the Engine API.
3. Submits the payload attributes to the Engine API, where they are converted into blocks and added to the canonical
chain.
This process is then repeated with incrementing epochs until the tip of L1 is reached.
### Engine API
The rollup driver doesn't actually create blocks. Instead, it directs the execution engine to do so via the Engine API.
For each iteration of the block derivation loop described above, the rollup driver will craft a _payload attributes_
object and send it to the execution engine. The execution engine will then convert the payload attributes object into a
block, and add it to the chain. The basic sequence of the rollup driver is as follows:
1. Call [fork choice updated][EngineAPIVersion] with the payload attributes object. We'll skip over the details of the
fork choice state parameter for now - just know that one of its fields is the L2 chain's `headBlockHash`, and that it
is set to the block hash of the tip of the L2 chain. The Engine API returns a payload ID.
2. Call [get payload][EngineAPIVersion] with the payload ID returned in step 1. The engine API returns a payload object
that includes a block hash as one of its fields.
3. Call [new payload][EngineAPIVersion] with the payload returned in step 2. (Ectone blocks, must use V3, pre-Ecotone
blocks MUST use the V2 version)
4. Call [fork choice updated][EngineAPIVersion] with the fork choice parameter's `headBlockHash` set to the block hash
returned in step 2. The tip of the L2 chain is now the block created in step 1.
[EngineAPIVersion]: derivation.md#engine-api-usage
The swimlane diagram below visualizes the process:
![Engine API](./assets/engine.svg)
# Predeploys
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [LegacyMessagePasser](#legacymessagepasser)
- [L2ToL1MessagePasser](#l2tol1messagepasser)
- [DeployerWhitelist](#deployerwhitelist)
- [LegacyERC20ETH](#legacyerc20eth)
- [WETH9](#weth9)
- [L2CrossDomainMessenger](#l2crossdomainmessenger)
- [L2StandardBridge](#l2standardbridge)
- [L1BlockNumber](#l1blocknumber)
- [GasPriceOracle](#gaspriceoracle)
- [L1Block](#l1block)
- [ProxyAdmin](#proxyadmin)
- [SequencerFeeVault](#sequencerfeevault)
- [OptimismMintableERC20Factory](#optimismmintableerc20factory)
- [OptimismMintableERC721Factory](#optimismmintableerc721factory)
- [BaseFeeVault](#basefeevault)
- [L1FeeVault](#l1feevault)
- [SchemaRegistry](#schemaregistry)
- [EAS](#eas)
- [create2Deployer](#create2deployer)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
[Predeployed smart contracts](./glossary.md#predeployed-contract-predeploy) exist on Optimism
at predetermined addresses in the genesis state. They are similar to precompiles but instead run
directly in the EVM instead of running native code outside of the EVM.
Predeploys are used instead of precompiles to make it easier for multiclient
implementations as well as allowing for more integration with hardhat/foundry
network forking.
Predeploy addresses exist in 1 byte namespace `0x42000000000000000000000000000000000000xx`.
Proxies are set at each possible predeploy address except for the
`GovernanceToken` and the `ProxyAdmin`.
The `LegacyERC20ETH` predeploy lives at a special address `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000`
and there is no proxy deployed at that account.
The following table includes each of the predeploys. The system version
indicates when the predeploy was introduced. The possible values are `Legacy`
or `Bedrock` or `Canyon`. Deprecated contracts should not be used.
| Name | Address | Introduced | Deprecated | Proxied |
| ----------------------------------------- | ------------------------------------------ | ----------- | ---------- | ------- |
| LegacyMessagePasser | 0x4200000000000000000000000000000000000000 | Legacy | Yes | Yes |
| DeployerWhitelist | 0x4200000000000000000000000000000000000002 | Legacy | Yes | Yes |
| LegacyERC20ETH | 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 | Legacy | Yes | No |
| WETH9 | 0x4200000000000000000000000000000000000006 | Legacy | No | No |
| L2CrossDomainMessenger | 0x4200000000000000000000000000000000000007 | Legacy | No | Yes |
| L2StandardBridge | 0x4200000000000000000000000000000000000010 | Legacy | No | Yes |
| SequencerFeeVault | 0x4200000000000000000000000000000000000011 | Legacy | No | Yes |
| OptimismMintableERC20Factory | 0x4200000000000000000000000000000000000012 | Legacy | No | Yes |
| L1BlockNumber | 0x4200000000000000000000000000000000000013 | Legacy | Yes | Yes |
| GasPriceOracle | 0x420000000000000000000000000000000000000F | Legacy | No | Yes |
| GovernanceToken | 0x4200000000000000000000000000000000000042 | Legacy | No | No |
| L1Block | 0x4200000000000000000000000000000000000015 | Bedrock | No | Yes |
| L2ToL1MessagePasser | 0x4200000000000000000000000000000000000016 | Bedrock | No | Yes |
| L2ERC721Bridge | 0x4200000000000000000000000000000000000014 | Legacy | No | Yes |
| OptimismMintableERC721Factory | 0x4200000000000000000000000000000000000017 | Bedrock | No | Yes |
| ProxyAdmin | 0x4200000000000000000000000000000000000018 | Bedrock | No | Yes |
| BaseFeeVault | 0x4200000000000000000000000000000000000019 | Bedrock | No | Yes |
| L1FeeVault | 0x420000000000000000000000000000000000001a | Bedrock | No | Yes |
| SchemaRegistry | 0x4200000000000000000000000000000000000020 | Bedrock | No | Yes |
| EAS | 0x4200000000000000000000000000000000000021 | Bedrock | No | Yes |
| create2Deployer | 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2 | Canyon | No | No |
## LegacyMessagePasser
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/LegacyMessagePasser.sol)
Address: `0x4200000000000000000000000000000000000000`
The `LegacyMessagePasser` contract stores commitments to withdrawal
transactions before the Bedrock upgrade. A merkle proof to a particular
storage slot that commits to the withdrawal transaction is used as part
of the withdrawing transaction on L1. The expected account that includes
the storage slot is hardcoded into the L1 logic. After the bedrock upgrade,
the `L2ToL1MessagePasser` is used instead. Finalizing withdrawals from this
contract will no longer be supported after the Bedrock and is only left
to allow for alternative bridges that may depend on it. This contract does
not forward calls to the `L2ToL1MessagePasser` and calling it is considered
a no-op in context of doing withdrawals through the `CrossDomainMessenger`
system.
Any pending withdrawals that have not been finalized are migrated to the
`L2ToL1MessagePasser` as part of the upgrade so that they can still be
finalized.
## L2ToL1MessagePasser
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL1MessagePasser.sol)
Address: `0x4200000000000000000000000000000000000016`
The `L2ToL1MessagePasser` stores commitments to withdrawal transactions.
When a user is submitting the withdrawing transaction on L1, they provide a
proof that the transaction that they withdrew on L2 is in the `sentMessages`
mapping of this contract.
Any withdrawn ETH accumulates into this contract on L2 and can be
permissionlessly removed from the L2 supply by calling the `burn()` function.
## DeployerWhitelist
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/DeployerWhitelist.sol)
Address: `0x4200000000000000000000000000000000000002`
The `DeployerWhitelist` is a predeploy that was used to provide additional safety
during the initial phases of Optimism.
It previously defined the accounts that are allowed to deploy contracts to the network.
Arbitrary contract deployment was subsequently enabled and it is not possible to turn
off. In the legacy system, this contract was hooked into `CREATE` and
`CREATE2` to ensure that the deployer was allowlisted.
In the Bedrock system, this contract will no longer be used as part of the
`CREATE` codepath.
This contract is deprecated and its usage should be avoided.
## LegacyERC20ETH
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/LegacyERC20ETH.sol)
Address: `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000`
The `LegacyERC20ETH` predeploy represents all ether in the system before the
Bedrock upgrade. All ETH was represented as an ERC20 token and users could opt
into the ERC20 interface or the native ETH interface.
The upgrade to Bedrock migrates all ether out of this contract and moves it to
its native representation. All of the stateful methods in this contract will
revert after the Bedrock upgrade.
This contract is deprecated and its usage should be avoided.
## WETH9
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/vendor/WETH9.sol)
Address: `0x4200000000000000000000000000000000000006`
`WETH9` is the standard implementation of Wrapped Ether on Optimism. It is a
commonly used contract and is placed as a predeploy so that it is at a
deterministic address across Optimism based networks.
## L2CrossDomainMessenger
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol)
Address: `0x4200000000000000000000000000000000000007`
The `L2CrossDomainMessenger` gives a higher level API for sending cross domain
messages compared to directly calling the `L2ToL1MessagePasser`.
It maintains a mapping of L1 messages that have been relayed to L2
to prevent replay attacks and also allows for replayability if the L1 to L2
transaction reverts on L2.
Any calls to the `L1CrossDomainMessenger` on L1 are serialized such that they
go through the `L2CrossDomainMessenger` on L2.
The `relayMessage` function executes a transaction from the remote domain while
the `sendMessage` function sends a transaction to be executed on the remote
domain through the remote domain's `relayMessage` function.
## L2StandardBridge
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2StandardBridge.sol)
Address: `0x4200000000000000000000000000000000000010`
The `L2StandardBridge` is a higher level API built on top of the
`L2CrossDomainMessenger` that gives a standard interface for sending ETH or
ERC20 tokens across domains.
To deposit a token from L1 to L2, the `L1StandardBridge` locks the token and
sends a cross domain message to the `L2StandardBridge` which then mints the
token to the specified account.
To withdraw a token from L2 to L1, the user will burn the token on L2 and the
`L2StandardBridge` will send a message to the `L1StandardBridge` which will
unlock the underlying token and transfer it to the specified account.
The `OptimismMintableERC20Factory` can be used to create an ERC20 token contract
on a remote domain that maps to an ERC20 token contract on the local domain
where tokens can be deposited to the remote domain. It deploys an
`OptimismMintableERC20` which has the interface that works with the
`StandardBridge`.
This contract can also be deployed on L1 to allow for L2 native tokens to be
withdrawn to L1.
## L1BlockNumber
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/legacy/L1BlockNumber.sol)
Address: `0x4200000000000000000000000000000000000013`
The `L1BlockNumber` returns the last known L1 block number. This contract was
introduced in the legacy system and should be backwards compatible by calling
out to the `L1Block` contract under the hood.
It is recommended to use the `L1Block` contract for getting information about
L1 on L2.
## GasPriceOracle
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/GasPriceOracle.sol)
Address: `0x420000000000000000000000000000000000000F`
In the legacy system, the `GasPriceOracle` was a permissioned contract
that was pushed the L1 base fee and the L2 gas price by an offchain actor.
The offchain actor observes the L1 blockheaders to get the
L1 base fee as well as the gas usage on L2 to compute what the L2 gas price
should be based on a congestion control algorithm.
After Bedrock, the `GasPriceOracle` is no longer a permissioned contract
and only exists to preserve the API for offchain gas estimation. The
function `getL1Fee(bytes)` accepts an unsigned RLP transaction and will return
the L1 portion of the fee. This fee pays for using L1 as a data availability
layer and should be added to the L2 portion of the fee, which pays for
execution, to compute the total transaction fee.
The values used to compute the L1 portion of the fee prior to the Ecotone upgrade are:
- scalar
- overhead
- decimals
After the Bedrock upgrade, these values are instead managed by the
`SystemConfig` contract on L1. The `scalar` and `overhead` values
are sent to the `L1Block` contract each block and the `decimals` value
has been hardcoded to 6.
Following the Ecotone upgrade, the values used for L1 fee computation are:
- l1BaseFeeScalar
- l1BlobBaseFeeScalar
- decimals
These values are managed by the `SystemConfig` contract on the L1. The`decimals` remains hardcoded
to 6, and the old `scalar` and `overhead` values are ignored.
## L1Block
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L1Block.sol)
Address: `0x4200000000000000000000000000000000000015`
[l1-block-predeploy]: glossary.md#l1-attributes-predeployed-contract
The [L1Block][l1-block-predeploy] was introduced in Bedrock and is responsible for
maintaining L1 context in L2. This allows for L1 state to be accessed in L2.
## ProxyAdmin
[ProxyAdmin](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/ProxyAdmin.sol)
Address: `0x4200000000000000000000000000000000000018`
The `ProxyAdmin` is the owner of all of the proxy contracts set at the
predeploys. It is itself behind a proxy. The owner of the `ProxyAdmin` will
have the ability to upgrade any of the other predeploy contracts.
## SequencerFeeVault
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SequencerFeeVault.sol)
Address: `0x4200000000000000000000000000000000000011`
The `SequencerFeeVault` accumulates any transaction priority fee and is the value of
`block.coinbase`.
When enough fees accumulate in this account, they can be withdrawn to an immutable L1 address.
To change the L1 address that fees are withdrawn to, the contract must be
upgraded by changing its proxy's implementation key.
## OptimismMintableERC20Factory
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/OptimismMintableERC20Factory.sol)
Address: `0x4200000000000000000000000000000000000012`
The `OptimismMintableERC20Factory` is responsible for creating ERC20 contracts on L2 that can be
used for depositing native L1 tokens into. These ERC20 contracts can be created permisionlessly
and implement the interface required by the `StandardBridge` to just work with deposits and withdrawals.
Each ERC20 contract that is created by the `OptimismMintableERC20Factory` allows for the `L2StandardBridge` to mint
and burn tokens, depending on if the user is depositing from L1 to L2 or withdrawing from L2 to L1.
## OptimismMintableERC721Factory
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/universal/OptimismMintableERC721Factory.sol)
Address: `0x4200000000000000000000000000000000000017`
The `OptimismMintableERC721Factory` is responsible for creating ERC721 contracts on L2 that can be used for
depositing native L1 NFTs into.
## BaseFeeVault
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/BaseFeeVault.sol)
Address: `0x4200000000000000000000000000000000000019`
The `BaseFeeVault` predeploy receives the base fees on L2. The base fee is not
burnt on L2 like it is on L1. Once the contract has received a certain amount
of fees, the ETH can be withdrawn to an immutable address on
L1.
## L1FeeVault
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L1FeeVault.sol)
Address: `0x420000000000000000000000000000000000001a`
The `L1FeeVault` predeploy receives the L1 portion of the transaction fees.
Once the contract has received a certain amount of fees, the ETH can be
withdrawn to an immutable address on L1.
## SchemaRegistry
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/EAS/SchemaRegistry.sol)
Address: `0x4200000000000000000000000000000000000020`
The `SchemaRegistry` predeploy implements the global attestation schemas for the `Ethereum Attestation Service`
protocol.
## EAS
[Implementation](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/EAS/EAS.sol)
Address: `0x4200000000000000000000000000000000000021`
The `EAS` predeploy implements the `Ethereum Attestation Service` protocol.
## create2Deployer
[Implementation](https://github.com/mdehoog/create2deployer/blob/69b9a8e112b15f9257ce8c62b70a09914e7be29c/contracts/Create2Deployer.sol)
The create2Deployer is a nice Solidity wrapper around the CREATE2 opcode. It provides the following ABI.
```solidity
/**
* @dev Deploys a contract using `CREATE2`. The address where the
* contract will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `value`.
* - if `value` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 value, bytes32 salt, bytes memory code) public;
/**
* @dev Deployment of the {ERC1820Implementer}.
* Further information: https://eips.ethereum.org/EIPS/eip-1820
*/
function deployERC1820Implementer(uint256 value, bytes32 salt);
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}.
* Any change in the `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 codeHash) public view returns (address);
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a
* contract located at `deployer`. If `deployer` is this contract's address, returns the
* same value as {computeAddress}.
*/
function computeAddressWithDeployer(
bytes32 salt,
bytes32 codeHash,
address deployer
) public pure returns (address);
```
Address: `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2`
When Canyon activates, the contract code at `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2` is set to
`0x6080604052600436106100435760003560e01c8063076c37b21461004f578063481286e61461007157806356299481146100ba57806366cfa057146100da57600080fd5b3661004a57005b600080fd5b34801561005b57600080fd5b5061006f61006a366004610327565b6100fa565b005b34801561007d57600080fd5b5061009161008c366004610327565b61014a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100c657600080fd5b506100916100d5366004610349565b61015d565b3480156100e657600080fd5b5061006f6100f53660046103ca565b610172565b61014582826040518060200161010f9061031a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604052610183565b505050565b600061015683836102e7565b9392505050565b600061016a8484846102f0565b949350505050565b61017d838383610183565b50505050565b6000834710156101f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064015b60405180910390fd5b815160000361025f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101eb565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101eb565b60006101568383305b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b61014e806104ad83390190565b6000806040838503121561033a57600080fd5b50508035926020909101359150565b60008060006060848603121561035e57600080fd5b8335925060208401359150604084013573ffffffffffffffffffffffffffffffffffffffff8116811461039057600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156103df57600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561040557600080fd5b818601915086601f83011261041957600080fd5b81358181111561042b5761042b61039b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156104715761047161039b565b8160405282815289602084870101111561048a57600080fd5b826020860160208301376000602084830101528095505050505050925092509256fe608060405234801561001057600080fd5b5061012e806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063249cb3fa14602d575b600080fd5b603c603836600460b1565b604e565b60405190815260200160405180910390f35b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff16608857600060aa565b7fa2ef4600d742022d532d4747cb3547474667d6f13804902513b2ec01c848f4b45b9392505050565b6000806040838503121560c357600080fd5b82359150602083013573ffffffffffffffffffffffffffffffffffffffff8116811460ed57600080fd5b80915050925092905056fea26469706673582212205ffd4e6cede7d06a5daf93d48d0541fc68189eeb16608c1999a82063b666eb1164736f6c63430008130033a2646970667358221220fdc4a0fe96e3b21c108ca155438d37c9143fb01278a3c1d274948bad89c564ba64736f6c63430008130033`.
# Preinstalls
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Overview](#overview)
- [Safe](#safe)
- [SafeL2](#safel2)
- [MultiSend](#multisend)
- [MultiSendCallOnly](#multisendcallonly)
- [SafeSingletonFactory](#safesingletonfactory)
- [Multicall3](#multicall3)
- [Arachnid's Deterministic Deployment Proxy](#arachnids-deterministic-deployment-proxy)
- [Permit2](#permit2)
- [ERC-4337 EntryPoint](#erc-4337-entrypoint)
- [ERC-4337 SenderCreator](#erc-4337-sendercreator)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Overview
[Preinstalled smart contracts](./glossary.md#preinstalled-contract-preinstall) exist on Optimism
at predetermined addresses in the genesis state. They are similar to precompiles but instead run
directly in the EVM instead of running native code outside of the EVM and are developed by third
parties unaffiliated with the Optimism Collective.
These preinstalls are commonly deployed smart contracts that are being placed at genesis for convenience.
It's important to note that these contracts do not have the same security guarantees
as [Predeployed smart contracts](./glossary.md#predeployed-contract-predeploy).
The following table includes each of the preinstalls.
| Name | Address |
| ----------------------------------------- | ------------------------------------------ |
| Safe | 0x69f4D1788e39c87893C980c06EdF4b7f686e2938 |
| SafeL2 | 0xfb1bffC9d739B8D520DaF37dF666da4C687191EA |
| MultiSend | 0x998739BFdAAdde7C933B942a68053933098f9EDa |
| MultiSendCallOnly | 0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B |
| SafeSingletonFactory | 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7 |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 |
| Arachnid's Deterministic Deployment Proxy | 0x4e59b44847b379578588920cA78FbF26c0B4956C |
| Permit2 | 0x000000000022D473030F116dDEE9F6B43aC78BA3 |
| ERC-4337 EntryPoint | 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 |
| ERC-4337 SenderCreator | 0x7fc98430eaedbb6070b35b39d798725049088348 |
## Safe
[Implementation](https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/GnosisSafe.sol)
Address: `0x69f4D1788e39c87893C980c06EdF4b7f686e2938`
A multisignature wallet with support for confirmations using signed messages based on ERC191.
Differs from [SafeL2](#safel2) by not emitting events to save gas.
## SafeL2
[Implementation](https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/GnosisSafeL2.sol)
Address: `0xfb1bffC9d739B8D520DaF37dF666da4C687191EA`
A multisignature wallet with support for confirmations using signed messages based on ERC191.
Differs from [Safe](#safe) by emitting events.
## MultiSend
[Implementation](https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/libraries/MultiSend.sol)
Address: `0x998739BFdAAdde7C933B942a68053933098f9EDa`
Allows to batch multiple transactions into one.
## MultiSendCallOnly
[Implementation](https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/libraries/MultiSendCallOnly.sol)
Address: `0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B`
Allows to batch multiple transactions into one, but only calls.
## SafeSingletonFactory
[Implementation](https://github.com/safe-global/safe-singleton-factory/blob/v1.0.17/source/deterministic-deployment-proxy.yul)
Address: `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7`
Singleton factory used by Safe-related contracts based on
[Arachnid's Deterministic Deployment Proxy](#arachnids-deterministic-deployment-proxy).
The original library used a pre-signed transaction without a chain ID to allow deployment on different chains.
Some chains do not allow such transactions to be submitted; therefore, this contract will provide the same factory
that can be deployed via a pre-signed transaction that includes the chain ID. The key that is used to sign is
controlled by the Safe team.
## Multicall3
[Implementation](https://github.com/mds1/multicall/blob/v3.1.0/src/Multicall3.sol)
Address: `0xcA11bde05977b3631167028862bE2a173976CA11`
`Multicall3` has two main use cases:
- Aggregate results from multiple contract reads into a single JSON-RPC request.
- Execute multiple state-changing calls in a single transaction.
## Arachnid's Deterministic Deployment Proxy
[Implementation](https://github.com/Arachnid/deterministic-deployment-proxy/blob/v1.0.0/source/deterministic-deployment-proxy.yul)
Address: `0x4e59b44847b379578588920cA78FbF26c0B4956C`
This contract can deploy other contracts with a deterministic address on any chain using `CREATE2`. The `CREATE2`
call will deploy a contract (like `CREATE` opcode) but instead of the address being
`keccak256(rlp([deployer_address, nonce]))` it instead uses the hash of the contract's bytecode and a salt.
This means that a given deployer address will deploy the
same code to the same address no matter when or where they issue the deployment. The deployer is deployed
ith a one-time-use-account, so no matter what chain the deployer is on, its address will always be the same. This
means the only variables in determining the address of your contract are its bytecode hash and the provided salt.
Between the use of `CREATE2` opcode and the one-time-use-account for the deployer, this contracts ensures
that a given contract will exist at the exact same address on every chain, but without having to use the
same gas pricing or limits every time.
## Permit2
[Implementation](https://github.com/Uniswap/permit2/blob/0x000000000022D473030F116dDEE9F6B43aC78BA3/src/Permit2.sol)
Address: `0x000000000022D473030F116dDEE9F6B43aC78BA3`
Permit2 introduces a low-overhead, next-generation token approval/meta-tx system to make token approvals easier,
more secure, and more consistent across applications.
## ERC-4337 EntryPoint
[Implementation](https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/EntryPoint.sol)
Address: `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789`
This contract verifies and executes the bundles of ERC-4337
[UserOperations](https://www.erc4337.io/docs/understanding-ERC-4337/user-operation) sent to it.
## ERC-4337 SenderCreator
[Implementation](https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/core/SenderCreator.sol)
Address: `0x7fc98430eaedbb6070b35b39d798725049088348`
Helper contract for [EntryPoint](#erc-4337-entrypoint), to call `userOp.initCode` from a "neutral" address,
which is explicitly not `EntryPoint` itself.
# L2 Output Root Proposals Specification
<!-- All glossary references in this file. -->
[g-rollup-node]: glossary.md#rollup-node
[g-mpt]: glossary.md#merkle-patricia-trie
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Proposing L2 Output Commitments](#proposing-l2-output-commitments)
- [L2OutputOracle v1.0.0](#l2outputoracle-v100)
- [L2 Output Commitment Construction](#l2-output-commitment-construction)
- [L2 Output Oracle Smart Contract](#l2-output-oracle-smart-contract)
- [Configuration](#configuration)
- [Security Considerations](#security-considerations)
- [L1 Reorgs](#l1-reorgs)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
After processing one or more blocks the outputs will need to be synchronized with the settlement layer (L1)
for trustless execution of L2-to-L1 messaging, such as withdrawals.
These output proposals act as the bridge's view into the L2 state.
Actors called "Proposers" submit the output roots to the settlement layer (L1) and can be contested with a fault proof,
with a bond at stake if the proof is wrong. The [op-proposer](../op-proposer/) in one such implementation of a proposer.
_Note_: Fault proofs on Optimism are not fully specified at this time. Although fault proof
construction and verification [is implemented in Cannon][cannon],
the fault proof game specification and integration of a output-root challenger into the [rollup-node][g-rollup-node]
are part of later specification milestones.
[cannon]: https://github.com/ethereum-optimism/cannon
## Proposing L2 Output Commitments
The proposer's role is to construct and submit output roots, which are commitments to the L2's state,
to the `L2OutputOracle` contract on L1 (the settlement layer). To do this, the proposer periodically
queries the [rollup node](./rollup-node.md) for the latest output root derived from the latest
[finalized](rollup-node.md#finalization-guarantees) L1 block. It then takes the output root and
submits it to the `L2OutputOracle` contract on the settlement layer (L1).
### L2OutputOracle v1.0.0
The submission of output proposals is permissioned to a single account. It is expected that this
account will continue to submit output proposals over time to ensure that user withdrawals do not halt.
The [L2 output proposer](../op-proposer) is expected to submit output roots on a deterministic
interval based on the configured `SUBMISSION_INTERVAL` in the `L2OutputOracle`. The larger
the `SUBMISSION_INTERVAL`, the less often L1 transactions need to be sent to the `L2OutputOracle`
contract, but L2 users will need to wait a bit longer for an output root to be included in L1 (the settlement layer)
that includes their intention to withdraw from the system.
The honest `op-proposer` algorithm assumes a connection to the `L2OutputOracle` contract to know
the L2 block number that corresponds to the next output proposal that must be submitted. It also
assumes a connection to an `op-node` to be able to query the `optimism_syncStatus` RPC endpoint.
```python
import time
while True:
next_checkpoint_block = L2OutputOracle.nextBlockNumber()
rollup_status = op_node_client.sync_status()
if rollup_status.finalized_l2.number >= next_checkpoint_block:
output = op_node_client.output_at_block(next_checkpoint_block)
tx = send_transaction(output)
time.sleep(poll_interval)
```
A `CHALLENGER` account can delete multiple output roots by calling the `deleteL2Outputs()` function
and specifying the index of the first output to delete, this will also delete all subsequent outputs.
## L2 Output Commitment Construction
The `output_root` is a 32 byte string, which is derived based on the a versioned scheme:
```pseudocode
output_root = keccak256(version_byte || payload)
```
where:
1. `version_byte` (`bytes32`) a simple version string which increments anytime the construction of the output root
is changed.
2. `payload` (`bytes`) is a byte string of arbitrary length.
In the initial version of the output commitment construction, the version is `bytes32(0)`, and the payload is defined
as:
```pseudocode
payload = state_root || withdrawal_storage_root || latest_block_hash
```
where:
1. The `latest_block_hash` (`bytes32`) is the block hash for the latest L2 block.
1. The `state_root` (`bytes32`) is the Merkle-Patricia-Trie ([MPT][g-mpt]) root of all execution-layer accounts.
This value is frequently used and thus elevated closer to the L2 output root, which removes the need to prove its
inclusion in the pre-image of the `latest_block_hash`. This reduces the merkle proof depth and cost of accessing the
L2 state root on L1.
1. The `withdrawal_storage_root` (`bytes32`) elevates the Merkle-Patricia-Trie ([MPT][g-mpt]) root of the [Message
Passer contract](./withdrawals.md#the-l2tol1messagepasser-contract) storage. Instead of making an MPT proof for a
withdrawal against the state root (proving first the storage root of the L2toL1MessagePasser against the state root,
then the withdrawal against that storage root), we can prove against the L2toL1MessagePasser's storage root directly,
thus reducing the verification cost of withdrawals on L1.
## L2 Output Oracle Smart Contract
L2 blocks are produced at a constant rate of `L2_BLOCK_TIME` (2 seconds).
A new L2 output MUST be appended to the chain once per `SUBMISSION_INTERVAL` which is based on a number of blocks.
The exact number is yet to be determined, and will depend on the design of the fault proving game.
The L2 Output Oracle contract implements the following interface:
```solidity
/**
* @notice The number of the first L2 block recorded in this contract.
*/
uint256 public startingBlockNumber;
/**
* @notice The timestamp of the first L2 block recorded in this contract.
*/
uint256 public startingTimestamp;
/**
* @notice Accepts an L2 outputRoot and the timestamp of the corresponding L2 block. The
* timestamp must be equal to the current value returned by `nextTimestamp()` in order to be
* accepted.
* This function may only be called by the Proposer.
*
* @param _l2Output The L2 output of the checkpoint block.
* @param _l2BlockNumber The L2 block number that resulted in _l2Output.
* @param _l1Blockhash A block hash which must be included in the current chain.
* @param _l1BlockNumber The block number with the specified block hash.
*/
function proposeL2Output(
bytes32 _l2Output,
uint256 _l2BlockNumber,
bytes32 _l1Blockhash,
uint256 _l1BlockNumber
)
/**
* @notice Deletes all output proposals after and including the proposal that corresponds to
* the given output index. Only the challenger address can delete outputs.
*
* @param _l2OutputIndex Index of the first L2 output to be deleted. All outputs after this
* output will also be deleted.
*/
function deleteL2Outputs(uint256 _l2OutputIndex) external
/**
* @notice Computes the block number of the next L2 block that needs to be checkpointed.
*/
function nextBlockNumber() public view returns (uint256)
```
### Configuration
The `startingBlockNumber` must be at least the number of the first Bedrock block.
The `startingTimestamp` MUST be the same as the timestamp of the start block.
The first `outputRoot` proposed will thus be at height `startingBlockNumber + SUBMISSION_INTERVAL`
## Security Considerations
### L1 Reorgs
If the L1 has a reorg after an output has been generated and submitted, the L2 state and correct output may change
leading to a faulty proposal. This is mitigated against by allowing the proposer to submit an
L1 block number and hash to the Output Oracle when appending a new output; in the event of a reorg, the block hash
will not match that of the block with that number and the call will revert.
# Rollup-node P2P interface
The [rollup node](./rollup-node.md) has an optional peer-to-peer (P2P) network service to improve the latency between
the view of sequencers and the rest of the network by bypassing the L1 in the happy case,
without relying on a single centralized endpoint.
This also enables faster historical sync to be bootstrapped by providing block headers to sync towards,
and only having to compare the L2 chain inputs to the L1 data as compared to processing everything one block at a time.
The rollup node will *always* prioritize L1 and reorganize to match the canonical chain.
The L2 data retrieved via the P2P interface is strictly a speculative extension, also known as the "unsafe" chain,
to improve the happy case performance.
This also means that P2P behavior is a soft-rule: nodes keep each other in check with scoring and eventual banning
of malicious peers by identity or IP. Any behavior on the P2P layer does not affect the rollup security, at worst nodes
rely on higher-latency data from L1 to serve.
In summary, the P2P stack looks like:
- Discovery to find peers: [Discv5][discv5]
- Connections, peering, transport security, multiplexing, gossip: [LibP2P][libp2p]
- Application-layer publishing and validation of gossiped messages like L2 blocks.
This document only specifies the composition and configuration of these network libraries.
These components have their own standards, implementations in Go/Rust/Java/Nim/JS/more,
and are adopted by several other blockchains, most notably the [L1 consensus layer (Eth2)][eth2-p2p].
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [P2P configuration](#p2p-configuration)
- [Identification](#identification)
- [Discv5](#discv5)
- [Structure](#structure)
- [LibP2P](#libp2p)
- [Transport](#transport)
- [Dialing](#dialing)
- [NAT](#nat)
- [Peer management](#peer-management)
- [Transport security](#transport-security)
- [Protocol negotiation](#protocol-negotiation)
- [Identify](#identify)
- [Ping](#ping)
- [Multiplexing](#multiplexing)
- [GossipSub](#gossipsub)
- [Content-based message identification](#content-based-message-identification)
- [Message compression and limits](#message-compression-and-limits)
- [Message ID computation](#message-id-computation)
- [Heartbeat and parameters](#heartbeat-and-parameters)
- [Topic configuration](#topic-configuration)
- [Topic validation](#topic-validation)
- [Gossip Topics](#gossip-topics)
- [`blocksv1`](#blocksv1)
- [`blocksv2`](#blocksv2)
- [`blocksv3`](#blocksv3)
- [Block encoding](#block-encoding)
- [Block signatures](#block-signatures)
- [Block validation](#block-validation)
- [Block processing](#block-processing)
- [Block topic scoring parameters](#block-topic-scoring-parameters)
- [Req-Resp](#req-resp)
- [`payload_by_number`](#payload_by_number)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## P2P configuration
### Identification
Nodes have a **separate** network- and consensus-identity.
The network identity is a `secp256k1` key, used for both discovery and active LibP2P connections.
Common representations of network identity:
- `PeerID`: a LibP2P specific ID derived from the pubkey (through protobuf encoding, typing and hashing)
- `NodeID`: a Discv5 specific ID derived from the pubkey (through hashing, used in the DHT)
- `Multi-address`: an unsigned address, containing: IP, TCP port, PeerID
- `ENR`: a signed record used for discovery, containing: IP, TCP port, UDP port, signature (pubkey can be derived)
and L2 network identification. Generally encoded in base64.
### Discv5
#### Structure
The Ethereum Node Record (ENR) for an Optimism rollup node must contain the following values, identified by unique keys:
- An IPv4 address (`ip` field) and/or IPv6 address (`ip6` field).
- A TCP port (`tcp` field) representing the local libp2p listening port.
- A UDP port (`udp` field) representing the local discv5 listening port.
- An OpStack (`opstack` field) L2 network identifier
The `opstack` value is encoded as a single RLP `bytes` value, the concatenation of:
- chain ID (`unsigned varint`)
- fork ID (`unsigned varint`)
Note that DiscV5 is a shared DHT (Distributed Hash Table): the L1 consensus and execution nodes,
as well as testnet nodes, and even external IOT nodes, all communicate records in this large common DHT.
This makes it more difficult to censor the discovery of node records.
The discovery process in Optimism is a pipeline of node records:
1. Fill the table with `FINDNODES` if necessary (Performed by Discv5 library)
2. Pull additional records with searches to random Node IDs if necessary
(e.g. iterate [`RandomNodes()`][discv5-random-nodes] in Go implementation)
3. Pull records from the DiscV5 module when looking for peers
4. Check if the record contains the `opstack` entry, verify it matches the chain ID and current or future fork number
5. If not already connected, and not recently disconnected or put on deny-list, attempt to dial.
### LibP2P
#### Transport
TCP transport. Additional transports are supported by LibP2P, but not required.
#### Dialing
Nodes should be publicly dialable, not rely on relay extensions, and able to dial both IPv4 and IPv6.
#### NAT
The listening endpoint must be publicly facing, but may be configured behind a NAT.
LibP2P will use PMP / UPNP based techniques to track the external IP of the node.
It is recommended to disable the above if the external IP is static and configured manually.
#### Peer management
The default is to maintain a peer count with a tide-system based on active peer count:
- At "low tide" the node starts to actively search for additional peer connections.
- At "high tide" the node starts to prune active connections,
except those that are marked as trusted or have a grace period.
Peers will have a grace period for a configurable amount of time after joining.
In an emergency, when memory runs low, the node should start pruning more aggressively.
Peer records can be persisted to disk to quickly reconnect with known peers after restarting the rollup node.
The discovery process feeds the peerstore with peer records to connect to, tagged with a time-to-live (TTL).
The current P2P processes do not require selective topic-specific peer connections,
other than filtering for the basic network participation requirement.
Peers may be banned if their performance score is too low, or if an objectively malicious action was detected.
Banned peers will be persisted to the same data-store as the peerstore records.
TODO: the connection gater does currently not gate by IP address on the dial Accept-callback.
#### Transport security
[Libp2p-noise][libp2p-noise], `XX` handshake, with the `secp256k1` P2P identity, as popularized in Eth2.
The TLS option is available as well, but `noise` should be prioritized in negotiation.
#### Protocol negotiation
[Multistream-select 1.0][multistream-select] (`/multistream/1.0.0`) is an interactive protocol
used to negotiate sub-protocols supported in LibP2P peers. Multistream-select 2.0 may be used in the future.
#### Identify
LibP2P offers a minimal identification module to share client version and programming language.
This is optional and can be disabled for enhanced privacy.
It also includes the same protocol negotiation information, which can speed up initial connections.
#### Ping
LibP2P includes a simple ping protocol to track latency between connections.
This should be enabled to help provide insight into the network health.
#### Multiplexing
For async communication over different channels over the same connection, multiplexing is used.
[mplex][mplex] (`/mplex/6.7.0`) is required, and [yamux][yamux] (`/yamux/1.0.0`) is recommended but optional
#### GossipSub
[GossipSub 1.1][gossipsub] (`/meshsub/1.1.0`, i.e. with peer-scoring extension) is a pubsub protocol for mesh-networks,
deployed on L1 consensus (Eth2) and other protocols such as Filecoin, offering lots of customization options.
##### Content-based message identification
Messages are deduplicated, and filtered through application-layer signature verification.
Thus origin-stamping is disabled and published messages must only contain application data,
enforced through a [`StrictNoSign` Signature Policy][signature-policy]
This provides greater privacy, and allows sequencers (consensus identity) to maintain
multiple network identities for redundancy.
##### Message compression and limits
The application contents are compressed with [snappy][snappy] single-block-compression
(as opposed to frame-compression), and constrained to 10 MiB.
##### Message ID computation
[Same as L1][l1-message-id], with recognition of compression:
- If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of
the concatenation of `MESSAGE_DOMAIN_VALID_SNAPPY` with the snappy decompressed message data,
i.e. `SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + snappy_decompress(message.data))[:20]`.
- Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of
the concatenation of `MESSAGE_DOMAIN_INVALID_SNAPPY` with the raw message data,
i.e. `SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + message.data)[:20]`.
#### Heartbeat and parameters
GossipSub [parameters][gossip-parameters]:
- `D` (topic stable mesh target count): 8
- `D_low` (topic stable mesh low watermark): 6
- `D_high` (topic stable mesh high watermark): 12
- `D_lazy` (gossip target): 6
- `heartbeat_interval` (interval of heartbeat, in seconds): 0.5
- `fanout_ttl` (ttl for fanout maps for topics we are not subscribed to but have published to, in seconds): 24
- `mcache_len` (number of windows to retain full messages in cache for `IWANT` responses): 12
- `mcache_gossip` (number of windows to gossip about): 3
- `seen_ttl` (number of heartbeat intervals to retain message IDs): 130 (= 65 seconds)
Notable differences from L1 consensus (Eth2):
- `seen_ttl` does not need to cover a full L1 epoch (6.4 minutes), but rather just a small window covering latest blocks
- `fanout_ttl`: adjusted to lower than `seen_ttl`
- `mcache_len`: a larger number of heartbeats can be retained since the gossip is much less noisy.
- `heartbeat_interval`: faster interval to reduce latency, bandwidth should still be reasonable since
there are far fewer messages to gossip about each interval than on L1 which uses an interval of 0.7 seconds.
#### Topic configuration
Topics have string identifiers and are communicated with messages and subscriptions.
`/optimism/chain_id/hardfork_version/Name`
- `chain_id`: replace with decimal representation of chain ID
- `hardfork_version`: replace with decimal representation of hardfork, starting at `0`
- `Name`: topic application-name
Note that the topic encoding depends on the topic, unlike L1,
since there are less topics, and all are snappy-compressed.
#### Topic validation
To ensure only valid messages are relayed, and malicious peers get scored based on application behavior,
an [extended validator][extended-validator] checks the message before it is relayed or processed.
The extended validator emits one of the following validation signals:
- `ACCEPT` valid, relayed to other peers and passed to local topic subscriber
- `IGNORE` scored like inactivity, message is dropped and not processed
- `REJECT` score penalties, message is dropped
## Gossip Topics
There are three topics for distributing blocks to other nodes faster than proxying through L1 would. These are:
### `blocksv1`
Pre-Canyon/Shanghai blocks are broadcast on `/optimism/<chainId>/0/blocks`.
### `blocksv2`
Canyon/Delta blocks are broadcast on `/optimism/<chainId>/1/blocks`.
### `blocksv3`
Ecotone blocks are broadcast on `/optimism/<chainId>/2/blocks`.
### Block encoding
A block is structured as the concatenation of:
- V1 and V2 topics
- `signature`: A `secp256k1` signature, always 65 bytes, `r (uint256), s (uint256), y_parity (uint8)`
- `payload`: A SSZ-encoded `ExecutionPayload`, always the remaining bytes.
- V3 topic
- `signature`: A `secp256k1` signature, always 65 bytes, `r (uint256), s (uint256), y_parity (uint8)`
- `parentBeaconBlockRoot`: L1 origin parent beacon block root, always 32 bytes
- `payload`: A SSZ-encoded `ExecutionPayload`, always the remaining bytes.
All topics use Snappy block-compression (i.e. no snappy frames):
the above needs to be compressed after encoding, and decompressed before decoding.
### Block signatures
The `signature` is a `secp256k1` signature, and signs over a message:
`keccak256(domain ++ chain_id ++ payload_hash)`, where:
- `domain` is 32 bytes, reserved for message types and versioning info. All zero for this signature.
- `chain_id` is a big-endian encoded `uint256`.
- `payload_hash` is `keccak256(payload)`, where `payload` is the remaining bytes of the payload.
The `secp256k1` signature must have `y_parity = 1 or 0`, the `chain_id` is already signed over.
### Block validation
An [extended-validator] checks the incoming messages as follows, in order of operation:
- `[REJECT]` if the compression is not valid
- `[REJECT]` if the block encoding is not valid
- `[REJECT]` if the `payload.timestamp` is older than 60 seconds in the past
(graceful boundary for worst-case propagation and clock skew)
- `[REJECT]` if the `payload.timestamp` is more than 5 seconds into the future
- `[REJECT]` if the `block_hash` in the `payload` is not valid
- `[REJECT]` if the block is on the V1 topic and has withdrawals
- `[REJECT]` if the block is on the V1 topic and has a withdrawals list
- `[REJECT]` if the block is on a topic >= V2 and does not have an empty withdrawals list
- `[REJECT]` if the block is on a topic <= V2 and has a blob gas-used value set
- `[REJECT]` if the block is on a topic <= V2 and has an excess blob gas value set
- `[REJECT]` if the block is on a topic >= V3 and has a blob gas-used value that is not zero
- `[REJECT]` if the block is on a topic >= V3 and has an excess blob gas value that is not zero
- `[REJECT]` if the block is on a topic <= V2 and the parent beacon block root is not nil
- `[REJECT]` if the block is on a topic >= V3 and the parent beacon block root is nil
- `[REJECT]` if more than 5 different blocks have been seen with the same block height
- `[IGNORE]` if the block has already been seen
- `[REJECT]` if the signature by the sequencer is not valid
- Mark the block as seen for the given block height
The block is signed by the corresponding sequencer, to filter malicious messages.
The sequencer model is singular but may change to multiple sequencers in the future.
A default sequencer pubkey is distributed with rollup nodes and should be configurable.
Note that blocks that a block may still be propagated even if the L1 already confirmed a different block.
The local L1 view of the node may be wrong, and the time and signature validation will prevent spam.
Hence, calling into the execution engine with a block lookup every propagation step is not worth the added delay.
#### Block processing
A node may apply the block to their local engine ahead of L1 availability, if it ensures that:
- The application of the block is reversible, in case of a conflict with delayed L1 information
- The subsequent forkchoice-update ensures this block is recognized as "unsafe"
(see [fork choice updated](derivation.md#engine-api-usage))
#### Block topic scoring parameters
TODO: GossipSub per-topic scoring to fine-tune incentives for ideal propagation delay and bandwidth usage.
## Req-Resp
The op-node implements a similar request-response encoding for its sync protocols as the L1 ethereum Beacon-Chain.
See [L1 P2P-interface req-resp specification][eth2-p2p-reqresp] and [Altair P2P update][eth2-p2p-altair-reqresp].
However, the protocol is simplified, to avoid several issues seen in L1:
- Error strings in responses, if there is any alternative response,
should not need to be compressed or have an artificial global length limit.
- Payload lengths should be fixed-length: byte-by-byte uvarint reading from the underlying stream is undesired.
- `<context-bytes>` are relaxed to encode a `uint32`, rather than a beacon-chain `ForkDigest`.
- Payload-encoding may change per hardfork, so is not part of the protocol-ID.
- Usage of response-chunks is specific to the req-resp method: most basic req-resp does not need chunked responses.
- Compression is encouraged to be part of the payload-encoding, specific to the req-resp method, where necessary:
pings and such do not need streaming frame compression etc.
And the protocol ID format follows the same scheme as L1,
except the trailing encoding schema part, which is now message-specific:
```text
/ProtocolPrefix/MessageName/SchemaVersion/
```
The req-resp protocols served by the op-node all have `/ProtocolPrefix` set to `/opstack/req`.
Individual methods may include the chain ID as part of the `/MessageName` segment,
so it's immediately clear which chain the method applies to, if the communication is chain-specific.
Other methods may include chain-information in the request and/or response data,
such as the `ForkDigest` `<context-bytes>` in L1 beacon chain req-resp protocols.
Each segment starts with a `/`, and may contain multiple `/`, and the final protocol ID is suffixed with a `/`.
### `payload_by_number`
This is an optional chain syncing method, to request/serve execution payloads by number.
This serves as a method to fill gaps upon missed gossip, and sync short to medium ranges of unsafe L2 blocks.
Protocol ID: `/opstack/req/payload_by_number/<chain-id>/0/`
- `/MessageName` is `/block_by_number/<chain-id>` where `<chain-id>` is set to the op-node L2 chain ID.
- `/SchemaVersion` is `/0`
Request format: `<num>`: a little-endian `uint64` - the block number to request.
Response format: `<response> = <res><version><payload>`
- `<res>` is a byte code describing the result.
- `0` on success, `<version><payload>` should follow.
- `1` if valid request, but unavailable payload.
- `2` if invalid request
- `3+` if other error
- The `>= 128` range is reserved for future use.
- `<version>` is a little-endian `uint32`, identifying the response type (fork-specific)
- `<payload>` is an encoded block, read till stream EOF.
The input of `<response>` should be limited, as well as any generated decompressed output,
to avoid unexpected resource usage or zip-bomb type attacks.
A 10 MB limit is recommended, to ensure all blocks may be synced.
Implementations may opt for a different limit, since this sync method is optional.
`<version>` list:
- `0`: SSZ-encoded `ExecutionPayload`, with Snappy framing compression,
matching the `ExecutionPayload` SSZ definition of the L1 Merge, L2 Bedrock and L2 Regolith, L2 Canyon versions.
- `1`: SSZ-encoded `ExecutionPayloadEnvelope` with Snappy framing compression,
matching the `ExecutionPayloadEnvelope` SSZ definition of the L2 Ecotone version.
The request is by block-number, enabling parallel fetching of a chain across many peers.
A `res = 0` response should be verified to:
- Have a block-number matching the requested block number.
- Have a consistent `blockhash` w.r.t. the other block contents.
- Build towards a known canonical block.
- This can be verified by checking if the parent-hash of a previous trusted canonical block matches
that of the verified hash of the retrieved block.
- For unsafe blocks this may be relaxed to verification against the parent-hash of any previously trusted block:
- The gossip validation process limits the amount of blocks that may be trusted to sync towards.
- The unsafe blocks should be queued for processing, the latest received L2 unsafe blocks should always
override any previous chain, until the final L2 chain can be reproduced from L1 data.
A `res > 0` response code should not be accepted. The result code is helpful for debugging,
but the client should regard any error like any other unanswered request, as the responding peer cannot be trusted.
----
[libp2p]: https://libp2p.io/
[discv5]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md
[discv5-random-nodes]: https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.12/p2p/discover#UDPv5.RandomNodes
[eth2-p2p]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md
[eth2-p2p-reqresp]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-reqresp-domain
[eth2-p2p-altair-reqresp]: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/p2p-interface.md#the-reqresp-domain
[libp2p-noise]: https://github.com/libp2p/specs/tree/master/noise
[multistream-select]: https://github.com/multiformats/multistream-select/
[mplex]: https://github.com/libp2p/specs/tree/master/mplex
[yamux]: https://github.com/hashicorp/yamux/blob/master/spec.md
[gossipsub]: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md
[signature-policy]: https://github.com/libp2p/specs/blob/master/pubsub/README.md#signature-policy-options
[snappy]: https://github.com/google/snappy
[l1-message-id]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#topics-and-messages
[gossip-parameters]: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.0.md#parameters
[extended-validator]: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#extended-validators
# Rollup Node Specification
<!-- All glossary references in this file. -->
[g-rollup-node]: glossary.md#rollup-node
[g-derivation]: glossary.md#L2-chain-derivation
[g-payload-attr]: glossary.md#payload-attributes
[g-block]: glossary.md#block
[g-exec-engine]: glossary.md#execution-engine
[g-reorg]: glossary.md#re-organization
[g-rollup-driver]: glossary.md#rollup-driver
[g-receipts]: glossary.md#receipt
The [rollup node][g-rollup-node] is the component responsible for [deriving the L2 chain][g-derivation] from L1 blocks
(and their associated [receipts][g-receipts]).
The part of the rollup node that derives the L2 chain is called the [rollup driver][g-rollup-driver]. This document is
currently only concerned with the specification of the rollup driver.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Driver](#driver)
- [Derivation](#derivation)
- [L2 Output RPC method](#l2-output-rpc-method)
- [Structures](#structures)
- [BlockID](#blockid)
- [L1BlockRef](#l1blockref)
- [L2BlockRef](#l2blockref)
- [SyncStatus](#syncstatus)
- [Output Method API](#output-method-api)
- [Protocol Version tracking](#protocol-version-tracking)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Driver
The task of the [driver][g-rollup-driver] in the [rollup node][g-rollup-node]
is to manage the [derivation][g-derivation] process:
- Keep track of L1 head block
- Keep track of the L2 chain sync progress
- Iterate over the derivation steps as new inputs become available
### Derivation
This process happens in three steps:
1. Select inputs from the L1 chain, on top of the last L2 block:
a list of blocks, with transactions and associated data and receipts.
2. Read L1 information, deposits, and sequencing batches in order to generate [payload attributes][g-payload-attr]
(essentially [a block without output properties][g-block]).
3. Pass the payload attributes to the [execution engine][g-exec-engine], so that the L2 block (including [output block
properties][g-block]) may be computed.
While this process is conceptually a pure function from the L1 chain to the L2 chain, it is in practice incremental. The
L2 chain is extended whenever new L1 blocks are added to the L1 chain. Similarly, the L2 chain re-organizes whenever the
L1 chain [re-organizes][g-reorg].
For a complete specification of the L2 block derivation, refer to the [L2 block derivation document](./derivation.md).
## L2 Output RPC method
The Rollup node has its own RPC method, `optimism_outputAtBlock` which returns a 32
byte hash corresponding to the [L2 output root](./proposals.md#l2-output-commitment-construction).
[SSZ]: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md
### Structures
These define the types used by rollup node API methods.
The types defined here are extended from the [engine API specs][engine-structures].
#### BlockID
- `hash`: `DATA`, 32 Bytes
- `number`: `QUANTITY`, 64 Bits
#### L1BlockRef
- `hash`: `DATA`, 32 Bytes
- `number`: `QUANTITY`, 64 Bits
- `parentHash`: `DATA`, 32 Bytes
- `timestamp`: `QUANTITY`, 64 Bits
#### L2BlockRef
- `hash`: `DATA`, 32 Bytes
- `number`: `QUANTITY`, 64 Bits
- `parentHash`: `DATA`, 32 Bytes
- `timestamp`: `QUANTITY`, 64 Bits
- `l1origin`: `BlockID`
- `sequenceNumber`: `QUANTITY`, 64 Bits - distance to first block of epoch
#### SyncStatus
Represents a snapshot of the rollup driver.
- `current_l1`: `Object` - instance of [`L1BlockRef`](#l1blockref).
- `current_l1_finalized`: `Object` - instance of [`L1BlockRef`](#l1blockref).
- `head_l1`: `Object` - instance of [`L1BlockRef`](#l1blockref).
- `safe_l1`: `Object` - instance of [`L1BlockRef`](#l1blockref).
- `finalized_l1`: `Object` - instance of [`L1BlockRef`](#l1blockref).
- `unsafe_l2`: `Object` - instance of [`L2BlockRef`](#l2blockref).
- `safe_l2`: `Object` - instance of [`L2BlockRef`](#l2blockref).
- `finalized_l2`: `Object` - instance of [`L2BlockRef`](#l2blockref).
- `pending_safe_l2`: `Object` - instance of [`L2BlockRef`](#l2blockref).
- `queued_unsafe_l2`: `Object` - instance of [`L2BlockRef`](#l2blockref).
### Output Method API
The input and return types here are as defined by the [engine API specs][engine-structures].
[engine-structures]: https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#structures
- method: `optimism_outputAtBlock`
- params:
1. `blockNumber`: `QUANTITY`, 64 bits - L2 integer block number.
- returns:
1. `version`: `DATA`, 32 Bytes - the output root version number, beginning with 0.
1. `outputRoot`: `DATA`, 32 Bytes - the output root.
1. `blockRef`: `Object` - instance of [`L2BlockRef`](#l2blockref).
1. `withdrawalStorageRoot`: 32 bytes - storage root of the `L2toL1MessagePasser` contract.
1. `stateRoot`: `DATA`: 32 bytes - the state root.
1. `syncStatus`: `Object` - instance of [`SyncStatus`](#syncstatus).
## Protocol Version tracking
The rollup-node should monitor the recommended and required protocol version by monitoring
the Protocol Version contract on L1, as specified in the [Superchain Version Signaling specifications].
[Superchain Version Signaling specifications]: ./superchain-upgrades.md#superchain-version-signaling
This can be implemented through polling in the [Driver](#driver) loop.
After polling the Protocol Version, the rollup node SHOULD communicate it with the execution-engine through an
[`engine_signalSuperchainV1`](./exec-engine.md#enginesignalsuperchainv1) call.
The rollup node SHOULD warn the user when the recommended version is newer than
the current version supported by the rollup node.
The rollup node SHOULD take safety precautions if it does not meet the required protocol version.
This may include halting the engine, with consent of the rollup node operator.
# Safe Liveness Checking
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Liveness checking Mechanism](#liveness-checking-mechanism)
- [Liveness checking methodology](#liveness-checking-methodology)
- [The liveness guard](#the-liveness-guard)
- [The liveness module](#the-liveness-module)
- [Owner removal call flow](#owner-removal-call-flow)
- [Shutdown](#shutdown)
- [Security Properties](#security-properties)
- [In the guard](#in-the-guard)
- [In the module](#in-the-module)
- [Interdependency between the guard and module](#interdependency-between-the-guard-and-module)
- [Operational considerations](#operational-considerations)
- [Manual validation of new owner liveness](#manual-validation-of-new-owner-liveness)
- [Deploying the liveness checking system](#deploying-the-liveness-checking-system)
- [Modify the liveness checking system](#modify-the-liveness-checking-system)
- [Replacing the module](#replacing-the-module)
- [Replacing the guard](#replacing-the-guard)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Liveness checking Mechanism
The Security Council uses a specially extended Safe multisig contract to ensure that
any loss of access to a signer's keys is identified and addressed within a predictable period of
time.
This mechanism is intended only to be used to remove signers who have lost access to their keys, or
are otherwise inactive. It is not intended to be used to remove signers who are acting in bad faith,
or any other subjective criteria, such cases should be addressed by governance, and the removal
handled via the standard Safe ownership management functionality.
## Liveness checking methodology
This is achieved using two types of contracts which the Safe contract has built-in support for:
1. **Guard contracts:** can execute pre- and post- transaction checks.
1. **Module contracts:** a contract which is added to the Safe by the signers, and thenceforth is
authorized to execute transactions via the Safe. This means the module must properly implement
auth conditions internally.
### The liveness guard
For implementing liveness checks a `LivenessGuard` is created which receives the signatures from
each executed transaction, and tracks the latest time at which a transaction was signed by each
signer. This time is made publicly available by calling a `lastLive(address)(Timestamp)` method.
Owners are recorded in this mapping in one of 4 ways:
1. Upon deployment, the guard reads the current set of owners from the Safe contract.
1. When a new owner is added to the safe. Similarly, when an owner is removed from the Safe, its
entry is deleted from the mapping.
1. When a transaction is executed, the signatures on that transaction are passed to the guard and
used to identify the signers. If more than the required number of signatures is provided, they
are ignored.
1. An owner may call the contract's `showLiveness()()` method directly in order to prove liveness.
Note that the first two methods do not require the owner to actually sign anything. However these mechanisms
are necessary to prevent new owners from being removed before they have had a chance to show liveness.
### The liveness module
A `LivenessModule` is also created which does the following:
1. Has a function `removeOwners()` that anyone may call to specify one or more owners to be removed from the
Safe.
1. The Module would then check the `LivenessGuard.lastLive()` to determine if the signer is
eligible for removal.
1. If so, it will call the Safe's `removeSigner()` to remove the non-live signer, and if necessary
reduce the threshold.
1. When a member is removed, the signing parameters are modified such that `M/N` is the lowest ratio
which remains greater than or equal to 75%. Using integer math, this can be expressed as `M = (N * 75 + 99) / 100`.
### Owner removal call flow
The following diagram illustrates the flow for removing a single owner. The `verifyFinalState`
box indicates calls to the Safe which ensure the final state is valid.
```mermaid
sequenceDiagram
participant User
participant LivenessModule
participant LivenessGuard
participant Safe
User->>LivenessModule: removeOwners([previousOwner], [owner])
LivenessModule->>LivenessGuard: lastLive(owner)
LivenessModule->>Safe: getOwners()
LivenessModule->>Safe: removeOwner(previousOwner, owner)
alt verifyFinalState
LivenessModule->>Safe: getOwners()
LivenessModule->>Safe: getThreshold()
LivenessModule->>Safe: getGuard()
end
```
### Shutdown
In the unlikely event that the signer set (`N`) is reduced below the allowed minimum number of
owners, then (and only then) is a shutdown mechanism activated which removes the existing
signers, and hands control of the multisig over to a predetermined entity.
### Security Properties
The following security properties must be upheld:
#### In the guard
1. Signatures are assigned to the correct signer.
1. Non-signers are unable to create a record of having signed.
1. An owner cannot be censored or griefed such that their signing is not recorded.
1. Owners may demonstrate liveness either by signing a transaction or by calling directly to the
guard.
1. It must be impossible for the guard's `checkTransaction` or `checkAfterExecution` method to
permanently revert given any calldata and the current state.
1. The guard correctly handles updates to the owners list, such that new owners are recorded, and
removed owners are deleted.
1. An `ownersBefore` enumerable set variable is used to accomplish this, it must be emptied at
the end of the `checkAfterExecution` call.
#### In the module
1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1.
1. The module only removes an owner if they have not demonstrated liveness during the interval, or
if enough other owners have been removed to activate the shutdown mechanism.
1. The module correctly sets the Safe's threshold upon removing a signer.
Note: neither the module nor guard attempt to prevent a quorum of owners from removing either the liveness
module or guard. There are legitimate reasons they might wish to do so. Moreover, if such a quorum
of owners exists, there is no benefit to removing them, as they are defacto 'sufficiently live'.
### Interdependency between the guard and module
The guard has no dependency on the module, and can be used independently to track liveness of
Safe owners.
This means that the module can be removed or replaced without any affect on the guard.
The module however does have a dependency on the guard; if the guard is removed from the Safe, then
the module will no longer be functional and calls to its `removeOwners` function will revert.
## Operational considerations
### Manual validation of new owner liveness
As [noted above](#the-liveness-guard) newly added owners are recorded in the guard without
necessarily having signed a transaction. Off-chain validation of the liveness of an address must
therefore be done prior to adding a new owner.
### Deploying the liveness checking system
[deploying]: #deploying-the-liveness-checking-system
The module and guard are intended to be deployed and installed on the safe in the following
sequence:
1. Deploy the guard contract
2. The guard's constructor will read the Safe's owners and set a timestamp
1. Deploy the module.
1. Set the guard on the safe.
1. Enable the module on the safe.
This order of operations is necessary to satisfy the constructor checks in the module, and is
intended to prevent owners from being immediately removable.
Note that changes to the owners set should not be made between the time the module is deployed, and
when it is enabled on the Safe, otherwise the checks made in the module's constructor may be
invalidated. If such changes are made, a new module should be deployed.
### Modify the liveness checking system
Changes to the liveness checking system should be done in the following manner:
#### Replacing the module
The module can safely be removed without affecting the operation of the guard. A new module can then
be added.
Note: none of the module's parameters are modifiable. In order to update the security properties
enforced by the module, it must be replaced.
#### Replacing the guard
The safe can only have one guard contract at a time, and if the guard is removed the module will
cease to function. This does not affect the ability of the Safe to operate normally, however the
module should be removed as a best practice.
If a new guard is added, eg. as a means of upgrading it, then a new module will also need to be
deployed and enabled. Once both the guard and module have been removed, they can be replaced
according to the steps in the [Deployment][deploying] section above.
# Span-batches
<!-- All glossary references in this file. -->
[g-deposit-tx-type]: glossary.md#deposited-transaction-type
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Introduction](#introduction)
- [Span batch format](#span-batch-format)
- [Max span-batch size](#max-span-batch-size)
- [Future batch-format extension](#future-batch-format-extension)
- [Span batch Activation Rule](#span-batch-activation-rule)
- [Optimization Strategies](#optimization-strategies)
- [Truncating information and storing only necessary data](#truncating-information-and-storing-only-necessary-data)
- [`tx_data_headers` removal from initial specs](#tx_data_headers-removal-from-initial-specs)
- [`Chain ID` removal from initial specs](#chain-id-removal-from-initial-specs)
- [Reorganization of constant length transaction fields](#reorganization-of-constant-length-transaction-fields)
- [RLP encoding for only variable length fields](#rlp-encoding-for-only-variable-length-fields)
- [Store `y_parity` and `protected_bit` instead of `v`](#store-y_parity-and-protected_bit-instead-of-v)
- [Adjust `txs` Data Layout for Better Compression](#adjust-txs-data-layout-for-better-compression)
- [`fee_recipients` Encoding Scheme](#fee_recipients-encoding-scheme)
- [How derivation works with Span Batch?](#how-derivation-works-with-span-batch)
- [Integration](#integration)
- [Channel Reader (Batch Decoding)](#channel-reader-batch-decoding)
- [Batch Queue](#batch-queue)
- [Batcher](#batcher)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
> The span-batches spec is experimental :shipit:
>
> *this feature is in active R&D and not yet part of any hard fork
## Introduction
Span-batches reduce overhead of OP-stack chains.
This enables sparse and low-throughput OP-stack chains.
The overhead is reduced by representing a span of
consecutive L2 blocks in a more efficient manner,
while preserving the same consistency checks as regular batch data.
Note that the [channel](./derivation.md#channel-format) and
[frame](./derivation.md#frame-format) formats stay the same:
data slicing, packing and multi-transaction transport is already optimized.
The overhead in the [V0 batch format](./derivation.md) comes from:
- The meta-data attributes are repeated for every L2 block, while these are mostly implied already:
- parent hash (32 bytes)
- L1 epoch: blockhash (32 bytes) and block number (~4 bytes)
- timestamp (~4 bytes)
- The organization of block data is inefficient:
- Similar attributes are far apart, diminishing any chances of effective compression.
- Random data like hashes are positioned in-between the more compressible application data.
- The RLP encoding of the data adds unnecessary overhead
- The outer list does not have to be length encoded, the attributes are known
- Fixed-length attributes do not need any encoding
- The batch-format is static and can be optimized further
- Remaining meta-data for consistency checks can be optimized further:
- The metadata only needs to be secure for consistency checks. E.g. 20 bytes of a hash may be enough.
Span-batches address these inefficiencies, with a new batch format version.
## Span batch format
[span-batch-format]: #span-batch-format
Note that span-batches, unlike previous singular batches,
encode *a range of consecutive* L2 blocks at the same time.
Introduce version `1` to the [batch-format](./derivation.md#batch-format) table:
| `batch_version` | `content` |
|-----------------|---------------------|
| 1 | `prefix ++ payload` |
Notation:
- `++`: concatenation of byte-strings
- `span_start`: first L2 block in the span
- `span_end`: last L2 block in the span
- `uvarint`: unsigned Base128 varint, as defined in [protobuf spec]
- `rlp_encode`: a function that encodes a batch according to the [RLP format],
and `[x, y, z]` denotes a list containing items `x`, `y` and `z`
[protobuf spec]: https://protobuf.dev/programming-guides/encoding/#varints
Standard bitlists, in the context of span-batches, are encoded as big-endian integers,
left-padded with zeroes to the next multiple of 8 bits.
Where:
- `prefix = rel_timestamp ++ l1_origin_num ++ parent_check ++ l1_origin_check`
- `rel_timestamp`: `uvarint` relative timestamp since L2 genesis,
i.e. `span_start.timestamp - config.genesis.timestamp`.
- `l1_origin_num`: `uvarint` number of last l1 origin number. i.e. `span_end.l1_origin.number`
- `parent_check`: first 20 bytes of parent hash, the hash is truncated to 20 bytes for efficiency,
i.e. `span_start.parent_hash[:20]`.
- `l1_origin_check`: the block hash of the last L1 origin is referenced.
The hash is truncated to 20 bytes for efficiency, i.e. `span_end.l1_origin.hash[:20]`.
- `payload = block_count ++ origin_bits ++ block_tx_counts ++ txs`:
- `block_count`: `uvarint` number of L2 blocks. This is at least 1, empty span batches are invalid.
- `origin_bits`: standard bitlist of `block_count` bits:
1 bit per L2 block, indicating if the L1 origin changed this L2 block.
- `block_tx_counts`: for each block, a `uvarint` of `len(block.transactions)`.
- `txs`: L2 transactions which is reorganized and encoded as below.
- `txs = contract_creation_bits ++ y_parity_bits ++
tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases ++ protected_bits`
- `contract_creation_bits`: standard bitlist of `sum(block_tx_counts)` bits:
1 bit per L2 transactions, indicating if transaction is a contract creation transaction.
- `y_parity_bits`: standard bitlist of `sum(block_tx_counts)` bits:
1 bit per L2 transactions, indicating the y parity value when recovering transaction sender address.
- `tx_sigs`: concatenated list of transaction signatures
- `r` is encoded as big-endian `uint256`
- `s` is encoded as big-endian `uint256`
- `tx_tos`: concatenated list of `to` field. `to` field in contract creation transaction will be `nil` and ignored.
- `tx_datas`: concatenated list of variable length rlp encoded data,
matching the encoding of the fields as in the [EIP-2718] format of the `TransactionType`.
- `legacy`: `rlp_encode(value, gasPrice, data)`
- `1`: ([EIP-2930]): `0x01 ++ rlp_encode(value, gasPrice, data, accessList)`
- `2`: ([EIP-1559]): `0x02 ++ rlp_encode(value, max_priority_fee_per_gas, max_fee_per_gas, data, access_list)`
- `tx_nonces`: concatenated list of `uvarint` of `nonce` field.
- `tx_gases`: concatenated list of `uvarint` of gas limits.
- `legacy`: `gasLimit`
- `1`: ([EIP-2930]): `gasLimit`
- `2`: ([EIP-1559]): `gas_limit`
- `protected_bits`: standard bitlist of length of number of legacy transactions:
1 bit per L2 legacy transactions, indicating if transaction is protected([EIP-155]) or not.
[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718
[EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930
[EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
[EIP-155]: https://eips.ethereum.org/EIPS/eip-155
### Max span-batch size
Total size of encoded span batch is limited to `MAX_SPAN_BATCH_SIZE` (currently 10,000,000 bytes,
equal to `MAX_RLP_BYTES_PER_CHANNEL`). Therefore every field size of span batch will be implicitly limited to
`MAX_SPAN_BATCH_SIZE` . There can be at least single span batch per channel, and channel size is limited
to `MAX_RLP_BYTES_PER_CHANNEL` and you may think that there is already an implicit limit. However, having an explicit
limit for span batch is helpful for several reasons. We may save computation costs by avoiding malicious input while
decoding. For example, let's say bad batcher wrote span batch which `block_count = max.Uint64`. We may early return
using the explicit limit, not trying to consume data until EOF is reached. We can also safely preallocate memory for
decoding because we know the upper limit of memory usage.
### Future batch-format extension
This is an experimental extension of the span-batch format, and not activated with the Delta upgrade yet.
Introduce version `2` to the [batch-format](./derivation.md#batch-format) table:
| `batch_version` | `content` |
|-----------------|---------------------|
| 2 | `prefix ++ payload` |
Where:
- `prefix = rel_timestamp ++ l1_origin_num ++ parent_check ++ l1_origin_check`:
- Identical to `batch_version` 1
- `payload = block_count ++ origin_bits ++ block_tx_counts ++ txs ++ fee_recipients`:
- An empty span-batch, i.e. with `block_count == 0`, is invalid and must not be processed.
- Every field definition identical to `batch_version` 1 except that `fee_recipients` is
added to support more decentralized sequencing.
- `fee_recipients = fee_recipients_idxs + fee_recipients_set`
- `fee_recipients_set`: concatenated list of unique L2 fee recipient address.
- `fee_recipients_idxs`: for each block,
`uvarint` number of index to decode fee recipients from `fee_recipients_set`.
## Span batch Activation Rule
The span batch upgrade is activated based on timestamp.
Activation Rule: `upgradeTime != null && span_start.l1_origin.timestamp >= upgradeTime`
`span_start.l1_origin.timestamp` is the L1 origin block timestamp of the first block in the span batch.
This rule ensures that every chain activity regarding this span batch is done after the hard fork.
i.e. Every block in the span is created, submitted to the L1, and derived from the L1 after the hard fork.
## Optimization Strategies
### Truncating information and storing only necessary data
The following fields stores truncated data:
- `rel_timestamp`: We can save two bytes by storing `rel_timestamp` instead of the full `span_start.timestamp`.
- `parent_check` and `l1_origin_check`: We can save twelve bytes by truncating twelve bytes from the full hash,
while having enough safety.
### `tx_data_headers` removal from initial specs
We do not need to store length per each `tx_datas` elements even if those are variable length,
because the elements itself is RLP encoded, containing their length in RLP prefix.
### `Chain ID` removal from initial specs
Every transaction has chain id. We do not need to include chain id in span batch because L2 already knows its chain id,
and use its own value for processing span batches while derivation.
### Reorganization of constant length transaction fields
`signature`, `nonce`, `gaslimit`, `to` field are constant size, so these were split up completely and
are grouped into individual arrays.
This adds more complexity, but organizes data for improved compression by grouping data with similar data pattern.
### RLP encoding for only variable length fields
Further size optimization can be done by packing variable length fields, such as `access_list`.
However, doing this will introduce much more code complexity, compared to benefiting from size reduction.
Our goal is to find the sweet spot on code complexity - span batch size tradeoff.
I decided that using RLP for all variable length fields will be the best option,
not risking codebase with gnarly custom encoding/decoding implementations.
### Store `y_parity` and `protected_bit` instead of `v`
Only legacy type transactions can be optionally protected. If protected([EIP-155]), `v = 2 * ChainID + 35 + y_parity`.
Else, `v = 27 + y_parity`. For other types of transactions, `v = y_parity`.
We store `y_parity`, which is single bit per L2 transaction.
We store `protected_bit`, which is single bit per L2 legacy type transactions to indicate that tx is protected.
This optimization will benefit more when ratio between number of legacy type transactions over number of transactions
excluding deposit tx is higher.
Deposit transactions are excluded in batches and are never written at L1 so excluded while analyzing.
### Adjust `txs` Data Layout for Better Compression
There are (7 choose 2) * 5! = 2520 permutations of ordering fields of `txs`.
It is not 7! because `contract_creation_bits` must be first decoded in order to decode `tx_tos`.
We experimented to find out the best layout for compression.
It turned out placing random data together(`TxSigs`, `TxTos`, `TxDatas`),
then placing leftovers helped gzip to gain more size reduction.
### `fee_recipients` Encoding Scheme
Let `K` := number of unique fee recipients(cardinality) per span batch. Let `N` := number of L2 blocks.
If we naively encode each fee recipients by concatenating every fee recipients, it will need `20 * N` bytes.
If we manage `fee_recipients_idxs` and `fee_recipients_set`, It will need at most `max uvarint size * N = 8 * N`,
`20 * K` bytes each. If `20 * N > 8 * N + 20 * K` then maintaining an index of fee recipients is reduces the size.
we thought sequencer rotation happens not much often, so assumed that `K` will be much lesser than `N`.
The assumption makes upper inequality to hold. Therefore, we decided to manage `fee_recipients_idxs` and
`fee_recipients_set` separately. This adds complexity but reduces data.
## How derivation works with Span Batch?
- Block Timestamp
- The first L2 block's block timestamp is `rel_timestamp + L2Genesis.Timestamp`.
- Then we can derive other blocks timestamp by adding L2 block time for each.
- L1 Origin Number
- The parent of the first L2 block's L1 origin number is `l1_origin_num - sum(origin_bits)`
- Then we can derive other blocks' L1 origin number with `origin_bits`
- `ith block's L1 origin number = (i-1)th block's L1 origin number + (origin_bits[i] ? 1 : 0)`
- L1 Origin Hash
- We only need the `l1_origin_check`, the truncated L1 origin hash of the last L2 block of Span Batch.
- If the last block references canonical L1 chain as its origin,
we can ensure the all other blocks' origins are consistent with the canonical L1 chain.
- Parent hash
- In V0 Batch spec, we need batch's parent hash to validate if batch's parent is consistent with current L2 safe head.
- But in the case of Span Batch, because it contains consecutive L2 blocks in the span,
we do not need to validate all blocks' parent hash except the first block.
- Transactions
- Deposit transactions can be derived from its L1 origin, identical with V0 batch.
- User transactions can be derived by following way:
- Recover `V` value of TX signature from `y_parity_bits` and L2 chainId, as described in optimization strategies.
- When parsing `tx_tos`, `contract_creation_bits` is used to determine if the TX has `to` value or not.
## Integration
### Channel Reader (Batch Decoding)
The Channel Reader decodes the span-batch, as described in the [span-batch format](#span-batch-format).
A set of derived attributes is computed as described above. Then cached with the decoded result:
### Batch Queue
A span-batch is buffered as a singular large batch,
by its starting timestamp (transformed `rel_timestamp`).
Span-batches share the same queue with v0 batches: batches are processed in L1 inclusion order.
A set of modified validation rules apply to the span-batches.
Rules are enforced with the [contextual definitions](./derivation.md#batch-queue) as v0-batch validation:
`epoch`, `inclusion_block_number`, `next_timestamp`
Definitions:
- `batch` as defined in the [Span batch format section][span-batch-format].
- `prev_l2_block` is the L2 block from the current safe chain,
whose timestamp is at `span_start.timestamp - l2_block_time`
Span-batch rules, in validation order:
- `batch_origin` is determined like with singular batches:
- `batch.epoch_num == epoch.number+1`:
- If `next_epoch` is not known -> `undecided`:
i.e. a batch that changes the L1 origin cannot be processed until we have the L1 origin data.
- If known, then define `batch_origin` as `next_epoch`
- `batch_origin.timestamp < span_batch_upgrade_timestamp` -> `drop`:
i.e. enforce the [span batch upgrade activation rule](#span-batch-activation-rule).
- `span_start.timestamp > next_timestamp` -> `future`: i.e. the batch must be ready to process,
but does not have to start exactly at the `next_timestamp`, since it can overlap with previously processed blocks,
- `span_end.timestamp < next_timestamp` -> `drop`: i.e. the batch must have at least one new block to process.
- If there's no `prev_l2_block` in the current safe chain -> `drop`: i.e. the timestamp must be aligned.
- `batch.parent_check != prev_l2_block.hash[:20]` -> `drop`:
i.e. the checked part of the parent hash must be equal to the same part of the corresponding L2 block hash.
- Sequencing-window checks:
- Note: The sequencing window is enforced for the *batch as a whole*:
if the batch was partially invalid instead, it would drop the oldest L2 blocks,
which makes the later L2 blocks invalid.
- Variables:
- `origin_changed_bit = origin_bits[0]`: `true` if the first L2 block changed its L1 origin, `false` otherwise.
- `start_epoch_num = batch.l1_origin_num - sum(origin_bits) + (origin_changed_bit ? 1 : 0)`
- `end_epoch_num = batch.l1_origin_num`
- Rules:
- `start_epoch_num + sequence_window_size < inclusion_block_number` -> `drop`:
i.e. the batch must be included timely.
- `start_epoch_num > prev_l2_block.l1_origin.number + 1` -> `drop`:
i.e. the L1 origin cannot change by more than one L1 block per L2 block.
- If `batch.l1_origin_check` does not match the canonical L1 chain at `end_epoch_num` -> `drop`:
verify the batch is intended for this L1 chain.
- After upper `l1_origin_check` check is passed, we don't need to check if the origin
is past `inclusion_block_number` because of the following invariant.
- Invariant: the epoch-num in the batch is always less than the inclusion block number,
if and only if the L1 epoch hash is correct.
- `start_epoch_num < prev_l2_block.l1_origin.number` -> `drop`:
epoch number cannot be older than the origin of parent block
- Max Sequencer time-drift checks:
- Note: The max time-drift is enforced for the *batch as a whole*, to keep the possible output variants small.
- Variables:
- `block_input`: an L2 block from the span-batch,
with L1 origin as derived from the `origin_bits` and now established canonical L1 chain.
- `next_epoch`: `block_input.origin`'s next L1 block.
It may reach to the next origin outside the L1 origins of the span.
- Rules:
- For each `block_input` whose timestamp is greater than `safe_head.timestamp`:
- `block_input.timestamp < block_input.origin.time` -> `drop`: enforce the min L2 timestamp rule.
- `block_input.timestamp > block_input.origin.time + max_sequencer_drift`: enforce the L2 timestamp drift rule,
but with exceptions to preserve above min L2 timestamp invariant:
- `len(block_input.transactions) == 0`:
- `origin_bits[i] == 0`: `i` is the index of `block_input` in the span batch.
So this implies the block_input did not advance the L1 origin,
and must thus be checked against `next_epoch`.
- If `next_epoch` is not known -> `undecided`:
without the next L1 origin we cannot yet determine if time invariant could have been kept.
- If `block_input.timestamp >= next_epoch.time` -> `drop`:
the batch could have adopted the next L1 origin without breaking the `L2 time >= L1 time` invariant.
- `len(block_input.transactions) > 0`: -> `drop`:
when exceeding the sequencer time drift, never allow the sequencer to include transactions.
- And for all transactions:
- `drop` if the `batch.tx_datas` list contains a transaction
that is invalid or derived by other means exclusively:
- any transaction that is empty (zero length `tx_data`)
- any [deposited transactions][g-deposit-tx-type] (identified by the transaction type prefix byte in `tx_data`)
- Overlapped blocks checks:
- Note: If the span batch overlaps the current L2 safe chain, we must validate all overlapped blocks.
- Variables:
- `block_input`: an L2 block derived from the span-batch.
- `safe_block`: an L2 block from the current L2 safe chain, at same timestamp as `block_input`
- Rules:
- For each `block_input`, whose timestamp is less than `next_timestamp`:
- `block_input.l1_origin.number != safe_block.l1_origin.number` -> `drop`
- `block_input.transactions != safe_block.transactions` -> `drop`
- compare excluding deposit transactions
Once validated, the batch-queue then emits a block-input for each of the blocks included in the span-batch.
The next derivation stage is thus only aware of individual block inputs, similar to the previous V0 batch,
although not strictly a "v0 batch" anymore.
### Batcher
Instead of transforming L2 blocks into batches,
the blocks should be buffered to form a span-batch.
Ideally the L2 blocks are buffered as block-inputs, to maximize the span of blocks covered by the span-batch:
span-batches of single L2 blocks do not increase efficiency as much as with larger spans.
This means that the `(c *channelBuilder) AddBlock` function is changed to
not directly call `(co *ChannelOut) AddBatch` but defer that until a minimum number of blocks have been buffered.
Output-size estimation of the queued up blocks is not possible until the span-batch is written to the channel.
Past a given number of blocks, the channel may be written for estimation, and then re-written if more blocks arrive.
The [batcher functionality](./batcher.md) stays the same otherwise: unsafe blocks are transformed into batches,
encoded in compressed channels, and then split into frames for submission to L1.
Batcher implementations can implement different heuristics and re-attempts to build the most gas-efficient data-txs.
# Superchain Configuration
The SuperchainConfig contract is used to manage global configuration values for multiple OP Chains within
a single Superchain network.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Configurable values](#configurable-values)
- [Configuration data flow](#configuration-data-flow)
- [Pausability](#pausability)
- [Paused identifiers](#paused-identifiers)
- [Scope of pausability](#scope-of-pausability)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Configurable values
Configurability of the Superchain is currently limited to two values:
The `SuperchainConfig` contract manages the following configuration values:
- `PAUSED_SLOT`: A boolean value indicating whether the Superchain is paused.
- `GUARDIAN_SLOT`: The address of the guardian, which can pause and unpause the system.
## Configuration data flow
All contracts which read from the `SuperchainConfig` contract hold its address as storage values
in the proxy account, and call directly to it when reading configuration data.
```mermaid
flowchart TD
StandardBridge --> SuperchainConfig
L1ERC721Bridge --> SuperchainConfig
L1CrossDomainMessenger --> SuperchainConfig
OptimismPortal --> SuperchainConfig
```
### Pausability
The Superchain pause feature is a safety mechanism designed to temporarily halt withdrawals from the system in
an emergency situation. The Guardian role is authorized to pause and unpause the system.
#### Paused identifiers
When the system is paused the `Paused(string identifier)` event is emitted. This allows for the
caller to provide additional information to be used during incident response.
#### Scope of pausability
The pause applies specifically to withdrawals of assets from the L1 bridge contracts. The L2 bridge contracts
are not pausable, on the basis that issues on L2 can be addressed more easily by a hard fork in the consensus
layer.
When the Pause is activated, the following methods are disabled:
1. `OptimismPortal.proveWithdrawalTransaction()`
1. `OptimismPortal.finalizeWithdrawalTransaction()`
1. `L1CrossDomainMessenger.relayMessage()`
1. `StandardBridge.finalizeBridgeERC20()`
1. `StandardBridge.finalizeBridgeETH()`
1. `L1ERC721Bridge.finalizeBridgeERC721()`
# Superchain Upgrades
Superchain upgrades, also known as forks or hardforks, implement consensus-breaking changes.
A Superchain upgrade requires the node software to support up to a given Protocol Version.
The version indicates support, the upgrade indicates the activation of new functionality.
This document lists the protocol versions of the OP-Stack, starting at the Bedrock upgrade,
as well as the default Superchain Targets.
Activation rule parameters of network upgrades are configured as part of the Superchain Target specification:
chains following the same Superchain Target upgrade synchronously.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Protocol Version](#protocol-version)
- [Protocol Version Format](#protocol-version-format)
- [Build identifier](#build-identifier)
- [Major versions](#major-versions)
- [Minor versions](#minor-versions)
- [Patch versions](#patch-versions)
- [Pre-releases](#pre-releases)
- [Protocol Version Exposure](#protocol-version-exposure)
- [Superchain Target](#superchain-target)
- [Superchain Version signaling](#superchain-version-signaling)
- [`ProtocolVersions` L1 contract](#protocolversions-l1-contract)
- [Activation rules](#activation-rules)
- [L2 Block-number based activation (deprecated)](#l2-block-number-based-activation-deprecated)
- [L2 Block-timestamp based activation](#l2-block-timestamp-based-activation)
- [OP-Stack Protocol versions](#op-stack-protocol-versions)
- [Post-Bedrock Network upgrades](#post-bedrock-network-upgrades)
- [Regolith](#regolith)
- [Canyon](#canyon)
- [Delta](#delta)
- [Ecotone](#ecotone)
- [Fjord](#fjord)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Protocol Version
The Protocol Version documents the progression of the total set of canonical OP-Stack specifications.
Components of the OP-Stack implement the subset of their respective protocol component domain,
up to a given Protocol Version of the OP-Stack.
OP-Stack mods, i.e. non-canonical extensions to the OP-Stack, are not included in the versioning of the Protocol.
Instead, mods must specify which upstream Protocol Version they are based on and where breaking changes are made.
This ensures tooling of the OP-Stack can be shared and collaborated on with OP-Stack mods.
The Protocol Version is NOT a hardfork identifier, but rather indicates software-support for a well-defined set
of features introduced in past and future hardforks, not the activation of said hardforks.
Changes that can be included in prospective Protocol Versions may be included in the specifications as proposals,
with explicit notice of the Protocol Version they are based on.
This enables an iterative integration process into the canonical set of specifications,
but does not guarantee the proposed specifications become canonical.
Note that the Protocol Version only applies to the Protocol specifications with the Superchain Targets specified within.
This versioning is independent of the [Semver] versioning used in OP Stack smart-contracts,
and the [Semver]-versioned reference software of the OP-Stack.
### Protocol Version Format
The Protocol Version is [Semver]-compatible.
It is encoded as a single 32 bytes long `<protocol version>`.
The version must be encoded as 32 bytes of `DATA` in JSON RPC usage.
The encoding is typed, to ensure future-compatibility.
```text
<protocol version> ::= <version-type><typed-payload>
<version-type> ::= <uint8>
<typed-payload> ::= <31 bytes>
```
version-type `0`:
```text
<reserved><build><major><minor><patch><pre-release>
<reserved> ::= <7 zeroed bytes>
<build> ::= <8 bytes>
<major> ::= <big-endian uint32>
<minor> ::= <big-endian uint32>
<patch> ::= <big-endian uint32>
<pre-release> ::= <big-endian uint32>
```
The `<reserved>` bytes of the Protocol Version are reserved for future extensions.
Protocol versions with a different `<version-type>` should not be compared directly.
[Semver]: https://semver.org/
#### Build identifier
The `<build>` identifier, as defined by [Semver], is ignored when determining version precedence.
The `<build>` must be non-zero to apply to the protocol version.
Modifications of the OP-Stack should define a `<build>` to distinguish from the canonical protocol feature-set.
Changes to the `<build>` may be encoded in the `<build>` itself to stay aligned with the upstream protocol.
The major/minor/patch versions should align with that of the upstream protocol that the modifications are based on.
Users of the protocol can choose to implement custom support for the alternative `<build>`,
but may work out of the box if the major features are consistent with that of the upstream protocol version.
The 8 byte `<build>` identifier may be presented as a string for human readability if the contents are alpha-numeric,
including `-` and `.`, as outlined in the [Semver] format specs. Trailing `0` bytes can be used for padding.
It may be presented as `0x`-prefixed hex string otherwise.
#### Major versions
Major version changes indicate support for new consensus-breaking functionality.
Major versions should retain support for functionality of previous major versions for
syncing/indexing of historical chain data.
Implementations may drop support for previous Major versions, when there are viable alternatives,
e.g. `l2geth` for pre-Bedrock data.
#### Minor versions
Minor version changes indicate support for backward compatible extensions,
including backward-compatible additions to the set of chains in a Superchain Target.
Backward-compatibility is defined by the requirement for existing end-users to upgrade nodes and tools or not.
Minor version changes may also include optional offchain functionality, such as additional syncing protocols.
#### Patch versions
Patch version changes indicate backward compatible bug fixes and improvements.
#### Pre-releases
Pre-releases of the protocol are proposals: these are not stable targets for production usage.
A pre-release might not satisfy the intended compatibility requirements as denoted by its associated normal version.
The `<pre-release>` must be non-zero to apply to the protocol version.
The `<pre-release>` `0`-value is reserved for non-prereleases, i.e. `v3.1.0` is higher than `v3.1.0-1`.
Node-software may support a pre-release, but must not activate any protocol changes without the user explicitly
opting in through the means of a feature-flag or configuration change.
A pre-release is not an official version and is meant for protocol developers to communicate an experimental changeset
before the changeset is reviewed by governance. Pre-releases are subject to change.
### Protocol Version Exposure
The Protocol Version is not exposed to the application-layer environment:
hardforks already expose the change of functionality upon activation as required,
and the Protocol Version is meant for offchain usage only.
The protocol version indicates support rather than activation of functionality.
There is one exception however: signaling by onchain components to offchain components.
More about this in [Superchain Version signaling].
## Superchain Target
Changes to the L2 state-transition function are transitioned into deterministically across all nodes
through an **activation rule**.
Changes to L1 smart-contracts must be compatible with the latest activated L2 functionality,
and are executed through **L1 contract-upgrades**.
A Superchain Target defines a set of activation rules and L1 contract upgrades shared between OP-Stack chains,
to upgrade the chains collectively.
### Superchain Version signaling
Each Superchain Target tracks the protocol changes, and signals the `recommended` and `required`
Protocol Version ahead of activation of new breaking functionality.
- `recommended`: a signal in advance of a network upgrade, to alert users of the protocol change to be prepared for.
Node software is recommended to signal the recommendation to users through logging and metrics.
- `required`: a signal shortly in advance of a breaking network upgrade, to alert users of breaking changes.
Users may opt in to elevated alerts or preventive measures, to ensure consistency with the upgrade.
Signaling is done through a L1 smart-contract that is monitored by the OP-Stack software.
Not all components of the OP-Stack are required to directly monitor L1 however:
cross-component APIs like the Engine API may be used to forward the Protocol Version signals,
to keep components encapsulated from L1.
See [`engine_signalOPStackVersionV1`](./exec-engine.md#enginesignalopstackversionv1).
### `ProtocolVersions` L1 contract
The `ProtocolVersions` contract on L1 enables L2 nodes to pick up on superchain protocol version signals.
The interface is:
- Required storage slot: `bytes32(uint256(keccak256("protocolversion.required")) - 1)`
- Recommended storage slot: `bytes32(uint256(keccak256("protocolversion.recommended")) - 1)`
- Required getter: `required()` returns `ProtocolVersion`
- Recommended getter `recommended()` returns `ProtocolVersion`
- Version updates also emit a typed event:
`event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data)`
## Activation rules
The below L2-block based activation rules may be applied in two contexts:
- The rollup node, specified through the rollup configuration (known as `rollup.json`),
referencing L2 blocks (or block input-attributes) that pass through the derivation pipeline.
- The execution engine, specified through the chain configuration (known as the `config` part of `genesis.json`),
referencing blocks or input-attributes that are part of, or applied to, the L2 chain.
For both types of configurations, some activation parameters may apply to all chains within the superchain,
and are then retrieved from the superchain target configuration.
### L2 Block-number based activation (deprecated)
Activation rule: `upgradeNumber != null && block.number >= upgradeNumber`
Starting at, and including, the L2 `block` with `block.number >= upgradeNumber`, the upgrade rules apply.
If the upgrade block-number `upgradeNumber` is not specified in the configuration, the upgrade is ignored.
This block number based method has commonly been used in L1 up until the Bellatrix/Paris upgrade, a.k.a. The Merge,
which was upgraded through special rules.
This method is not superchain-compatible, as the activation-parameter is chain-specific
(different chains may have different block-heights at the same moment in time).
This applies to the L2 block number, not to the L1-origin block number.
This means that an L2 upgrade may be inactive, and then active, without changing the L1-origin.
### L2 Block-timestamp based activation
Activation rule: `upgradeTime != null && block.timestamp >= upgradeTime`
Starting at, and including, the L2 `block` with `block.timestamp >= upgradeTime`, the upgrade rules apply.
If the upgrade block-timestamp `upgradeTime` is not specified in the configuration, the upgrade is ignored.
This is the preferred superchain upgrade activation-parameter type:
it is synchronous between all L2 chains and compatible with post-Merge timestamp-based chain upgrades in L1.
This applies to the L2 block timestamp, not to the L1-origin block timestamp.
This means that an L2 upgrade may be inactive, and then active, without changing the L1-origin.
This timestamp based method has become the default on L1 after the Bellatrix/Paris upgrade, a.k.a. The Merge,
because it can be planned in accordance with beacon-chain epochs and slots.
Note that the L2 version is not limited to timestamps that match L1 beacon-chain slots or epochs.
A timestamp may be chosen to be synchronous with a specific slot or epoch on L1,
but the matching L1-origin information may not be present at the time of activation on L2.
## OP-Stack Protocol versions
- `v1.0.0`: 2021 Jan 16th - Mainnet Soft Launch, based on OVM.
([announcement](https://medium.com/ethereum-optimism/mainnet-soft-launch-7cacc0143cd5))
- `v1.1.0`: 2021 Aug 19th - Community launch.
([announcement](https://medium.com/ethereum-optimism/community-launch-7c9a2a9d3e84))
- `v2.0.0`: 2021 Nov 12th - the EVM-Equivalence update, also known as OVM 2.0 and chain regenesis.
([announcement](https://twitter.com/optimismfnd/status/1458953238867165192))
- `v2.1.0`: 2022 May 31st - Optimism Collective.
([announcement](https://optimism.mirror.xyz/gQWKlrDqHzdKPsB1iUnI-cVN3v0NvsWnazK7ajlt1fI)).
- `v3.0.0-1`: 2023 Jan 13th - Bedrock pre-release, deployed on OP-Goerli, and later Base-Goerli.
- `v3.0.0`: 2023 Jun 6th - Bedrock, including the Regolith hardfork improvements, first deployed on OP-Mainnet.
- `v4.0.0`: TBD - Canyon.
[Governance proposal](https://gov.optimism.io/t/final-upgrade-proposal-2-canyon-network-upgrade/7088).
- `v5.0.0-1`: Delta - Experimental, devnet pre-release stage.
- `v6.0.0-1`: Ecotone - Very experimental, in development.
## Post-Bedrock Network upgrades
### Regolith
The Regolith upgrade, named after a material best described as "deposited dust on top of a layer of bedrock",
implements minor changes to deposit processing, based on reports of the Sherlock Audit-contest and findings in
the Bedrock Optimism Goerli testnet.
Summary of changes:
- The `isSystemTx` boolean is disabled, system transactions now use the same gas accounting rules as regular deposits.
- The actual deposit gas-usage is recorded in the receipt of the deposit transaction,
and subtracted from the L2 block gas-pool.
Unused gas of deposits is not refunded with ETH however, as it is burned on L1.
- The `nonce` value of the deposit sender account, before the transaction state-transition, is recorded in a new
optional field (`depositNonce`), extending the transaction receipt (i.e. not present in pre-Regolith receipts).
- The recorded deposit `nonce` is used to correct the transaction and receipt metadata in RPC responses,
including the `contractAddress` field of deposits that deploy contracts.
- The `gas` and `depositNonce` data is committed to as part of the consensus-representation of the receipt,
enabling the data to be safely synced between independent L2 nodes.
- The L1-cost function was corrected to more closely match pre-Bedrock behavior.
The [deposit specification](./deposits.md) specifies the deposit changes of the Regolith upgrade in more detail.
The [execution engine specification](./exec-engine.md) specifies the L1 cost function difference.
The Regolith upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the
rollup-node (`regolith_time`) and execution engine (`config.regolithTime`).
## Canyon
The Canyon upgrade contains the Shapella upgrade from L1 and some minor protocol fixes.
- Shapella Upgrade
- [EIP-3651: Warm COINBASE](https://eips.ethereum.org/EIPS/eip-3651)
- [EIP-3855: PUSH0 instruction](https://eips.ethereum.org/EIPS/eip-3855)
- [EIP-3860: Limit and meter initcode](https://eips.ethereum.org/EIPS/eip-3860)
- [EIP-4895: Beacon chain push withdrawals as operations](https://eips.ethereum.org/EIPS/eip-4895)
- [Withdrawals are prohibited in P2P Blocks](./rollup-node-p2p.md#block-validation)
- [Withdrawals should be set to the empty array with Canyon](./derivation.md#building-individual-payload-attributes)
- [EIP-6049: Deprecate SELFDESTRUCT](https://eips.ethereum.org/EIPS/eip-6049)
- [Modifies the EIP-1559 Denominator](./exec-engine.md#1559-parameters)
- [Channel Ordering Fix](./derivation.md#reading)
- [Adds the deposit nonce & deposit nonce version to the deposit receipt hash](./deposits.md#deposit-receipt)
- [Deploys the create2Deployer to `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2`](./predeploys.md#create2deployer)
The Canyon upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the
rollup-node (`canyon_time`) and execution engine (`config.canyonTime`). Shanghai time in the
execution engine should be set to the same time as the Canyon time.
## Delta
The Delta upgrade consists of a single consensus-layer feature: [Span Batches](./span-batches.md).
The Delta upgrade uses a *L2 block-timestamp* activation-rule, and is specified only in the rollup-node (`delta_time`).
## Ecotone
The Ecotone upgrade contains the Dencun upgrade from L1, and adopts EIP-4844 blobs for data-availability.
Dencun Upgrade:
- Cancun (Execution Layer):
- [EIP-1153: Transient storage opcodes](https://eips.ethereum.org/EIPS/eip-1153)
- [EIP-4844: Shard Blob Transactions](https://eips.ethereum.org/EIPS/eip-4844)
- [Blob transactions are disabled](./exec-engine.md#ecotone-disable-blob-transactions)
- [EIP-4788: Beacon block root in the EVM](https://eips.ethereum.org/EIPS/eip-4788)
- [The L1 beacon block root is embedded into L2](./exec-engine.md#ecotone-beacon-block-root)
- [The Beacon roots contract deployment is automated](./derivation.md#ecotone-beacon-block-roots-contract-deployment-eip-4788)
- [EIP-5656: MCOPY - Memory copying instruction](https://eips.ethereum.org/EIPS/eip-5656)
- [EIP-6780: SELFDESTRUCT only in same transaction](https://eips.ethereum.org/EIPS/eip-6780)
- [EIP-7516: BLOBBASEFEE opcode](https://eips.ethereum.org/EIPS/eip-7516)
- [BLOBBASEFEE always pushes 1 onto the stack](./exec-engine.md#ecotone-disable-blob-transactions)
- Deneb (Consensus Layer): *not applicable to L2*
- [EIP-7044: Perpetually Valid Signed Voluntary Exits](https://eips.ethereum.org/EIPS/eip-7044)
- [EIP-7045: Increase Max Attestation Inclusion Slot](https://eips.ethereum.org/EIPS/eip-7045)
- [EIP-7514: Add Max Epoch Churn Limit](https://eips.ethereum.org/EIPS/eip-7514)
Data Availability (DA) upgrade:
- Blobs Data Availability: support blobs DA the [L1 Data-retrieval stage](./derivation.md#ecotone-blob-retrieval).
- Rollup fee update: support blobs DA in
[L1 Data Fee computation](./exec-engine.md#ecotone-l1-cost-fee-changes-eip-4844-da)
- Auto-upgrading and extension of the [L1 Attributes Predeployed Contract](./deposits.md#ecotone-l1block-upgrade)
(also known as `L1Block` predeploy)
## Fjord
Name of the next upgrade after Ecotone. Placeholder for development coordination.
# System Config
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [System config contents (version 0)](#system-config-contents-version-0)
- [`batcherHash` (`bytes32`)](#batcherhash-bytes32)
- [Scalars](#scalars)
- [Pre-Ecotone `scalar`, `overhead` (`uint256,uint256`)](#pre-ecotone-scalar-overhead-uint256uint256)
- [Ecotone `scalar`, `overhead` (`uint256,uint256`) change](#ecotone-scalar-overhead-uint256uint256-change)
- [`gasLimit` (`uint64`)](#gaslimit-uint64)
- [`unsafeBlockSigner` (`address`)](#unsafeblocksigner-address)
- [Writing the system config](#writing-the-system-config)
- [Reading the system config](#reading-the-system-config)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
The `SystemConfig` is a contract on L1 that can emit rollup configuration changes as log events.
The rollup [block derivation process](./derivation.md) picks up on these log events and applies the changes.
## System config contents (version 0)
Version 0 of the system configuration contract defines the following parameters:
### `batcherHash` (`bytes32`)
A versioned hash of the current authorized batcher sender(s), to rotate keys as batch-submitter.
The first byte identifies the version.
Version `0` embeds the current batch submitter ethereum address (`bytes20`) in the last 20 bytes of the versioned hash.
In the future this versioned hash may become a commitment to a more extensive configuration,
to enable more extensive redundancy and/or rotation configurations.
### Scalars
The L1 fee parameters, also known as Gas Price Oracle (GPO) parameters, are used to compute the L1
data fee applied to an L2 transaction. The specific parameters used depend on the upgrades that
are active.
Fee parameter updates are signaled to L2 through the `GAS_CONFIG` log-event of the `SystemConfig`.
#### Pre-Ecotone `scalar`, `overhead` (`uint256,uint256`)
The `overhead` and `scalar` are consulted and passed to the L2 via L1 attribute info.
The values are interpreted as big-endian `uint256`.
#### Ecotone `scalar`, `overhead` (`uint256,uint256`) change
After Ecotone activation:
- The `scalar` attribute encodes additional scalar information, in a versioned encoding scheme.
- The `overhead` value is ignored: it does not affect the L2 state-transition output.
The `scalar` is encoded as big-endian `uint256`, interpreted as `bytes32`, and composed as following:
*Byte ranges are indicated with `[` (inclusive) and `)` (exclusive).
- `0`: scalar-version byte
- `[1, 32)`: depending scalar-version:
- Scalar-version `0`:
- `[1, 28)`: padding, should be zero.
- `[28, 32)`: big-endian `uint32`, encoding the L1-fee `baseFeeScalar`
- This version implies the L1-fee `blobBaseFeeScalar` is set to 0.
- In the event there are non-zero bytes in the padding area, `baseFeeScalar` must be set to MaxUint32.
- This version is compatible with the pre-Ecotone `scalar` value (assuming a `uint32` range).
- Scalar-version `1`:
- `[1, 24)`: padding, must be zero.
- `[24, 28)`: big-endian `uint32`, encoding the `blobBaseFeeScalar`
- `[28, 32)`: big-endian `uint32`, encoding the `baseFeeScalar`
- This version is meant to configure the EIP-4844 blob fee component, once blobs are used for data-availability.
- Other scalar-version values: unrecognized.
OP-Stack forks are recommended to utilize the `>= 128` scalar-version range and document their `scalar` encoding.
Invalid and unrecognized scalar event-data should be ignored,
and the last valid configuration should continue to be utilized.
The `baseFeeScalar` and `blobBaseFeeScalar` are incorporated into the L2 through the
[Ecotone L1 attributes deposit transaction calldata](./deposits.md#l1-attributes---ecotone).
Future upgrades of the `SystemConfig` contract may provide additional typed getters/setters
for the versioned scalar information.
In Ecotone the existing `setGasConfig` function, and `scalar` and `overhead` getters, continue to function.
When the batch-submitter utilizes EIP-4844 blob data for data-availability
it can adjust the scalars to accurately price the resources:
- `baseFeeScalar` to correspond to the share of the user-transaction (per byte)
in the total regular L1 EVM gas usage consumed by the data-transaction of the batch-submitter.
For blob transactions this is the fixed intrinsic gas cost of the L1 transaction.
- `blobBaseFeeScalar` to correspond to share of a user-transaction (per byte)
in the total Blob data that is introduced by the data-transaction of the batch-submitter.
### `gasLimit` (`uint64`)
The gas limit of the L2 blocks is configured through the system config.
Changes to the L2 gas limit are fully applied in the first L2 block with the L1 origin that introduced the change,
as opposed to the 1/1024 adjustments towards a target as seen in limit updates of L1 blocks.
### `unsafeBlockSigner` (`address`)
Blocks are gossiped around the p2p network before they are made available on L1.
To prevent denial of service on the p2p layer, these unsafe blocks must be
signed with a particular key to be accepted as "canonical" unsafe blocks.
The address corresponding to this key is the `unsafeBlockSigner`. To ensure
that its value can be fetched with a storage proof in a storage layout independent
manner, it is stored at a special storage slot corresponding to
`keccak256("systemconfig.unsafeblocksigner")`.
Unlike the other values, the `unsafeBlockSigner` only operates on blockchain
policy. It is not a consensus level parameter.
## Writing the system config
The `SystemConfig` contract applies authentication to all writing contract functions,
the configuration management can be configured to be any type of ethereum account or contract.
On a write, an event is emitted for the change to be picked up by the L2 system,
and a copy of the new written configuration variable is retained in L1 state to read with L1 contracts.
## Reading the system config
A rollup node initializes its derivation process by finding a starting point based on its past L2 chain:
- When started from L2 genesis, the initial system configuration is retrieved from the rollup chain configuration.
- When started from an existing L2 chain, a previously included L1 block is determined as derivation starting point,
and the system config can thus be retrieved from the last L2 block that referenced the L1 block as L1 origin:
- If the chain state precedes the Ecotone upgrade, `batcherHash`, `overhead` and `scalar` are
retrieved from the L1 block info transaction. Otherwise, `batcherHash`, `baseFeeScalar`, and
`blobBaseFeeScalar` are retrieved instead.
- `gasLimit` is retrieved from the L2 block header.
- other future variables may also be retrieved from other contents of the L2 block, such as the header.
After preparing the initial system configuration for the given L1 starting input,
the system configuration is updated by processing all receipts from each new L1 block.
The contained log events are filtered and processed as follows:
- the log event contract address must match the rollup `SystemConfig` deployment
- the first log event topic must match the ABI hash of `ConfigUpdate(uint256,uint8,bytes)`
- the second topic determines the version. Unknown versions are critical derivation errors.
- the third topic determines the type of update. Unknown types are critical derivation errors.
- the remaining event data is opaque, encoded as ABI bytes (i.e. includes offset and length data),
and encodes the configuration update. In version `0` the following types are supported:
- type `0`: `batcherHash` overwrite, as `bytes32` payload.
- type `1`: Pre-Ecotone, `overhead` and `scalar` overwrite, as two packed `uint256`
entries. After Ecotone upgrade, `overhead` is ignored and `scalar` interpreted as a [versioned
encoding](#ecotone-scalar-overhead-uint256uint256-change) that updates `baseFeeScalar` and
`blobBaseFeeScalar`.
- type `2`: `gasLimit` overwrite, as `uint64` payload.
- type `3`: `unsafeBlockSigner` overwrite, as `address` payload.
[encodePacked]: https://docs.soliditylang.org/en/latest/abi-spec.html#non-standard-packed-mode
Note that individual derivation stages may be processing different L1 blocks,
and should thus maintain individual system configuration copies,
and apply the event-based changes as the stage traverses to the next L1 block.
# Withdrawals
<!-- All glossary references in this file. -->
[g-deposits]: glossary.md#deposits
[g-deposited]: glossary.md#deposited-transaction
[deposit-tx-type]: glossary.md#deposited-transaction-type
[g-withdrawal]: glossary.md#withdrawal
[g-mpt]: glossary.md#merkle-patricia-trie
[g-relayer]: glossary.md#withdrawals
[g-execution-engine]: glossary.md#execution-engine
[Withdrawals][g-withdrawal] are cross domain transactions which are initiated on L2, and finalized by a transaction
executed on L1. Notably, withdrawals may be used by an L2 account to call an L1 contract, or to transfer ETH from
an L2 account to an L1 account.
**Vocabulary note**: _withdrawal_ can refer to the transaction at various stages of the process, but we introduce
more specific terms to differentiate:
- A _withdrawal initiating transaction_ refers specifically to a transaction on L2 sent to the Withdrawals predeploy.
- A _withdrawal proving transaction_ refers specifically to an L1 transaction
which proves the withdrawal is correct (that it has been included in a merkle
tree whose root is available on L1).
- A _withdrawal finalizing transaction_ refers specifically to an L1 transaction which finalizes and relays the
withdrawal.
Withdrawals are initiated on L2 via a call to the Message Passer predeploy contract, which records the important
properties of the message in its storage.
Withdrawals are proven on L1 via a call to the `OptimismPortal`, which proves the inclusion of this withdrawal message.
Withdrawals are finalized on L1 via a call to the `OptimismPortal` contract,
which verifies that the fault challenge period has passed since the withdrawal message has been proved.
In this way, withdrawals are different from [deposits][g-deposits] which make use of a special transaction type in the
[execution engine][g-execution-engine] client. Rather, withdrawals transaction must use smart contracts on L1 for
finalization.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**
- [Withdrawal Flow](#withdrawal-flow)
- [On L2](#on-l2)
- [On L1](#on-l1)
- [The L2ToL1MessagePasser Contract](#the-l2tol1messagepasser-contract)
- [Addresses are not Aliased on Withdrawals](#addresses-are-not-aliased-on-withdrawals)
- [The Optimism Portal Contract](#the-optimism-portal-contract)
- [Withdrawal Verification and Finalization](#withdrawal-verification-and-finalization)
- [Security Considerations](#security-considerations)
- [Key Properties of Withdrawal Verification](#key-properties-of-withdrawal-verification)
- [Handling Successfully Verified Messages That Fail When Relayed](#handling-successfully-verified-messages-that-fail-when-relayed)
- [OptimismPortal can send arbitrary messages on L1](#optimismportal-can-send-arbitrary-messages-on-l1)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Withdrawal Flow
We first describe the end to end flow of initiating and finalizing a withdrawal:
### On L2
An L2 account sends a withdrawal message (and possibly also ETH) to the `L2ToL1MessagePasser` predeploy contract.
This is a very simple contract that stores the hash of the withdrawal data.
### On L1
1. A [relayer][g-relayer] submits a withdrawal proving transaction with the required inputs
to the `OptimismPortal` contract.
The relayer is not necessarily the same entity which initiated the withdrawal on L2.
These inputs include the withdrawal transaction data, inclusion proofs, and a block number. The block number
must be one for which an L2 output root exists, which commits to the withdrawal as registered on L2.
1. The `OptimismPortal` contract retrieves the output root for the given block number from the `L2OutputOracle`'s
`getL2Output()` function, and performs the remainder of the verification process internally.
1. If proof verification fails, the call reverts. Otherwise the hash is recorded to prevent it from being re-proven.
Note that the withdrawal can be proven more than once if the corresponding output root changes.
1. After the withdrawal is proven, it enters a 7 day challenge period, allowing time for other network participants
to challenge the integrity of the corresponding output root.
1. Once the challenge period has passed, a relayer submits a withdrawal finalizing transaction to the
`OptimismPortal` contract.
The relayer doesn't need to be the same entity that initiated the withdrawal on L2.
1. The `OptimismPortal` contract receives the withdrawal transaction data and verifies that the withdrawal has
both been proven and passed the challenge period.
1. If the requirements are not met, the call reverts. Otherwise the call is forwarded, and the hash is recorded to
prevent it from being replayed.
## The L2ToL1MessagePasser Contract
[message-passer-contract]: #the-l2tol1messagepasser-contract
A withdrawal is initiated by calling the L2ToL1MessagePasser contract's `initiateWithdrawal` function.
The L2ToL1MessagePasser is a simple predeploy contract at `0x4200000000000000000000000000000000000016`
which stores messages to be withdrawn.
```js
interface L2ToL1MessagePasser {
event MessagePassed(
uint256 indexed nonce, // this is a global nonce value for all withdrawal messages
address indexed sender,
address indexed target,
uint256 value,
uint256 gasLimit,
bytes data,
bytes32 withdrawalHash
);
event WithdrawerBalanceBurnt(uint256 indexed amount);
function burn() external;
function initiateWithdrawal(address _target, uint256 _gasLimit, bytes memory _data) payable external;
function messageNonce() public view returns (uint256);
function sentMessages(bytes32) view external returns (bool);
}
```
The `MessagePassed` event includes all of the data that is hashed and
stored in the `sentMessages` mapping, as well as the hash itself.
### Addresses are not Aliased on Withdrawals
[address-aliasing]: #no-address-aliasing
When a contract makes a deposit, the sender's address is [aliased](./deposits.md#address-aliasing). The same is not true
of withdrawals, which do not modify the sender's address. The difference is that:
- on L2, the deposit sender's address is returned by the `CALLER` opcode, meaning a contract cannot easily tell if the
call originated on L1 or L2, whereas
- on L1, the withdrawal sender's address is accessed by calling the `l2Sender()` function on the `OptimismPortal`
contract.
Calling `l2Sender()` removes any ambiguity about which domain the call originated from. Still, developers will need to
recognize that having the same address does not imply that a contract on L2 will behave the same as a contract on L1.
## The Optimism Portal Contract
The Optimism Portal serves as both the entry and exit point to the Optimism L2. It is a contract which inherits from
the [OptimismPortal](./deposits.md#deposit-contract) contract, and in addition provides the following interface for
withdrawals:
- [`WithdrawalTransaction` type]
- [`OutputRootProof` type]
```js
interface OptimismPortal {
event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);
function l2Sender() returns(address) external;
function proveWithdrawalTransaction(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
) external;
function finalizeWithdrawalTransaction(
Types.WithdrawalTransaction memory _tx
) external;
}
```
## Withdrawal Verification and Finalization
The following inputs are required to prove and finalize a withdrawal:
- Withdrawal transaction data:
- `nonce`: Nonce for the provided message.
- `sender`: Message sender address on L2.
- `target`: Target address on L1.
- `value`: ETH to send to the target.
- `data`: Data to send to the target.
- `gasLimit`: Gas to be forwarded to the target.
- Proof and verification data:
- `l2OutputIndex`: The index in the L2 outputs where the applicable output root may be found.
- `outputRootProof`: Four `bytes32` values which are used to derive the output root.
- `withdrawalProof`: An inclusion proof for the given withdrawal in the L2ToL1MessagePasser contract.
These inputs must satisfy the following conditions:
1. The `l2OutputIndex` must be the index in the L2 outputs that contains the applicable output root.
1. `L2OutputOracle.getL2Output(l2OutputIndex)` returns a non-zero `OutputProposal`.
1. The keccak256 hash of the `outputRootProof` values is equal to the `outputRoot`.
1. The `withdrawalProof` is a valid inclusion proof demonstrating that a hash of the Withdrawal transaction data
is contained in the storage of the L2ToL1MessagePasser contract on L2.
## Security Considerations
### Key Properties of Withdrawal Verification
1. It should not be possible to 'double spend' a withdrawal, ie. to relay a withdrawal on L1 which does not
correspond to a message initiated on L2. For reference, see [this writeup][polygon-dbl-spend] of a vulnerability
of this type found on Polygon.
[polygon-dbl-spend]: https://gerhard-wagner.medium.com/double-spending-bug-in-polygons-plasma-bridge-2e0954ccadf1
1. For each withdrawal initiated on L2 (i.e. with a unique `messageNonce()`), the following properties must hold:
1. It should only be possible to prove the withdrawal once, unless the outputRoot for the withdrawal
has changed.
1. It should only be possible to finalize the withdrawal once.
1. It should not be possible to relay the message with any of its fields modified, ie.
1. Modifying the `sender` field would enable a 'spoofing' attack.
1. Modifying the `target`, `data`, or `value` fields would enable an attacker to dangerously change the
intended outcome of the withdrawal.
1. Modifying the `gasLimit` could make the cost of relaying too high, or allow the relayer to cause execution
to fail (out of gas) in the `target`.
### Handling Successfully Verified Messages That Fail When Relayed
If the execution of the relayed call fails in the `target` contract, it is unfortunately not possible to determine
whether or not it was 'supposed' to fail, and whether or not it should be 'replayable'. For this reason, and to
minimize complexity, we have not provided any replay functionality, this may be implemented in external utility
contracts if desired.
[`WithdrawalTransaction` type]: https://github.com/ethereum-optimism/optimism/blob/08daf8dbd38c9ffdbd18fc9a211c227606cdb0ad/packages/contracts-bedrock/src/libraries/Types.sol#L62-L69
[`OutputRootProof` type]: https://github.com/ethereum-optimism/optimism/blob/08daf8dbd38c9ffdbd18fc9a211c227606cdb0ad/packages/contracts-bedrock/src/libraries/Types.sol#L25-L30
### OptimismPortal can send arbitrary messages on L1
The `L2ToL1MessagePasser` contract's `initiateWithdrawal` function accepts a `_target` address and `_data` bytes,
which is passed to a `CALL` opcode on L1 when `finalizeWithdrawalTransaction` is called after the challenge
period. This means that, by design, the `OptimismPortal` contract can be used to send arbitrary transactions on
the L1, with the `OptimismPortal` as the `msg.sender`.
This means users of the `OptimismPortal` contract should be careful what permissions they grant to the portal.
For example, any ERC20 tokens mistakenly sent to the `OptimismPortal` contract are essentially lost, as they can
be claimed by anybody that pre-approves transfers of this token out of the portal, using the L2 to initiate the
approval and the L1 to prove and finalize the approval (after the challenge period).
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment