ethereum-optimism / specs

OP Stack Specifications
https://specs.optimism.io
Creative Commons Zero v1.0 Universal
100 stars 89 forks source link

L2 Messaging and Rollbacks #460

Open tynes opened 14 hours ago

tynes commented 14 hours ago

When bridging between two chains, it is possible to accidentally lock your funds in a way that prevents you from being able to unlock them. There has been this general idea of "rolling back" the cross chain message on the source chain if its known that it reverts on the destination chain. The design for this was removed in https://github.com/ethereum-optimism/specs/pull/459 due to iteration on the design.

Due to unreliable gas estimation problems with catching the call failure and not bubbling it up to the top level (fixed in https://github.com/ethereum-optimism/optimism/pull/12526) there is now no way to know that a cross chain message was unsuccessful directly in the messenger itself. This means that the new entrypoint design (https://github.com/ethereum-optimism/design-docs/pull/163) would need to track this, but it would result in the same gas estimation devex issues. It is possible to solve the problem of rolling back an always reverting cross chain message with this design but the devex isn't great, an estimation address would need to be used to reliable gas estimation.

This solution does not cover the stuck funds when they are sent to a chain that is not in the dependency set. There will be no way to relay the funds back with the rollback mechanism. We need to be sure that we are all aligned on the user stories that we are trying to solve. With SuperchainERC20 tokens, I think the larger problem to solve is preventing sending to a chain not in the dependency set, this is currently considered the same thing as sending to an EOA with no known private key. There is no case in which a standard SuperchainERC20 transfer will fail partway and the user will need to roll it back, we should design it such that it always succeeds.

Given the enforcement of a fully connected graph in interop (https://github.com/ethereum-optimism/design-docs/pull/84), this means that one chain's dependency set represents the whole dependency set. To solve the problem of having funds be stuck by sending to a chain outside of the dependency set, we can add one new line of code to the L2ToL2CrossDomainMessenger and solve this problem.

diff --git a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol
index 6b1d7327d..c46f4b9b4 100644
--- a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol
+++ b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol
@@ -130,6 +130,7 @@ contract L2ToL2CrossDomainMessenger is ISemver, TransientReentrancyAware {
         if (_destination == block.chainid) revert MessageDestinationSameChain();
         if (_target == Predeploys.CROSS_L2_INBOX) revert MessageTargetCrossL2Inbox();
         if (_target == Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER) revert MessageTargetL2ToL2CrossDomainMessenger();
+        if (!IDependencySet(Predeploys.L1_BLOCK_ATTRIBUTES).isInDependencySet(_destination)) revert InvalidChainId();

         uint256 nonce = messageNonce();
         emit SentMessage(_destination, _target, nonce, msg.sender, _message);

With this change, the cross chain message reverts on the source chain when trying to send to a destination chain that isn't in the dependency set.

tynes commented 13 hours ago

Expired Message User Stories

Generic Message Passing

Asset Bridging

I don't buy that the "took too long to relay message" user story is that important, I think that the "user sends asset to incorrect destination chain" story is much more important to solve. This user story is solved with the solution described in this issue (https://github.com/ethereum-optimism/specs/issues/460). The one thing that it does not solve for is the remote sequencer is censoring, which we are launching a governance based interop solution and censorship is attributable and we have a path towards solving this as described in https://github.com/ethereum-optimism/optimism/issues/10870