fix: Outbox replay state management, saves ~15k gas per msg #623
fix: Outbox replay state management, saves ~15k gas per msg #623PlasmaPower merged 11 commits intoOffchainLabs:masterfrom shotaronowhere:master
Conversation
contracts/src/bridge/Outbox.sol
Outdated
| if (spent[index]) revert AlreadySpent(index); | ||
| spent[index] = true; | ||
| uint256 spentIndex = index / 256; | ||
| uint256 bitOffset = index - spentIndex * 256; |
There was a problem hiding this comment.
Let's use 255 instead of 256 here.. this will leave the most significant bit reserved.
We might do something clever with this reserved bit later, to avoid 1/256 users paying more gas for the release.
There was a problem hiding this comment.
Sure, just made that change. : )
|
It goes without saying, but message relaying is most efficient when batched into groups of 255 (or 256 including the MSB in the replay bitmap). Specifically batching multiple messages index_initial to index_final is most efficient when since SSTORE only costs 100 gas since the Replay "Spent" State Management Gas Summary
Moreover, creating an auxiliary function specifically for executing batch transactions which checks the spent bitmap only once, and sets it only once, before sequentially executing each message (check effects pattern), can bring this down the state overhead to about 20k (no 100 gas SSTORE calls). If this doesn't sound like too much complexity (in smart contract dev, KISS simplicity is often the best, right?) I could make an implementation. This might be overkill, but in the future, I expect state cost on L1 to be very expensive until sharding and data availability arrives (2030? who knows). EIP 5022 doesn't have much discussion, but I completely support it, SSTORE should actually be more expensive. With multidimensional gas pricing storage will probably be at a premium. |
|
Crazy savings. But, you missed on the SLOADs that are also storage overhead. So actually storage overhead costs are:
Bitmap + batch is a 76x performance boost to previous cost, and 17x to bitmap + different triggers
It's true that it would be just 22k in state overhead, due to triggering SSTORE once, but it may be the case that the extra non-state computation needed to make it work are over the 51k gas that you would be saving. Also, take into account that only applies to the most optimistic scenario. In more realistic scenarios, this process would occur multiple times, and then, the simple bitmap solution may be more efficient. Why it's realistic to assume multiple calls:
|
Since there's the possibility of MEV, plus the fact that the first party that "opens" this bitmap is still getting something out of it (getting to be first, value of relaying the msg is probably higher than the cost), and the first solution taking this cost into account for every message, I'm not sure how good reserving this bit is. |
|
We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign the linked documents below to get yourself added. https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=b15c81cc-b5ea-42a6-9107-3992526f2898&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2 |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
Codecov Report
@@ Coverage Diff @@
## master #623 +/- ##
==========================================
- Coverage 52.02% 47.50% -4.52%
==========================================
Files 225 214 -11
Lines 26421 22394 -4027
Branches 496 496
==========================================
- Hits 13745 10638 -3107
+ Misses 11285 10366 -919
+ Partials 1391 1390 -1 |
|
@greenlucid |
|
@cla-bot check |
|
We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign the linked documents below to get yourself added. https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=b15c81cc-b5ea-42a6-9107-3992526f2898&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2 |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign the linked documents below to get yourself added. https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=b15c81cc-b5ea-42a6-9107-3992526f2898&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2 |
|
Hey @shotaronowhere, appreciate the contributions and we'd love to get these merged. I saw you signed the arbitrum CLA, but we actually have a new one for this repo. Would appreciate if you could sign the CLA for this repo when you get a chance 😄 |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
Should save like . . . 6 gas per message : )
Head branch was pushed to by a user without write access
|
By the way, as I take it, the plan is that Offchain Labs can subsidize opening the slots by setting the MSB of a large set of replay bitmaps in advance at a time when gas is extremely cheap. You can then socialize the cost amongst all the message senders, hope fully without any rent seeking, but hey, that's a business model, need to keep the lights on some how. The coordinator fee. |
|
We don't have a precise plan for how we're going to set the MSBs in advance (and we may not launch with it). It's a low overhead change though, so our thinking is that it's better to keep our options open by reserving it. |
I implemented a simple packed bitmap to prevent message replay.
The original implementation uses a mapping to a boolean which wastes 255 bits of state per message. By packing the spent boolean into a bitmap, only one zero -> nonzero SSTORE call is required ~20k gas.
Since the packed bitmap is set to non-zero for the first message, all 255 subsequent messages only cost ~5k gast since non-zero -> non-zero SSTORE calls cost ~5k gas.
Hence a ~15k gas savings per message.