Skip to content

Commit

Permalink
feat!: Mark transactions as reverted on L1 (#5226)
Browse files Browse the repository at this point in the history
# Introduction

Presently, if a transaction is reverted, the base rollup does not mark it as reverted: it merely has its revertible side effects dropped. This issue will update the base rollup to mark reverted transactions.

# Solution Design

## New `RevertCode` in `TxEffect`

Create a new class in `circuits.js` to hold a `RevertCode`. It will be a safe wrapper around an `Fr` that will be used to store the revert code of a transaction.

`0` will indicate success, and any other value will indicate failure. Presently, only `1` is used to indicate general failure, but we'll leave the door open for future expansion.

`TxEffect` will be updated to include a `RevertCode`.

### Ethereum `status`

Ethereum stores their `status` in a `uint64`, but only currently use `0` to indicate failure and `1` for success. [More info](ethereum/EIPs#98) (Thanks @spalladino !)

### Size considerations

We'll eventually want to add `gasUsed` and `gasPrice` to `TxEffect`. Using a full field is wasteful, but using a smaller size will make the encoding and hashing more complex (see below). We'll implement with a full field and have a stacked PR to optimize the size.

## Kernel Constraints

The `RevertCode` will become part of the content commitment for a transaction.

The content commitment is computed by the base rollup in `compute_tx_effects_hash`, which:

- accepts a `CombinedAccumulatedData`
- operates over `Field`s

We will therefore update the `CombinedAccumulatedData` to include the `RevertCode`.

A fallout from that is we will move the current `reverted` flag from `PublicKernelCircuitPublicInputs` to be part of:

- `PrivateAccumulatedNonRevertibleData`
- `PublicAccumulatedNonRevertibleData`

This is because we:

1. build up a `CombinedAccumulatedData` during private execution
2. split them into `PrivateAccumulatedNonRevertibleData` and `PrivateAccumulatedRevertibleData` in the private kernel tail
3. convert those `PrivateAccumulated...` into `PublicAccumulated...` during public kernel execution as needed
4. recombine them back into `CombinedAccumulatedData` before feeding back into base rollup

## Encoding

The `RevertCode` will come first in the encoded `TxEffect`.

That is we will publish:

```
|| 32 bytes for RevertCode || ... Existing PublishedTxEffect ... ||
```

## L1 Tx Decoder

We'll need to update the availability oracle to compensate for the new flag.

## `TxReceipt`

We'll add a new `TxStatus` that is `REVERTED = 'reverted'`.

We need to update `getSettledTxReceipt` to inspect the `TxEffect` and set the `status` accordingly.

# Test Plan

## Unit Tests

- Serde of `TxEffect` in TS and solidity.

## E2E Tests

- Add checks for tx statuses of `REVERTED` in the `e2e_fees`, `e2e_deploy_contract`, and `dapp_testing`.

# Documentation Plan

Will start a page in the "Data publication and availability" section of the yellow paper describing the format of the block submitted.

# Especially Relevant Parties

- @PhilWindle
- @benesjan
- @alexghr
- @LeilaWang
- @LHerskind

# Plan Approvals

**_👋 Please add a +1 or comment to express your approval or disapproval of the plan above._**
  • Loading branch information
just-mitch authored Mar 20, 2024
1 parent 36e0f59 commit 40ecc02
Show file tree
Hide file tree
Showing 60 changed files with 876 additions and 549 deletions.
6 changes: 1 addition & 5 deletions docs/docs/developers/tutorials/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,14 @@ Keep in mind that public function calls behave as in EVM blockchains, in that th

#### A public call fails on the sequencer

We can ignore a local simulation error for a public function via the `skipPublicSimulation`. This will submit a failing call to the sequencer, who will include the transaction, but without any side effects from our application logic.
We can ignore a local simulation error for a public function via the `skipPublicSimulation`. This will submit a failing call to the sequencer, who will include the transaction, but without any side effects from our application logic. Requesting the receipt for the transaction will also show it has a reverted status.

#include_code pub-reverted /yarn-project/end-to-end/src/guides/dapp_testing.test.ts typescript

```
WARN Error processing tx 06dc87c4d64462916ea58426ffcfaf20017880b353c9ec3e0f0ee5fab3ea923f: Assertion failed: Balance too low.
```

:::info
Presently, the transaction is included, but no additional information is included in the block to mark it as reverted. This will change in the near future.
:::

### State

We can check private or public state directly rather than going through view-only methods, as we did in the initial example by calling `token.methods.balance().view()`. Bear in mind that directly accessing contract storage will break any kind of encapsulation.
Expand Down
113 changes: 60 additions & 53 deletions l1-contracts/slither_output.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Summary
- [pess-unprotected-setter](#pess-unprotected-setter) (1 results) (High)
- [uninitialized-local](#uninitialized-local) (2 results) (Medium)
- [unused-return](#unused-return) (1 results) (Medium)
- [pess-dubious-typecast](#pess-dubious-typecast) (6 results) (Medium)
- [pess-dubious-typecast](#pess-dubious-typecast) (7 results) (Medium)
- [missing-zero-check](#missing-zero-check) (2 results) (Low)
- [reentrancy-events](#reentrancy-events) (2 results) (Low)
- [timestamp](#timestamp) (1 results) (Low)
Expand Down Expand Up @@ -32,9 +32,9 @@ src/core/libraries/HeaderLib.sol#L148


- [ ] ID-2
[TxsDecoder.decode(bytes).vars](src/core/libraries/decoders/TxsDecoder.sol#L79) is a local variable never initialized
[TxsDecoder.decode(bytes).vars](src/core/libraries/decoders/TxsDecoder.sol#L81) is a local variable never initialized

src/core/libraries/decoders/TxsDecoder.sol#L79
src/core/libraries/decoders/TxsDecoder.sol#L81


## unused-return
Expand All @@ -50,34 +50,41 @@ src/core/Rollup.sol#L57-L96
Impact: Medium
Confidence: High
- [ ] ID-4
Dubious typecast in [TxsDecoder.read1(bytes,uint256)](src/core/libraries/decoders/TxsDecoder.sol#L314-L316):
bytes => bytes1 casting occurs in [uint256(uint8(bytes1(slice(_data,_offset,1))))](src/core/libraries/decoders/TxsDecoder.sol#L315)
Dubious typecast in [TxsDecoder.decode(bytes)](src/core/libraries/decoders/TxsDecoder.sol#L78-L192):
bytes => bytes32 casting occurs in [vars.baseLeaf = bytes.concat(bytes32(slice(_body,offsets.reverted,0x20)),bytes.concat(sliceAndPad(_body,offsets.noteHash,counts.noteHash * 0x20,Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP),sliceAndPad(_body,offsets.nullifier,counts.nullifier * 0x20,Constants.NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP),sliceAndPad(_body,offsets.l2ToL1Msgs,counts.l2ToL1Msgs * 0x20,Constants.L2_TO_L1_MSGS_NUM_BYTES_PER_BASE_ROLLUP),sliceAndPad(_body,offsets.publicData,counts.publicData * 0x40,Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP)),bytes.concat(vars.encryptedLogsHash,vars.unencryptedLogsHash))](src/core/libraries/decoders/TxsDecoder.sol#L156-L185)

src/core/libraries/decoders/TxsDecoder.sol#L314-L316
src/core/libraries/decoders/TxsDecoder.sol#L78-L192


- [ ] ID-5
Dubious typecast in [Outbox.sendL1Messages(bytes32[])](src/core/messagebridge/Outbox.sol#L38-L46):
uint256 => uint32 casting occurs in [version = uint32(REGISTRY.getVersionFor(msg.sender))](src/core/messagebridge/Outbox.sol#L40)
Dubious typecast in [MessagesDecoder.read4(bytes,uint256)](src/core/libraries/decoders/MessagesDecoder.sol#L164-L166):
bytes => bytes4 casting occurs in [uint256(uint32(bytes4(_data)))](src/core/libraries/decoders/MessagesDecoder.sol#L165)

src/core/messagebridge/Outbox.sol#L38-L46
src/core/libraries/decoders/MessagesDecoder.sol#L164-L166


- [ ] ID-6
Dubious typecast in [TxsDecoder.read4(bytes,uint256)](src/core/libraries/decoders/TxsDecoder.sol#L324-L326):
bytes => bytes4 casting occurs in [uint256(uint32(bytes4(slice(_data,_offset,4))))](src/core/libraries/decoders/TxsDecoder.sol#L325)
Dubious typecast in [Outbox.sendL1Messages(bytes32[])](src/core/messagebridge/Outbox.sol#L38-L46):
uint256 => uint32 casting occurs in [version = uint32(REGISTRY.getVersionFor(msg.sender))](src/core/messagebridge/Outbox.sol#L40)

src/core/libraries/decoders/TxsDecoder.sol#L324-L326
src/core/messagebridge/Outbox.sol#L38-L46


- [ ] ID-7
Dubious typecast in [MessagesDecoder.read4(bytes,uint256)](src/core/libraries/decoders/MessagesDecoder.sol#L160-L162):
bytes => bytes4 casting occurs in [uint256(uint32(bytes4(_data)))](src/core/libraries/decoders/MessagesDecoder.sol#L161)
Dubious typecast in [TxsDecoder.read1(bytes,uint256)](src/core/libraries/decoders/TxsDecoder.sol#L322-L324):
bytes => bytes1 casting occurs in [uint256(uint8(bytes1(slice(_data,_offset,1))))](src/core/libraries/decoders/TxsDecoder.sol#L323)

src/core/libraries/decoders/MessagesDecoder.sol#L160-L162
src/core/libraries/decoders/TxsDecoder.sol#L322-L324


- [ ] ID-8
Dubious typecast in [TxsDecoder.read4(bytes,uint256)](src/core/libraries/decoders/TxsDecoder.sol#L332-L334):
bytes => bytes4 casting occurs in [uint256(uint32(bytes4(slice(_data,_offset,4))))](src/core/libraries/decoders/TxsDecoder.sol#L333)

src/core/libraries/decoders/TxsDecoder.sol#L332-L334


- [ ] ID-9
Dubious typecast in [HeaderLib.decode(bytes)](src/core/libraries/HeaderLib.sol#L143-L184):
bytes => bytes32 casting occurs in [header.lastArchive = AppendOnlyTreeSnapshot(bytes32(_header),uint32(bytes4(_header)))](src/core/libraries/HeaderLib.sol#L151-L153)
bytes => bytes4 casting occurs in [header.lastArchive = AppendOnlyTreeSnapshot(bytes32(_header),uint32(bytes4(_header)))](src/core/libraries/HeaderLib.sol#L151-L153)
Expand All @@ -103,24 +110,24 @@ Dubious typecast in [HeaderLib.decode(bytes)](src/core/libraries/HeaderLib.sol#L
src/core/libraries/HeaderLib.sol#L143-L184


- [ ] ID-9
Dubious typecast in [MessagesDecoder.read1(bytes,uint256)](src/core/libraries/decoders/MessagesDecoder.sol#L150-L152):
bytes => bytes1 casting occurs in [uint256(uint8(bytes1(_data)))](src/core/libraries/decoders/MessagesDecoder.sol#L151)
- [ ] ID-10
Dubious typecast in [MessagesDecoder.read1(bytes,uint256)](src/core/libraries/decoders/MessagesDecoder.sol#L154-L156):
bytes => bytes1 casting occurs in [uint256(uint8(bytes1(_data)))](src/core/libraries/decoders/MessagesDecoder.sol#L155)

src/core/libraries/decoders/MessagesDecoder.sol#L150-L152
src/core/libraries/decoders/MessagesDecoder.sol#L154-L156


## missing-zero-check
Impact: Low
Confidence: Medium
- [ ] ID-10
- [ ] ID-11
[Inbox.constructor(address,uint256)._rollup](src/core/messagebridge/Inbox.sol#L40) lacks a zero-check on :
- [ROLLUP = _rollup](src/core/messagebridge/Inbox.sol#L41)

src/core/messagebridge/Inbox.sol#L40


- [ ] ID-11
- [ ] ID-12
[NewOutbox.constructor(address)._rollup](src/core/messagebridge/NewOutbox.sol#L31) lacks a zero-check on :
- [ROLLUP_CONTRACT = _rollup](src/core/messagebridge/NewOutbox.sol#L32)

Expand All @@ -130,7 +137,7 @@ src/core/messagebridge/NewOutbox.sol#L31
## reentrancy-events
Impact: Low
Confidence: Medium
- [ ] ID-12
- [ ] ID-13
Reentrancy in [Inbox.sendL2Message(DataStructures.L2Actor,bytes32,bytes32)](src/core/messagebridge/Inbox.sol#L61-L95):
External calls:
- [index = currentTree.insertLeaf(leaf)](src/core/messagebridge/Inbox.sol#L91)
Expand All @@ -140,7 +147,7 @@ Reentrancy in [Inbox.sendL2Message(DataStructures.L2Actor,bytes32,bytes32)](src/
src/core/messagebridge/Inbox.sol#L61-L95


- [ ] ID-13
- [ ] ID-14
Reentrancy in [Rollup.process(bytes,bytes32,bytes,bytes)](src/core/Rollup.sol#L57-L96):
External calls:
- [inHash = INBOX.consume()](src/core/Rollup.sol#L87)
Expand All @@ -154,7 +161,7 @@ src/core/Rollup.sol#L57-L96
## timestamp
Impact: Low
Confidence: Medium
- [ ] ID-14
- [ ] ID-15
[HeaderLib.validate(HeaderLib.Header,uint256,uint256,bytes32)](src/core/libraries/HeaderLib.sol#L106-L136) uses timestamp for comparisons
Dangerous comparisons:
- [_header.globalVariables.timestamp > block.timestamp](src/core/libraries/HeaderLib.sol#L120)
Expand All @@ -165,35 +172,35 @@ src/core/libraries/HeaderLib.sol#L106-L136
## pess-public-vs-external
Impact: Low
Confidence: Medium
- [ ] ID-15
- [ ] ID-16
The following public functions could be turned into external in [FrontierMerkle](src/core/messagebridge/frontier_tree/Frontier.sol#L7-L93) contract:
[FrontierMerkle.constructor(uint256)](src/core/messagebridge/frontier_tree/Frontier.sol#L19-L27)

src/core/messagebridge/frontier_tree/Frontier.sol#L7-L93


- [ ] ID-16
- [ ] ID-17
The following public functions could be turned into external in [Registry](src/core/messagebridge/Registry.sol#L22-L129) contract:
[Registry.constructor()](src/core/messagebridge/Registry.sol#L29-L33)

src/core/messagebridge/Registry.sol#L22-L129


- [ ] ID-17
- [ ] ID-18
The following public functions could be turned into external in [Inbox](src/core/messagebridge/Inbox.sol#L24-L124) contract:
[Inbox.constructor(address,uint256)](src/core/messagebridge/Inbox.sol#L40-L51)

src/core/messagebridge/Inbox.sol#L24-L124


- [ ] ID-18
- [ ] ID-19
The following public functions could be turned into external in [Rollup](src/core/Rollup.sol#L29-L105) contract:
[Rollup.constructor(IRegistry,IAvailabilityOracle)](src/core/Rollup.sol#L42-L48)

src/core/Rollup.sol#L29-L105


- [ ] ID-19
- [ ] ID-20
The following public functions could be turned into external in [Outbox](src/core/messagebridge/Outbox.sol#L21-L148) contract:
[Outbox.constructor(address)](src/core/messagebridge/Outbox.sol#L29-L31)
[Outbox.get(bytes32)](src/core/messagebridge/Outbox.sol#L77-L84)
Expand All @@ -202,7 +209,7 @@ The following public functions could be turned into external in [Outbox](src/cor
src/core/messagebridge/Outbox.sol#L21-L148


- [ ] ID-20
- [ ] ID-21
The following public functions could be turned into external in [NewOutbox](src/core/messagebridge/NewOutbox.sol#L18-L132) contract:
[NewOutbox.constructor(address)](src/core/messagebridge/NewOutbox.sol#L31-L33)

Expand All @@ -212,37 +219,37 @@ src/core/messagebridge/NewOutbox.sol#L18-L132
## assembly
Impact: Informational
Confidence: High
- [ ] ID-21
[MessagesDecoder.decode(bytes)](src/core/libraries/decoders/MessagesDecoder.sol#L60-L142) uses assembly
- [INLINE ASM](src/core/libraries/decoders/MessagesDecoder.sol#L79-L81)
- [INLINE ASM](src/core/libraries/decoders/MessagesDecoder.sol#L112-L118)
- [ ] ID-22
[MessagesDecoder.decode(bytes)](src/core/libraries/decoders/MessagesDecoder.sol#L61-L146) uses assembly
- [INLINE ASM](src/core/libraries/decoders/MessagesDecoder.sol#L80-L82)
- [INLINE ASM](src/core/libraries/decoders/MessagesDecoder.sol#L116-L122)

src/core/libraries/decoders/MessagesDecoder.sol#L60-L142
src/core/libraries/decoders/MessagesDecoder.sol#L61-L146


- [ ] ID-22
[TxsDecoder.computeRoot(bytes32[])](src/core/libraries/decoders/TxsDecoder.sol#L256-L275) uses assembly
- [INLINE ASM](src/core/libraries/decoders/TxsDecoder.sol#L263-L265)
- [ ] ID-23
[TxsDecoder.computeRoot(bytes32[])](src/core/libraries/decoders/TxsDecoder.sol#L264-L283) uses assembly
- [INLINE ASM](src/core/libraries/decoders/TxsDecoder.sol#L271-L273)

src/core/libraries/decoders/TxsDecoder.sol#L256-L275
src/core/libraries/decoders/TxsDecoder.sol#L264-L283


## dead-code
Impact: Informational
Confidence: Medium
- [ ] ID-23
- [ ] ID-24
[Outbox._errNothingToConsume(bytes32)](src/core/messagebridge/Outbox.sol#L114-L116) is never used and should be removed

src/core/messagebridge/Outbox.sol#L114-L116


- [ ] ID-24
- [ ] ID-25
[Hash.sha256ToField(bytes32)](src/core/libraries/Hash.sol#L52-L54) is never used and should be removed

src/core/libraries/Hash.sol#L52-L54


- [ ] ID-25
- [ ] ID-26
[Outbox._errIncompatibleEntryArguments(bytes32,uint64,uint64,uint32,uint32,uint32,uint32)](src/core/messagebridge/Outbox.sol#L129-L147) is never used and should be removed

src/core/messagebridge/Outbox.sol#L129-L147
Expand All @@ -251,25 +258,25 @@ src/core/messagebridge/Outbox.sol#L129-L147
## solc-version
Impact: Informational
Confidence: High
- [ ] ID-26
- [ ] ID-27
solc-0.8.23 is not recommended for deployment

## similar-names
Impact: Informational
Confidence: Medium
- [ ] ID-27
- [ ] ID-28
Variable [Constants.LOGS_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L130) is too similar to [Constants.NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP](src/core/libraries/ConstantsGen.sol#L123)

src/core/libraries/ConstantsGen.sol#L130


- [ ] ID-28
- [ ] ID-29
Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L110) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L111)

src/core/libraries/ConstantsGen.sol#L110


- [ ] ID-29
- [ ] ID-30
Variable [Rollup.AVAILABILITY_ORACLE](src/core/Rollup.sol#L32) is too similar to [Rollup.constructor(IRegistry,IAvailabilityOracle)._availabilityOracle](src/core/Rollup.sol#L42)

src/core/Rollup.sol#L32
Expand All @@ -278,7 +285,7 @@ src/core/Rollup.sol#L32
## constable-states
Impact: Optimization
Confidence: High
- [ ] ID-30
- [ ] ID-31
[Rollup.lastWarpedBlockTs](src/core/Rollup.sol#L40) should be constant

src/core/Rollup.sol#L40
Expand All @@ -287,37 +294,37 @@ src/core/Rollup.sol#L40
## pess-multiple-storage-read
Impact: Optimization
Confidence: High
- [ ] ID-31
- [ ] ID-32
In a function [NewOutbox.insert(uint256,bytes32,uint256)](src/core/messagebridge/NewOutbox.sol#L44-L64) variable [NewOutbox.roots](src/core/messagebridge/NewOutbox.sol#L29) is read multiple times

src/core/messagebridge/NewOutbox.sol#L44-L64


- [ ] ID-32
- [ ] ID-33
In a function [Inbox.consume()](src/core/messagebridge/Inbox.sol#L104-L123) variable [Inbox.toConsume](src/core/messagebridge/Inbox.sol#L34) is read multiple times

src/core/messagebridge/Inbox.sol#L104-L123


- [ ] ID-33
- [ ] ID-34
In a function [Inbox.consume()](src/core/messagebridge/Inbox.sol#L104-L123) variable [Inbox.inProgress](src/core/messagebridge/Inbox.sol#L36) is read multiple times

src/core/messagebridge/Inbox.sol#L104-L123


- [ ] ID-34
- [ ] ID-35
In a function [FrontierMerkle.root()](src/core/messagebridge/frontier_tree/Frontier.sol#L43-L76) variable [FrontierMerkle.HEIGHT](src/core/messagebridge/frontier_tree/Frontier.sol#L8) is read multiple times

src/core/messagebridge/frontier_tree/Frontier.sol#L43-L76


- [ ] ID-35
- [ ] ID-36
In a function [Inbox.sendL2Message(DataStructures.L2Actor,bytes32,bytes32)](src/core/messagebridge/Inbox.sol#L61-L95) variable [Inbox.inProgress](src/core/messagebridge/Inbox.sol#L36) is read multiple times

src/core/messagebridge/Inbox.sol#L61-L95


- [ ] ID-36
- [ ] ID-37
In a function [FrontierMerkle.root()](src/core/messagebridge/frontier_tree/Frontier.sol#L43-L76) variable [FrontierMerkle.frontier](src/core/messagebridge/frontier_tree/Frontier.sol#L13) is read multiple times

src/core/messagebridge/frontier_tree/Frontier.sol#L43-L76
Expand Down
Loading

0 comments on commit 40ecc02

Please sign in to comment.