Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.

refactor: new messengers#421

Merged
mslipper merged 37 commits intomainfrom
sc/base-messenger
May 12, 2022
Merged

refactor: new messengers#421
mslipper merged 37 commits intomainfrom
sc/base-messenger

Conversation

@smartcontracts
Copy link
Contributor

@smartcontracts smartcontracts commented May 6, 2022

Implements the new messenger flow. This ensures that the messengers and bridges work in a backwards compatible way. The previous iteration of the messengers didn't take into account deposits that were in flight during the upgrade. This pull request has some major architectural changes so that the bridges now go through the messengers again. This allows for replayability in the bridges as well as gives the bridges replay protection.

A main feature of this PR is that the messenger and bridges now extend a base messenger or bridge contract to make the functionality basically the same on both L1 and L2. The previous iteration of the contracts made a distinction between the L1 and L2 sides of things. The previous APIs are persisted, but now there is a universal API that can be used on the bridges/messengers no matter which domain you are in.

Hardhat deploy scripts are added to the ops setup.

The bindings for the l2os and opnode are regenerated.

Deprecates:

Unblocks:

Closes:

@codecov-commenter
Copy link

codecov-commenter commented May 6, 2022

Codecov Report

Merging #421 (5e37e47) into main (3a1f6ff) will increase coverage by 1.42%.
The diff coverage is 7.14%.

@@            Coverage Diff             @@
##             main     #421      +/-   ##
==========================================
+ Coverage   51.68%   53.10%   +1.42%     
==========================================
  Files          57       62       +5     
  Lines        5764     6498     +734     
==========================================
+ Hits         2979     3451     +472     
- Misses       2415     2608     +193     
- Partials      370      439      +69     
Impacted Files Coverage Δ
opnode/contracts/deposit/deposit_feed_raw.go 5.21% <0.00%> (ø)
l2os/bindings/l2oo/l2_output_oracle.go 8.60% <5.71%> (-0.29%) ⬇️
l2os/drivers/l2output/driver.go 67.24% <100.00%> (+0.18%) ⬆️
opnode/rollup/driver/state.go 71.23% <0.00%> (-5.36%) ⬇️
l2os/service.go 90.78% <0.00%> (-3.95%) ⬇️
opnode/rollup/driver/step.go 61.37% <0.00%> (-3.13%) ⬇️
opnode/node/node.go 60.00% <0.00%> (-1.71%) ⬇️
opnode/node/api.go 58.64% <0.00%> (-0.76%) ⬇️
opnode/p2p/config.go 7.83% <0.00%> (-0.18%) ⬇️
opnode/service.go 0.00% <0.00%> (ø)
... and 13 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3a1f6ff...5e37e47. Read the comment docs.

@smartcontracts smartcontracts force-pushed the sc/base-messenger branch 2 times, most recently from 7dcef83 to 73eef4e Compare May 9, 2022 21:31
@tynes tynes force-pushed the sc/base-messenger branch from 810db4d to 179f2f5 Compare May 11, 2022 03:13
tynes and others added 25 commits May 10, 2022 20:15
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Implement the `L1CrossDomainMessenger` and
`L2CrossDomainMessenger` based on the base
`CrossDomainMessenger`. This makes the interfaces
the same on both sides.

Co-authored-by: smartcontracts <kelvin@optimism.io>
Also implement the `L1StandardBridge` and
`L2StandardBridge` based off of the base
`StandardBridge`

Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
tynes and others added 2 commits May 10, 2022 20:18
Co-authored-by: smartcontracts <kelvin@optimism.io>
Co-authored-by: smartcontracts <kelvin@optimism.io>
@tynes tynes force-pushed the sc/base-messenger branch from 179f2f5 to 741cccc Compare May 11, 2022 03:18
@tynes tynes changed the title Sc/base messenger refactor: new messengers May 11, 2022
@tynes tynes marked this pull request as ready for review May 11, 2022 03:25
@tynes tynes self-requested a review May 11, 2022 04:04
@tynes tynes force-pushed the sc/base-messenger branch from 2242fdb to 43f201d Compare May 11, 2022 04:06
@tynes tynes force-pushed the sc/base-messenger branch from 43f201d to 03c8c86 Compare May 11, 2022 04:19
This was referenced May 11, 2022
Copy link
Contributor

@norswap norswap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I'm missing some kind of document (or even better, diagram) that tie all the components together. In particular, illustrating the flow of L1->L2 bridging and L2->L1 bridging through the components & functions would be really a great help in wrapping your head around the logic.

  • We should consolidate the "new API" and the "legacy API" (separately!) and provide a mapping / migration path between both.

  • It seems to me (unless I've missed something) that the relayMessage call is never used. It's not necessary when doing L1->L2 (because of deposit inclusion), but it's not used either when doing L2->L1 (instead the logic lives entirely within OptimismPortal).

    • Suggest removing relayMessage from CrossDomainMessenger.
    • Preserve it in L1CrossDomainMessenger (for backward compatibility) but call into OptimismPortal instead.


emit ETHBridgeFinalized(_from, _to, _amount, _data);
(bool success, ) = _to.call{ value: _amount }(new bytes(0));
require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That require string needs to be updated.

*/
function _isSystemMessageSender() internal view override returns (bool) {
return msg.sender == address(portal) && portal.l2Sender() == otherMessenger;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only used in CrossDomainMessenger#relayMessage, which is never called by the OptimismPortal??

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the comment "Ensure that the L1CrossDomainMessenger can only be called by the OptimismPortal" seems false?

The privilege of the messenger is that it can relay messages that have not not been marked as received (but again, the portal never relays currently).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OptimismPortal does make calls on L1 for a withdrawal, the flow through the L2 messenger would be encoding a call to the L1 messenger relayMessage

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, I get it now 👍

) internal {
emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data);
_initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _data);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason why the two functions above are not inlined within the external functions that call them?

Copy link
Contributor

@trianglesphere trianglesphere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just flagged everywhere I was a gasLimit that was 256 bits, but didn't do as much in terms of determining if it was valid or not.

I also flagged where I had the concern around msg.value and _value on L2. I don't think this is fully relevant yet, but will be in the future.

Otherwise, this looks good to me.

event l2OutputAppended(
bytes32 indexed _l2Output,
uint256 indexed _l1Timestamp,
uint256 indexed _l2timestamp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also use block number here. This is a larger refactor though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need consensus before making that large of a change, should put together a doc @trianglesphere and schedule discussion for next office hours @K-Ho

address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new code? This is the gas limit that should be limited to 64 bites

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is new code, good call

@@ -62,21 +72,20 @@ contract Withdrawer {
function initiateWithdrawal(
address _target,
uint256 _gasLimit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too large gas limit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is safe, downstream there is a require(gasleft() > _gasLimit + buffer)

I lean towards not changing any of the gas limits here as the only one that needs to be a uint64 is the one used for deposits. Unless there is strong preference for it to be a uint64 everywhere just for sanity reasons, which I would understand too

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it could be fine. I just flagged each instance without too much thought. It's just that any gas limit that serializes to go / actual execution needs to fit in 64 bits (and probably way fewer) otherwise the deposit gets stuck

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts @smartcontracts?

bool _isCreate,
uint256 _mint,
uint256 _value,
uint256 _gas,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too large? Maybe not actually?

address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

address _sender,
address _target,
uint256 _value,
uint256 _gasLimit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

256 bit gas

address sender,
bytes message,
uint256 messageNonce,
uint256 gasLimit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

address indexed sender,
address indexed target,
uint256 value,
uint256 gasLimit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


if (_isSystemMessageSender()) {
// Should never happen.
require(msg.value == _value, "Mismatched message value.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have concerns about this when we are doing stuff on L2 with this. Specifically the L1 value is set to the L2 mint, and then a user specified (to the deposit tx at least) amount is set to the value field. If these fields do not line up exactly, we have have stuck messages. In particular, we expect one version of the Optimism Portal Deposit function to take eth to pay for L2 gas which would change the amount of value emitted.

@mslipper mslipper merged commit 55db896 into main May 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants