cartesi / rollups-contracts

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

Generalize `executeVoucher` and `validateNotice` #202

Closed guidanoli closed 6 months ago

guidanoli commented 6 months ago

📚 Context

Stepping from a typed view on outputs ("one is either a voucher or a notice") to a more generalized view ("an arbitrary blob, which may encode a function call, and our contracts currently support these two function signatures"), we noticed we can create an intermediary step.

Regardless of the view, we can divide outputs into two disjoint categories: executable and non-executable. What it means to execute an output? Well, we don't know, yet. We know what it is to execute a voucher: it does a message call to another contract. We can also foresee another type of executable output, the DELEGATECALL voucher, which does a delegate call to another contract.

✔️ Solution

Why is this view interesting for us? Because we can abstract away output types at the interface level. So, instead of having executeVoucher, executeDelegateCallVoucher, etc., we can define a single entry point for executing any output, namely executeOutput. But how is such a thing possible, if outputs may have different fields, etc.? Let it accept an arbitrary blob and decode it on-the-run.

So, instead of having...

function executeOutput1([fields1...], Proof calldata proof) external;
function executeOutput2([fields2...], Proof calldata proof) external;
// ...
function executeOutput4([fields4...], Proof calldata proof) external;

We can have...

function executeOutput(bytes calldata output, Proof calldata proof) external;

It's worth mentioning that if you try to call this function with an invalid output blob or with a blob of a non-executable output, it should revert with a nice error message.

Likewise, we can generalize the validateNotice function to any output. The implementation of such a function should be completely agnostic to the contents of the output blob, as it will simply hash it and check if the proof is sound.

function validateOutput(bytes calldata output, Proof calldata proof) external view;

With this, we can also generalize the wasVoucherExecuted function...

function wasOutputExecuted(uint256 inputIndex, uint256 outputIndexWithinInput) external view returns (bool);

This means that the bitmap we currently use for vouchers will be used for any executable output.

guidanoli commented 6 months ago

FYI @cartesi/node-unit