Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
cd726443
Unverified
Commit
cd726443
authored
Apr 11, 2023
by
protolambda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
specs: initial fault proof program/VM specs
parent
4016b3a0
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
424 additions
and
0 deletions
+424
-0
README.md
specs/README.md
+8
-0
fault-proof.svg
specs/assets/fault-proof.svg
+4
-0
fault-proof.md
specs/fault-proof.md
+412
-0
No files found.
specs/README.md
View file @
cd726443
...
@@ -24,6 +24,14 @@ that maintains 1:1 compatibility with Ethereum.
...
@@ -24,6 +24,14 @@ that maintains 1:1 compatibility with Ethereum.
-
[
Predeploys
](
predeploys.md
)
-
[
Predeploys
](
predeploys.md
)
-
[
Glossary
](
glossary.md
)
-
[
Glossary
](
glossary.md
)
### Experimental
Specifications of new features in active development.
-
[
Fault Proof
](
./fault-proof.md
)
-
[
Dispute Game
](
./dispute-game.md
)
-
[
Dispute Game Interface
](
./dispute-game-interface.md
)
## Design Goals
## Design Goals
Our aim is to design a protocol specification that is:
Our aim is to design a protocol specification that is:
...
...
specs/assets/fault-proof.svg
0 → 100644
View file @
cd726443
<?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=
"<mxfile host="app.diagrams.net" modified="2023-04-11T15:13:26.154Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0" etag="vDBsOIw1GRsWubY4oKHH" version="21.1.5" type="google"><diagram name="Page-1" id="5oXVfdM0MUB0GZk8333n">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</diagram></mxfile>"
><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
/>
&
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
specs/fault-proof.md
0 → 100644
View file @
cd726443
# 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-header <blockhash>`
](
#l1-header-blockhash
)
-
[
`l1-transactions <blockhash>`
](
#l1-transactions-blockhash
)
-
[
`l1-receipts <blockhash>`
](
#l1-receipts-blockhash
)
-
[
`l2-header <blockhash>`
](
#l2-header-blockhash
)
-
[
`l2-transactions <blockhash>`
](
#l2-transactions-blockhash
)
-
[
`l2-code <codehash>`
](
#l2-code-codehash
)
-
[
`l2-state-node <nodehash>`
](
#l2-state-node-nodehash
)
-
[
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
]
.

## 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 types
](
#pre-image-types
)
.
The communication happens over a simple request-response wire protocol:
-
The client initiates a request for data by writing a
`bytes32`
[
pre-image key
](
#pre-image-key-types
)
.
-
The
### 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 contex-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 bit 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:
-
`key`
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 the pre-image into the global store for usage by all fault proof VMs without upgrades.
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(key bytes32, offset uint64, span uint8, value bytes32)`
:
-
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 and 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 responsiblity 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 minimal wire-protocol over a blocking one-way stream:
```
text
<request> := <length prefix> <hint bytes> <end>
<length prefix> := big-endian uint32 # length of <hint bytes>
<hint bytes> := byte sequence
<end> := 0 byte
```
The
`<end>`
trailing zero byte allows the server to block the program
(since the communication is blocking) until the hint is processed.
### Pre-image communication
Pre-images are communicated with a minimal wire-protocol over a blocking two-way stream:
```
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
<hint bytes> := byte sequence #
```
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 timme,
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 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-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 transactions-list MPT nodes.
#### `l2-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>`
.
## 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 the execution trace of the VM, bounded with a base-case that proves a 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 [dispute-game specs](./dispute-game.md) for general dispute game system specifications,
> And [dispute-game-interface specs](./dispute-game-interface.md) for dispute game interface specifications.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment