Skip to content

Commit

Permalink
Deploying to gh-pages from @ 7a80089 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
tynes committed Jan 22, 2025
1 parent 3174486 commit 465c399
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 190 deletions.
23 changes: 15 additions & 8 deletions interop/overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ <h1 class="menu-title">OP Stack Specification</h1>
<!-- DOCTOC SKIP -->
<h1 id="interop"><a class="header" href="#interop">Interop</a></h1>
<p>The ability for a blockchain to easily read the state of another blockchain is called interoperability.
Low latency interoperability allows for horizontally scalable blockchains, a key feature of the superchain.</p>
Relatively trustless interop is possible between rollups by using L1 Ethereum as a hub. A message is
withdrawn from one chain to L1 and then deposited to another chain. The goal of OP Stack native interop
is to enable cross chain messaging at a much lower latency than going through L1. Low latency interoperability
allows for a horizontally scalable blockchain network.</p>
<p>Note: this document references an "interop network upgrade" as a temporary name. The pending name of the
network upgrade is isthmus.</p>
<div class="table-wrapper"><table><thead><tr><th>Term</th><th>Definition</th></tr></thead><tbody>
Expand All @@ -182,17 +185,21 @@ <h1 id="interop"><a class="header" href="#interop">Interop</a></h1>
<tr><td>Executing Message</td><td>An event emitted from a destination chain's <code>CrossL2Inbox</code> that includes an initiating message and identifier</td></tr>
<tr><td>Cross Chain Message</td><td>The cumulative execution and side effects of the initiating message and executing message</td></tr>
<tr><td>Dependency Set</td><td>The set of chains that originate initiating transactions where the executing transactions are valid</td></tr>
<tr><td>Log</td><td>The Ethereum consensus object created by the <code>LOG*</code> opcodes</td></tr>
<tr><td>Event</td><td>The solidity representation of a log</td></tr>
</tbody></table>
</div>
<p>A total of two transactions are required to complete a cross chain message.
The first transaction is submitted to the source chain and emits an event (initiating message) that can be
consumed on a destination chain. The second transaction is submitted to the destination chain and includes the
The first transaction is submitted to the source chain and any log that is emitted can be
used as an initiating message that can be consumed on a destination chain. The second
transaction is submitted to the destination chain and includes the
initiating message as well as the identifier that uniquely points to the initiating message.</p>
<p>The chain's fork choice rule will reorg out any blocks that contain an executing message that is not valid,
meaning that the identifier actually points to the initiating message that was passed into the remote chain.
This means that the block builder SHOULD only include an executing message if they have already checked its validity.</p>
<p>The term "block builder" is used interchangeably with the term "sequencer" for the purposes of this document but
they need not be the same entity in practice.</p>
<p>The chain's fork choice rule will reorg out any blocks that contain an executing message that is not valid.
A valid executing message means that the identifier correctly references its initiating message.
This means that the sequencer SHOULD only include an executing message if they have checked its validity.
The integrity of a message is guaranteed at the application layer without the need for any sort of confirmation
depth.</p>
<p>The proof system is able to check the validity of all executing messages.</p>
<h2 id="specifications"><a class="header" href="#specifications">Specifications</a></h2>
<ul>
<li><a href="./dependency-set.html">Dependency Set</a>: definition of chains and chain-dependencies in the Superchain.</li>
Expand Down
152 changes: 69 additions & 83 deletions interop/sequencer.html
Original file line number Diff line number Diff line change
Expand Up @@ -173,129 +173,115 @@ <h1 id="sequencer"><a class="header" href="#sequencer">Sequencer</a></h1>
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<p><strong>Table of Contents</strong></p>
<ul>
<li><a href="#sequencer-policy">Sequencer Policy</a></li>
<li><a href="#block-building">Block Building</a>
<li><a href="#overview">Overview</a></li>
<li><a href="#block-building">Block Building</a></li>
<li><a href="#sequencer-policy">Sequencer Policy</a>
<ul>
<li><a href="#static-analysis">Static analysis</a></li>
<li><a href="#dependency-confirmations">Dependency confirmations</a>
<li><a href="#safety-levels">Safety Levels</a>
<ul>
<li><a href="#pre-confirmations">Pre-confirmations</a>
<ul>
<li><a href="#streaming-pre-confirmations-shreds">Streaming pre-confirmations: "shreds"</a></li>
</ul>
</li>
<li><a href="#direct-dependency-confirmation">Direct-dependency confirmation</a></li>
<li><a href="#transitive-dependency-confirmation">Transitive-dependency confirmation</a></li>
<li><a href="#executing-message-validation">Executing Message Validation</a></li>
<li><a href="#transitive-dependencies">Transitive Dependencies</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#sponsorship">Sponsorship</a></li>
<li><a href="#shared-sequencing">Shared Sequencing</a></li>
<li><a href="#security-considerations">Security Considerations</a>
<ul>
<li><a href="#cross-chain-message-latency">Cross Chain Message Latency</a></li>
<li><a href="#depending-on-preconfirmations">Depending on Preconfirmations</a></li>
</ul>
</li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<h2 id="sequencer-policy"><a class="header" href="#sequencer-policy">Sequencer Policy</a></h2>
<p>Sequencer Policy is the process of optimistically enacting rules outside of consensus
(the state-transition function in this context), and the choices can then be asynchronously validated
by <a href="./verifier.html">verifiers</a> and <a href="./fault-proof.html">the fault-proof</a>.</p>
<p>In the context of superchain interoperability, sequencer policy is utilized to enable cross-chain message relay
without adding additional state-transition complexity or cross-chain synchronicity to the protocol.</p>
<h2 id="overview"><a class="header" href="#overview">Overview</a></h2>
<p>New validity rules are added to blocks that the sequencer must follow. If the
new rules are not followed, then the sequencer risks producing empty blocks
and reorg'ing the chain.</p>
<p>The term "block builder" is used interchangeably with the term "sequencer" for the purposes of this document but
they need not be the same entity in practice.</p>
<h2 id="block-building"><a class="header" href="#block-building">Block Building</a></h2>
<p>The goal is to present information in a way where it is as efficient as possible for the block builder to only include
executing messages that have a corresponding initiating message. It is not possible to enforce the ability to
statically analyze a transaction, so execution MAY be required to determine the information required to include
executing messages.</p>
<h3 id="static-analysis"><a class="header" href="#static-analysis">Static analysis</a></h3>
<p>Note that static analysis is never reliable because even if the top level <code>transaction.to</code>
is equal to the <code>CrossL2Inbox</code>, it is possible that there is a reentrant <code>CALL</code>. The block
builder SHOULD NOT rely on static analysis for building blocks.</p>
<h3 id="dependency-confirmations"><a class="header" href="#dependency-confirmations">Dependency confirmations</a></h3>
<p>The sequencer MAY include an executing message in a block with any desired level
of confirmation safety around the dependency of the message.</p>
<p>Confirmation levels:</p>
<ul>
<li>pre-confirmation: through direct signaling by the block builder of the initiating message.</li>
<li>direct-dependency confirmation: verify the inclusion of the initiating message, but not the transitive dependencies.</li>
<li>transitive-dependency confirmation: verify the message and all transitive dependencies
are included in canonical blocks within the specified safety-view (unsafe/safe/finalized).</li>
</ul>
<p>When operating at lower-safety confirmation levels, the block builder SHOULD re-validate included
executing messages at an increased safety level, before the block is published.</p>
<h4 id="pre-confirmations"><a class="header" href="#pre-confirmations">Pre-confirmations</a></h4>
<p>The block builder can include executing messages that have corresponding initiating messages
that only have pre-confirmation levels of security if they trust the block builder that initiates.</p>
<p>Using an allowlist and identity turns sequencing into an integrated game which increases the ability for
block builders to trust each other. Better pre-confirmation technology will help to scale the block builder
set to untrusted actors.</p>
<p>Without pre-confirmations, the block builder cannot include messages of other concurrent block building work.</p>
<p>Pre-confirmations MAY be invalidated, and assumptions around message-validity SHOULD be treated with care.</p>
<h5 id="streaming-pre-confirmations-shreds"><a class="header" href="#streaming-pre-confirmations-shreds">Streaming pre-confirmations: "shreds"</a></h5>
<p>In the context of low-latency block building, each pre-confirmation may be communicated in the form of a "shred":
the most minimal atomic state-change that can be communicated between actors in the system.</p>
<p>In the context of cross-chain block-building, shreds may be used to communicate initiated cross-chain messages,
to validate executing messages against.</p>
<p>Shreds may be streamed, and potentially signal rewinds in case of invalidated dependencies.</p>
<p>This block builder feature is in ongoing research,
and may be developed and experimented with between block builders without further protocol rules changes.</p>
<h4 id="direct-dependency-confirmation"><a class="header" href="#direct-dependency-confirmation">Direct-dependency confirmation</a></h4>
<p>By verifying the direct dependency the block-builder does not have to implement pre-confirmations,
and can rely on its direct view of the remote chain.</p>
<p>It is now required that a block builder fully executes a transaction and validates any executing messages
that it may produce before knowing that the transaction is valid. This adds a denial of service possibility
for the block builder. It is generally accepted that block builders can be sophisticated actors that can
build solutions for this sort of problem.</p>
<h2 id="sequencer-policy"><a class="header" href="#sequencer-policy">Sequencer Policy</a></h2>
<p>Sequencer policy represents the set of ways that a sequencer may act that are not constrained by consensus.
The ordering of transactions in a block is considered policy, consensus dictates that all of the transactions
in a block are valid.</p>
<p>OP Stack interop leverages sequencer policy to reduce synchrony assumptions between chains.
If the sequencer's view of a remote chain lags from the tip, it will not impact the overall liveness of
the network, it will only impact the liveness of inbound cross chain messages from that remote chain.
If there was a strict synchrony assumption, it could result in liveness or safety failures when any sequencer
in the cluster falls behind the tip of any remote chain.</p>
<h3 id="safety-levels"><a class="header" href="#safety-levels">Safety Levels</a></h3>
<p>The sequencer MAY include an executing message with any level of confirmation safety.
Including cross chain messages based on preconfirmation levels of security results
in lower latency messaging at a higher risk or an invalid block being produced.</p>
<p>The sequencer MAY require different levels of security depending on the source chain.
If the block containing the initiating message is considered safe, no additional trust
assumptions are assumed. The only time that additional trust assumptions are added is
when an initiating message from an unsafe block is consumed.</p>
<h4 id="executing-message-validation"><a class="header" href="#executing-message-validation">Executing Message Validation</a></h4>
<p>The block builder SHOULD validate executing messages directly before including the transaction
that produced the executing message in a block. Given the async nature of many independent chains
operating in parallel, it is possible that the block builder does not have the most up to date
view of all remote chains at any given moment.</p>
<p>The block builder MAY require cryptographic proof of the existence of the log
that the identifier points to, if it trusts the remote canonical chain but not its RPC server.</p>
<p>The block builder MAY also trust a remote RPC and use the following algorithm
to verify the existence of the log.</p>
<p>The following pseudocode represents how to check existence of a log based on an <code>Identifier</code>.
If the value <code>True</code> is returned, then it is safe to include the transaction.</p>
<p>The block builder MAY also trust a remote RPC and use the following algorithm to verify the
existence of the log. This algorithm does not check for a particular finality level of the
block that includes the initiating message.</p>
<pre><code class="language-python">success, receipt = evm.apply_transaction(tx)

# no logs are produced for reverting transactions
if not success:
return True

# iterate over all of the logs
for log in receipt.logs:
if is_executing_message(log):
id = abi.decode(log.data)
messageHash = log.topics[1]
message_hash = log.topics[1]

# assumes there is a client for each chain in the dependency set
# maintain a RPC client for each remote node by chainid
eth = clients[id.chainid]

# cannot verify messages without a client, do not include it
if eth is None:
return False

logs = eth.getLogs(id.origin, from=id.blocknumber, to=id.blocknumber)
log = filter(lambda x: x.index == id.logIndex &amp;&amp; x.address == id.origin)
if len(log) == 0:
# use the identifier to fetch logs
logs = eth.get_logs(id.origin, from=id.block_number, to=id.block_number)
filtered = filter(lambda x: x.index == id.log_index &amp;&amp; x.address == id.origin)
# log does not exist, do not include it
if len(filtered) != 1:
return False

if messageHash != hash(encode(log[0])):
# ensure the contents of the log are correct
log = encode(filtered[0])
if message_hash != keccack256(log):
return False

block = eth.getBlockByNumber(id.blocknumber)
block = eth.get_block_by_number(id.blocknumber)

# ensure that the timestamp is correct
if id.timestamp != block.timestamp:
return False

return True
</code></pre>
<h4 id="transitive-dependency-confirmation"><a class="header" href="#transitive-dependency-confirmation">Transitive-dependency confirmation</a></h4>
<p>When operating pessimistically, the direct-dependency validation may be applied recursively,
to harden against unstable message guarantees at the cost of increased cross-chain latency.</p>
<p>The transitive dependencies may also be enforced with <code>safe</code> or even <code>finalized</code> safety-views
over the blocks of the chains in the dependency set, to further ensure increased cross-chain safety.</p>
<h2 id="sponsorship"><a class="header" href="#sponsorship">Sponsorship</a></h2>
<p>If a user does not have ether to pay for the gas of an executing message, application layer sponsorship
solutions can be created. It is possible to create an MEV incentive by paying <code>tx.origin</code> in the executing
message. This can be done by wrapping the <code>L2ToL2CrossDomainMessenger</code> with a pair of relaying contracts.</p>
<h4 id="transitive-dependencies"><a class="header" href="#transitive-dependencies">Transitive Dependencies</a></h4>
<p>The safety of a block is inherently tied to the safety of the blocks that include initiating messages
consumed. This applies recursively, so a block builder that wants to only include safe cross chain
messages will need to recursively check that all dependencies are safe.</p>
<h2 id="shared-sequencing"><a class="header" href="#shared-sequencing">Shared Sequencing</a></h2>
<p>A shared sequencer can be built if the block builder is able to build the next canonical block
for multiple chains. This can enable synchronous composability where transactions are able
to execute across multiple chains at the same timestamp.</p>
<h2 id="security-considerations"><a class="header" href="#security-considerations">Security Considerations</a></h2>
<h3 id="cross-chain-message-latency"><a class="header" href="#cross-chain-message-latency">Cross Chain Message Latency</a></h3>
<p>The latency at which a cross chain message is relayed from the moment at which it was initiated is bottlenecked by
the security of the preconfirmations. An initiating transaction and a executing transaction MAY have the same timestamp,
meaning that a secure preconfirmation scheme enables atomic cross chain composability. Any sort of equivocation on
behalf of the sequencer will result in the production of invalid blocks.</p>
<h3 id="depending-on-preconfirmations"><a class="header" href="#depending-on-preconfirmations">Depending on Preconfirmations</a></h3>
<p>If a local sequencer is accepting inbound cross chain transactions where the initiating message only has preconfirmation
levels of security, this means that the remote sequencer can trigger a reorg on the local chain.</p>

</main>

Expand Down
Loading

0 comments on commit 465c399

Please sign in to comment.