Refactor code commitment methodology
- 主要语言
- Rust
- 星标
- 132
- 派生
- 167
- 平均合并
- 1 天 23 小时
- 30 天内合并 PR
- 110
描述
There are currently two code "entities" that we commit to as a part of the protocol:
- Note scripts - committed to simplify as `NoteScriptRoot` which is the hash of the script's entrypoint procedure.
- Account code - committed to as `hash(proc0_root, proc1_root, ..., procN_root)` where procedure roots are not sorted, and `proc0` is expected to be the authentication procedure of the account.
In https://github.com/0xMiden/miden-vm/issues/3067, we propose to change the commitment methodology of the MAST forest to:
```
commitment = hash(interface_commitment || dependency_commitment || advice_commitment)
```
Where:
```
interface_commitment = hash(root_nodes)
dependency_commitment = hash(external_nodes)
```
This should unambiguously commit to a given MAST forest. We should do something similar for protocol code commitments as well.
### Note scripts
For note scripts, we can define the commitment to be:
```
commitment = hash(script_root || dependency_commitment || advice_commitment)
```
The `dependency_commitment` and `advice_commitment` here could be defined in the same way as for the MAST forest. Overall, it should be pretty easy to compute this in the transaction kernel:
- We'd get `script_root`, a sorted list of external nodes, and advice commitment non-deterministically.
- We'd compute `dependency_commitment` from `external_nodes`. In the future, we could also check if all external nodes are present in the code registry.
- Then, we compute the `commitment` from its parts.
A few notes about the above:
- This would be slightly different from the proposed MAST forest commitment methodology. The main difference is that we take only `script_root` rather than roots of all procedures in the MAST forest to compute the commitment. This should be fine as long as the script is not expected to invoke some procedures in the forest dynamically. If we do want the dynamic invocation capability, then, we'll also need to commit to roots of all procedures in the forest.
- A fee related thought: somehow, for fee computations, we'd need to get the size of the MAST forest. This is relevant only for public notes, and I think it is fine to get it non-deterministically - but we'll need to come up with a mechanism for how to do it (e.g., maybe we need another event for this).
### Account code
For account code, we can define the commitment to be:
```
commitment = hash(interface_commitment || dependency_commitment || advice_commitment)
```
Where `interface_commitment` would be a hash the procedures of the account's interface (i.e., the ones to be invoked via the `call` instruction).
A few notes here as we:
- Similar to note scripts, only procedures covered by `interface_commitment` could be called dynamically. This may be fine for account code, but if we want to make other procedures invocable dynamically (i.e., via `dynexec`), we'd need to commit to all procedure roots of the MAST forest as well.
- To compute the interface commitment, we'd need to sort procedures somehow. Potential approaches are covered in https://github.com/0xMiden/protocol/issues/2961.
- Similar to note scripts, for fee computation purposes, we'd need to get the size of the MAST forest for public accounts somehow. Maybe also can be done via an event.
#### An alternative interface commitment
We could potentially address the first two points by changing how we commit to the interface procedures. Specifically, instead of absorbing each procedure as just a single root, we can expand each procedure's commitment to two words:
```
[PROC_ROOT, is_auth_proc, is_interface_proc, 0, 0]
```
Then, all procedures could be sorted by `PROC_ROOT`.
This does come with its own complications and increases the amount of hashing by 2x - so, not clear if it is worth it.
贡献指南
评估
这个 Issue 还没有评估数据。