cartesi / rollups-contracts

Smart Contracts for Cartesi Rollups
https://cartesi.github.io/rollups-contracts/
Apache License 2.0
18 stars 38 forks source link

Include the chain ID in the `EvmAdvance` input #145

Closed guidanoli closed 7 months ago

guidanoli commented 9 months ago

📚 Context

The chain ID uniquely identifies a network through an uint256 value. For the Ethereum main net, this value is 1, and for the Sepolia test net, this value is 11155111, for example. This information is included in signed transactions to avoid replay attacks.

The DApp can interact with other contracts, such as portals and token contracts, whose addresses may change depending on the network in which the DApp contract is deployed. For this reason, the DApp back-end needs to be aware of this information.

Currently, this chain ID is not known to the back-end developers. This information could be relayed to the back-end through a relay contract (not implemented), but then how would you know the address of this contract? We now think this is an antipattern, since the DApp would not be "ready" at $t=0$. See #144 for context.

Because the chain ID is not known at runtime, it is decided at compile time. In other words, the back-end must decide which chain should it expect to run on before receiving its first advance request. This makes the back-end machine initial state chain-specific.

This problem is relevant because it impacts DApp developers, given that they must decide which chain the DApp must be deployed, in other to generate the machine image correctly.

✔️ Solution

Add block.chainid to the input metadata. In #84 terms, this would correspond to another parameter to the EvmAdvance function.

This information could be abstracted away from the user by high-level frameworks. The new procedure for validating inputs coming from trusted contract would be the following:

  1. Input received with $sender$ and $chainId$ in the metadata
  2. Check if $sender \in TrustedSenders[chainId]$
  3. Delegate input handling to $TrustedHandlers[chainId][sender]$
guidanoli commented 7 months ago

Alternative validation steps for inputs coming from trusted contracts

For HLF developers, there is a similar, arguably more elegant, procedure for validating inputs coming from trusted contracts. First, we need to enumerate kinds of inputs added by relays.

data InputKind = EtherDeposit | Erc20Deposit | Erc721Deposit | -- ...

Then, we define a partial mapping from the chain ID and the input sender to an input kind. In practice, this could be implemented by a hash table.

data getInputKind : ChainId -> Address -> Maybe InputKind

Finally, we define a total mapping from the kind of input to handler functions.

data getInputHandler : InputKind -> InputHandler

Now, the HLF would do the following:

  1. get the chain ID and input sender from the input metadata
  2. get the kind of input $k$ from the chain ID and input sender (through getInputKind)
  3. if $k$ is Nothing, then proceed to fallback input handling procedure
  4. if $k$ is Just k', then forward input to input handler (through getInputHandler)

Note that I'm deliberately not defining several types here. This is just pseudocode.