Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/docs/src/core/src/integrating-tests.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Integrating the OVM Transpiler
Installing
-----------

Both `truffle` and `ethereum-waffle` allow you to specify a custom replacement for `solc`. First, you'll need to install ``@eth-optimism/solc-transpiler``:
Both ``truffle`` and ``ethereum-waffle`` allow you to specify a custom replacement for ``solc-js``. First, you'll need to install ``@eth-optimism/solc-transpiler``:

.. code-block:: none

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/core/src/limitations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Our transpiler does not currently support the usage of libraries in solidity --

TX.origin
-------------
Msg.sender is supported by the OVM, but ``tx.origin`` is not yet. Staye tuned--it's coming soon!
Msg.sender is supported by the OVM, but ``tx.origin`` is not yet. Stay tuned--it's coming soon!

Parent/Child chain communication
-------------
Expand Down
104 changes: 61 additions & 43 deletions packages/docs/src/core/src/spec/design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
Notes on Design Philosophy
==========================


# Overview
********
Overview
********

This diagram depicts a simple developer enviornment interacting with a Rollup node using the MVOVM.

![high-level-ovm (2) (1)](https://user-images.githubusercontent.com/706123/70545643-e78cb480-1b3b-11ea-8562-59e7d3e23b0b.png)
!high-level-ovm (2) (1)](https://user-images.githubusercontent.com/706123/70545643-e78cb480-1b3b-11ea-8562-59e7d3e23b0b.png)
( Editable Version -- https://drive.google.com/open?id=1iF2gvJut3LU1NCfcJLn7Jh_Cm0PZIwTZ )

### Components
Components
**********

- Local Solidity test suite
- Imports transpiler
- Rollup Fullnode
Expand All @@ -20,37 +23,49 @@ This diagram depicts a simple developer enviornment interacting with a Rollup no
- Ethereum fraud contracts
- Stateless Execution Manager

# Stateful (off-chain) vs Stateless (on-chain) State Manager
**********************************************************
Stateful (off-chain) vs Stateless (on-chain) State Manager
**********************************************************

There are two settings in which we will be executing transactions against our VM:

1. Off-chain to calculate the current state of the rollup chain; and
2. On-chain to prove a fraudulent [`state root`](https://github.com/plasma-group/optimistic-rollup/wiki/Glossary).
2. On-chain to prove a fraudulent `state root <https://github.com/plasma-group/optimistic-rollup/wiki/Glossary>`_.

Both cases are identical except for one key detail: _off-chain we have access to the full state, while on-chain we only have access to the state we need to compute the result of the transaction_. This difference means that state access must be handled slightly differently between the two implementations; however, we should keep the two implementations as similar as possible to reduce the risk of bugs.

### Stateless Clients
This design comes from the work on stateless clients introduced by Vitalik: https://ethresear.ch/t/the-stateless-client-concept/172
Stateless Clients
*****************

This design comes from the work on stateless clients `introduced by Vitalik <https://ethresear.ch/t/the-stateless-client-concept/172>`_.

Stateless clients evalute state transitions with only a subset of the full state. Every storage slot & contract code which is touched during the execution of the smart contract must be stored locally to evaluate the transition. If all touched state is stored, a stateless client can evaluate the validity of a transition as well as calculate the resulting state root.

The stateless client allows us to verify a single state transition in isolation--exactly what is required for a fraud proof. Fraud proofs in ORU cannot hold all state because because then we lose the ORU scalability in the case of fraud. Instead of holding all the state, we can use a stateless client!

### Stateful (off-chain) State Manager
Stateful (off-chain) State Manager
**********************************

Off-chain there is no problem running our OVM with all of the ORU state. This behaves exactly like an Ethereum fullnode.

... TODO ...

### Stateless (on-chain) State Manager
Stateless (on-chain) State Manager
**********************************

... TODO ...

# L2_CONTEXT (aka global variables to transpile)
**********************************************
L2_CONTEXT (aka global variables to transpile)
**********************************************

Can we add fields to "msg"? e.g. have msg.queueOrigin?

A: Don't think so. looks like `msg.value` has its own assembly code of `callvalue` for example.
A: Don't think so. looks like ``msg.value`` has its own assembly code of ``callvalue`` for example.

Block and Transaction Properties ([Source](https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html))
--------------------------------
Block and Transaction Properties
********************************
`(Source) <https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html>`_

- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks
- ``block.coinbase`` (``address payable``): current block miner's address
Expand All @@ -68,37 +83,40 @@ Block and Transaction Properties ([Source](https://solidity.readthedocs.io/en/v0
- ``tx.gasprice`` (``uint``): gas price of the transaction
- ``tx.origin`` (``address payable``): sender of the transaction (full call chain)

> note:
> The values of all members of ``msg``, including ``msg.sender`` and
> ``msg.value`` can change for every **external** function call.
> This includes calls to library functions.
note:
The values of all members of ``msg``, including ``msg.sender`` and
``msg.value`` can change for every **external** function call.
This includes calls to library functions.

> note:
> Do not rely on ``block.timestamp``, ``now`` and ``blockhash`` as a source of randomness,
> unless you know what you are doing.
note:
Do not rely on ``block.timestamp``, ``now`` and ``blockhash`` as a source of randomness,
unless you know what you are doing.

> note:
> The block hashes are not available for all blocks for scalability reasons.
> You can only access the hashes of the most recent 256 blocks, all other
> values will be zero.
note:
The block hashes are not available for all blocks for scalability reasons.
You can only access the hashes of the most recent 256 blocks, all other
values will be zero.

> note:
> The function ``blockhash`` was previously known as ``block.blockhash``, which was deprecated in
> version 0.4.22 and removed in version 0.5.0.
note:
The function ``blockhash`` was previously known as ``block.blockhash``, which was deprecated in
version 0.4.22 and removed in version 0.5.0.

> note::
> The function ``gasleft`` was previously known as ``msg.gas``, which was deprecated in
> version 0.4.21 and removed in version 0.5.0.
note::
The function ``gasleft`` was previously known as ``msg.gas``, which was deprecated in
version 0.4.21 and removed in version 0.5.0.

> index: abi, encoding, packed



******************************
Other things to be transpiled:
******************************

# Other things to be transpiled:
Members of Address Types
************************

Members of Address Types ([Source](https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html))
------------------------
`(Source) <https://solidity.readthedocs.io/en/v0.4.24/units-and-global-variables.html>`_

- ``<address>.balance`` (``uint256``):
balance of the :ref:`address` in Wei
Expand All @@ -113,19 +131,19 @@ Members of Address Types ([Source](https://solidity.readthedocs.io/en/v0.4.24/un
- ``<address>.staticcall(bytes memory) returns (bool, bytes memory)``:
issue low-level ``STATICCALL`` with the given payload, returns success condition and return data, forwards all available gas, adjustable

> warning:
> There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024
> (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
> to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
> Use a pattern where the recipient withdraws the money.
warning:
There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1024
(this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
Use a pattern where the recipient withdraws the money.

> note:
> Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``.
> This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``.
note:
Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``.
This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``.
NOTE: we will need address(this) to return the L2 address and not the L1 address.

Contract Related
----------------
****************

- ``this`` (current contract's type):
the current contract, explicitly convertible to :ref:`address`
Expand Down
20 changes: 9 additions & 11 deletions packages/docs/src/core/src/spec/execution-manager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
Execution Manager Overview
================================

The Execution Manager is technically just a smart contract running in a local EVM (layer 2) and available on Ethereum to evaluate fraud claims (layer 1), but in principle, it is much more. It _is_ the layer 2 EVM, and it allows our Optimistic Rollup implementation to generically support layer 1 smart contracts.
The Execution Manager is technically just a smart contract running in a local EVM (layer 2) and available on Ethereum to evaluate fraud claims (layer 1), but in principle, it is much more. It *is* the layer 2 EVM, and it allows our Optimistic Rollup implementation to generically support layer 1 smart contracts.

Motivation
==========

The `Unipig Demo`_ showed that Optimistic Rollup is possible with custom contract code in both layer 1 and layer 2.
The `Unipig Demo <https://unipig.exchange/>`_ showed that Optimistic Rollup is possible with custom contract code in both layer 1 and layer 2.
Layer 1 contracts each need a custom state transition function that can be given a snapshot of the layer 2 state and a state transition to execute in order to evaluate if the layer 2 state transition was properly executed. A simple state transition function example would be transferring an ERC-20 token. The layer 1 token contract would need a function that takes in pre-state (i.e. address balances, approvals, etc.), evaluates a particular transition (e.g. a transfer), and computes the resulting state (i.e. updated balances). Needless to say, the logic to execute this state transition in layer 2 needed to be created as well.

To support generic smart contracts in layer 1...
------------------------------------------------

We need all state transitions for all possible contracts deployed to layer 2 to be generically calculable by layer 1. The EVM provides this functionality, but layer 1 runs on the EVM -- we need this to run on layer 1 (_on the EVM_). If we can create an EVM that can run _inside_ of the EVM, all standard EVM operations can be executed efficiently in this layer 2 EVM while also being generically verifiable in the case of fraud in layer 1 (by calling the EVM within the layer 1 EVM).
We need all state transitions for all possible contracts deployed to layer 2 to be generically calculable by layer 1. The EVM provides this functionality, but layer 1 runs on the EVM -- we need this to run on layer 1 (*on the EVM*). If we can create an EVM that can run *inside* of the EVM, all standard EVM operations can be executed efficiently in this layer 2 EVM while also being generically verifiable in the case of fraud in layer 1 (by calling the EVM within the layer 1 EVM).

To support generic smart contracts in layer 2...
------------------------------------------------
Expand Down Expand Up @@ -41,16 +41,16 @@ As stated above, the Execution Manager is a smart contract that runs in a [sligh
Transaction Context & Re-implementing Opcodes
---------------------------------------------

Transactions that are run in layer 2 will necessarily have a different context than fraud proofs in layer 1. For instance, a fraud proof can only be submitted to layer 1 to dispute a layer 2 transaction some time after it has been executed. As such, opcodes like `TIMESTAMP` will _function_ the same (it'll be the timestamp when the transaction was actually executed), but the actual current time will not _be_ the same when executed in layer 1 vs challenged as fraudulent layer 2.
Transactions that are run in layer 2 will necessarily have a different context than fraud proofs in layer 1. For instance, a fraud proof can only be submitted to layer 1 to dispute a layer 2 transaction some time after it has been executed. As such, opcodes like `TIMESTAMP` will *function* the same (it'll be the timestamp when the transaction was actually executed), but the actual current time will not *be* the same when executed in layer 1 vs challenged as fraudulent layer 2.

.. raw:: html

<img src="https://i.imgur.com/cOhmFRo.png" alt="The Execution Manager">


To handle this, the OVM ExecutionManager Contract implements these opcodes as functions. When a contract executing in layer 2 or a fraud proof executing in layer 1 needs to know the timestamp, it will call the OVM ExecutionManager Contract instead of accessing these layer-1-protocol-level opcodes directly. We have [transpilation tools](https://github.com/op-optimism/optimistic-rollup/wiki/Opcode-Transpilation-Details) that take compiled layer 1 bytecode and swap out certain opcodes, like `TIMESTAMP`, for calls to our OVM ExecutionManager Contract. All contracts deployed to layer 2 must be transpiled accordingly.
To handle this, the OVM ExecutionManager Contract implements these opcodes as functions. When a contract executing in layer 2 or a fraud proof executing in layer 1 needs to know the timestamp, it will call the OVM ExecutionManager Contract instead of accessing these layer-1-protocol-level opcodes directly. We have `transpilation tools <https://github.com/op-optimism/optimistic-rollup/wiki/Opcode-Transpilation-Details>`_ that take compiled layer 1 bytecode and swap out certain opcodes, like `TIMESTAMP`, for calls to our OVM ExecutionManager Contract. All contracts deployed to layer 2 must be transpiled accordingly.

In our example, the sequencer that commits to a layer 2 transaction passes the timestamp at the time of execution to the OVM ExecutionManager Contract with the transaction to evaluate. They also specify the same timestamp in their rollup block that includes the transaction. This way, when the fraud proof is executed, the same timestamp from the rollup block will be set in the OVM ExecutionManager Contract prior to evaluating fraud so that the context that was committed to can be accessed correctly. More on timestamp considerations [here](https://github.com/op-optimism/optimistic-rollup/wiki/MVOVM-State-Specification).
In our example, the sequencer that commits to a layer 2 transaction passes the timestamp at the time of execution to the OVM ExecutionManager Contract with the transaction to evaluate. They also specify the same timestamp in their rollup block that includes the transaction. This way, when the fraud proof is executed, the same timestamp from the rollup block will be set in the OVM ExecutionManager Contract prior to evaluating fraud so that the context that was committed to can be accessed correctly. More on timestamp considerations `here <https://github.com/op-optimism/optimistic-rollup/wiki/MVOVM-State-Specification>`_.

CALL
----
Expand All @@ -62,7 +62,7 @@ SSTORE & SLOAD

The last example to highlight is that `SSTORE` and `SLOAD` also need to be transpiled into calls to the OVM ExecutionManager Contract. Recall that one of the requirements is that the OVM ExecutionManager Contract needs to store all layer 2 state. This is so rollup blocks can commit to single pre-state and post-state roots and the fraud proof's pre- and post-state can be verified and executed through the OVM ExecutionManager Contract on layer 1 during fraud proofs.

A list of transpiled opcodes and other transpilation details are available [here](https://github.com/op-optimism/optimistic-rollup/wiki/Opcode-Transpilation-Details).
A list of transpiled opcodes and other transpilation details are available `here <https://github.com/op-optimism/optimistic-rollup/wiki/Opcode-Transpilation-Details>`_.

Example: A user trading ETH for BAT on Uniswap
==============================================
Expand Down Expand Up @@ -95,7 +95,7 @@ Uniswap / BAT Contract interaction
9. The OVM ExecutionManager Contract restores the call context such that the `CALLER` is the original caller, the `ADDRESS` is the Uniswap contract, etc.
10. The OVM ExecutionManager Contract returns the result to the Uniswap contract.
11. The Uniswap contract then calls the BAT contract, through the OVM ExecutionManager Contract again, to actually execute the transfer of the calculated amount of BAT
12. The Uniswap contract makes a final call to the BAT contract, through the OVM ExecutionManager Contract, to transfer the WETH [all ETH in layer 2 is WETH](https://github.com/op-optimism/optimistic-rollup/wiki/Opcode-Transpilation-Details#eth-native-value).
12. The Uniswap contract makes a final call to the BAT contract, through the OVM ExecutionManager Contract, to transfer the WETH `all ETH in layer 2 is WETH <https://github.com/op-optimism/optimistic-rollup/wiki/Opcode-Transpilation-Details#eth-native-value>`_.
13. The Uniswap returns the number of tokens bought.
14. The OVM ExecutionManager Contract restores the original call context before the original call to the Uniswap contract and returns the result.

Expand All @@ -119,6 +119,4 @@ Not mentioned above:



*The layer 2 EVM will be run by the Sequencer that submits new layer 2 "blocks" to layer 1, validators who validate these blocks once submitted to layer 1, and any other interested party. Validation entails executing each individual state transition that is claimed to be valid by the Sequencer and ensuring that it is, in fact, valid (i.e. the resulting state from executing the state transition match the post-state claimed by the Sequencer).

.._`Unipig Demo`: https://unipig.exchange/
*The layer 2 EVM will be run by the Sequencer that submits new layer 2 "blocks" to layer 1, validators who validate these blocks once submitted to layer 1, and any other interested party. Validation entails executing each individual state transition that is claimed to be valid by the Sequencer and ensuring that it is, in fact, valid (i.e. the resulting state from executing the state transition match the post-state claimed by the Sequencer).
Loading