-
Notifications
You must be signed in to change notification settings - Fork 159
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RFC32: CKB VM version selection (#238)
* RFC32: CKB VM version selection * Update rfcs/0032-ckb-vm-version-selection/0032-ckb-vm-version-selection.md Co-authored-by: Boyu Yang <[email protected]> * Update rfcs/0032-ckb-vm-version-selection/0032-ckb-vm-version-selection.md * add cross references between rfc 22, 32, 33, 34, 35 * add transaction hash test vectors for data1 hash type * revise rfc32 according to the review comment * revise rfc32 according to the review comment * Apply suggestions from code review Co-authored-by: zhangsoledad <[email protected]> Co-authored-by: Boyu Yang <[email protected]> Co-authored-by: zhangsoledad <[email protected]>
- Loading branch information
1 parent
1cbeeb7
commit 3a376af
Showing
2 changed files
with
176 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
172 changes: 171 additions & 1 deletion
172
rfcs/0032-ckb-vm-version-selection/0032-ckb-vm-version-selection.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,171 @@ | ||
In review, see <https://github.com/nervosnetwork/rfcs/pull/238>, <https://github.com/nervosnetwork/rfcs/pull/236>, and <https://github.com/nervosnetwork/rfcs/pull/237> | ||
--- | ||
Number: "0032" | ||
Category: Consensus (Hard Fork) | ||
Status: Draft | ||
Author: Ian Yang | ||
Organization: Nervos Foundation | ||
Created: 2021-04-26 | ||
--- | ||
|
||
# CKB VM Version Selection | ||
|
||
## Abstract | ||
|
||
This RFC proposes a mechanism to decide on the CKB VM version to execute the transaction scripts. | ||
|
||
## Motivation | ||
|
||
It's essential to keep improving CKB VM because it is the computation bottleneck of the whole network. The upgrade packages can improve the performance, bring bug fixings and add new RISC-V extensions. However the upgrade should not break the old code, users must have the opt-in option to specify the VM version. | ||
|
||
This RFC proposes a general mechanism that determines how the CKB node chooses the CKB VM version for a transaction script group. | ||
|
||
## Specification | ||
|
||
When CKB launches the testnet Lina, it only has one VM version, the version 0. The first hard fork will bring VM version 1 which coexists with version 0. Users have the opt-in option to specify which VM version to run the script of a cell by setting the `hash_type` field. | ||
|
||
In CKB, each VM version also has its bundled instruction set, syscalls and cost model. The [rfc3], [rfc5], [rfc9] and [rfc14] have defined what is VM version 0. VM version 1 is version 0 plus the revisions mentioned in [rfc33] and [rfc34]. | ||
|
||
[rfc3]: ../0003-ckb-vm/0003-ckb-vm.md | ||
[rfc5]: ../0005-priviledged-mode/0005-priviledged-mode.md | ||
[rfc9]: ../0009-vm-syscalls/0009-vm-syscalls.md | ||
[rfc14]: ../0014-vm-cycle-limits/0014-vm-cycle-limits.md | ||
[rfc33]: ../0033-ckb-vm-version-1/0033-ckb-vm-version-1.md | ||
[rfc34]: ../0034-vm-syscalls-2/0034-vm-syscalls-2.md | ||
|
||
The first hard fork takes effect from an epoch decided by the community consensus. For all the transactions in the blocks before the activation epoch, they must run the CKB VM version 0 to verify all the script groups. In these transactions, the `hash_type` in cell lock and type script must be 0 or 1 in the serialized molecule data. | ||
|
||
After the fork is activated, CKB nodes must choose the CKB VM version for each script group. The allowed values for the `hash_type` field in the lock and type script are 0, 1, and 2. Cells are sorted into different groups if they have different `hash_type`. According to the value of `hash_type`: | ||
|
||
* When the `hash_type` is 0, the script group matches code via data hash and will run the code using the CKB VM version 0. | ||
* When the `hash_type` is 1, the script group matches code via type script hash and will run the code using the CKB VM version 1. | ||
* When the `hash_type` is 2, the script group matches code via data hash and will run the code using the CKB VM version 1. | ||
|
||
| `hash_type` | matches by | VM version | | ||
| ----------- | ---------------- | ---------- | | ||
| 0 | data hash | 0 | | ||
| 1 | type script hash | 1 | | ||
| 2 | data hash | 1 | | ||
|
||
The transaction is invalid if any `hash_type` is not in the allowed values 0, 1, and 2. | ||
|
||
See more information about code locating using `hash_type` in [rfc22]. | ||
|
||
[rfc22]: ../0022-transaction-structure/0022-transaction-structure.md | ||
|
||
The `hash_type` encoding pattern ensures that if a script matches code via type hash, CKB always uses the latest available version of VM depending when the script is executed. But if the script matches code via data hash, the VM version to execute is determined when the cell is created. | ||
|
||
Here is an example of when VM version 2 is available: | ||
|
||
| `hash_type` | matches by | VM version | | ||
| ----------- | ---------------- | ---------- | | ||
| 0 | data hash | 0 | | ||
| 1 | type script hash | 2 | | ||
| 2 | data hash | 1 | | ||
| \* | data hash | 2 | | ||
|
||
> \* The actual value to represent data hash plus VM version 2 is undecided yet. | ||
Cell owners can trade off between the determination and VM performance boost when creating the cell. They should use data hash for determination, and type hash for the latest VM techniques. | ||
|
||
In [nervosnetwork/ckb](https://github.com/nervosnetwork/ckb), the `hash_type` is returned in the JSON RPC as an enum. Now it has three allowed values: | ||
|
||
* 0: "data" | ||
* 1: "type" | ||
* 2: "data1" | ||
|
||
## RFC Dependencies | ||
|
||
This RFC depends on [rfc33], [rfc34], and [rfc35]. The 4 RFCs must be activated together at the same epoch. | ||
|
||
[rfc35]: ../0035-ckb2021-p2p-protocol-upgrade/0035-ckb2021-p2p-protocol-upgrade.md | ||
|
||
The first two RFCs, [rfc33] and [rfc34] are the specification of VM version 1. The [rfc35] proposes to run two versions of transaction relay protocols during the fork, because the VM selection algorithm depends on which epoch the transaction belongs to, thus it is not deterministic for transactions still in the memory pool. | ||
|
||
## Rationale | ||
|
||
There are many other solutions to select VM versions. The current solution results from discussion and trade-off. Following are some example alternatives: | ||
|
||
Consistently uses the latest VM version. The users cannot specify the VM versions for transactions, and the version selection will be non-determine cause it will depend on the chain state. | ||
* Depend on the script code cell epoch. Use the old VM version if the code cell is deployed before the fork, and use the new one otherwise. The problem with this solution is that anyone can re-deploy the cell and construct the transaction using the new code cell to choose VM versions. | ||
|
||
## Backward compatibility | ||
|
||
For cell scripts which reference codes via data hash, they will use the same VM before and after the fork. For those referenced by type hash, they will use the different VM versions. The dApps developers must ensure the compatibility of their scripts and upgrade them if necessary. | ||
|
||
## Test Vectors | ||
|
||
### Transaction Hash | ||
|
||
This is a transaction containing `data1` hash type. | ||
|
||
<details><summary>JSON</summary> | ||
|
||
```json | ||
{ | ||
"version": "0x0", | ||
"cell_deps": [ | ||
{ | ||
"out_point": { | ||
"tx_hash": "0xace5ea83c478bb866edf122ff862085789158f5cbff155b7bb5f13058555b708", | ||
"index": "0x0" | ||
}, | ||
"dep_type": "dep_group" | ||
} | ||
], | ||
"header_deps": [], | ||
"inputs": [ | ||
{ | ||
"since": "0x0", | ||
"previous_output": { | ||
"tx_hash": "0xa563884b3686078ec7e7677a5f86449b15cf2693f3c1241766c6996f206cc541", | ||
"index": "0x7" | ||
} | ||
} | ||
], | ||
"outputs": [ | ||
{ | ||
"capacity": "0x2540be400", | ||
"lock": { | ||
"code_hash": "0x709f3fda12f561cfacf92273c57a98fede188a3f1a59b1f888d113f9cce08649", | ||
"hash_type": "data", | ||
"args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" | ||
}, | ||
"type": null | ||
}, | ||
{ | ||
"capacity": "0x2540be400", | ||
"lock": { | ||
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", | ||
"hash_type": "type", | ||
"args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" | ||
}, | ||
"type": null | ||
}, | ||
{ | ||
"capacity": "0x2540be400", | ||
"lock": { | ||
"code_hash": "0x709f3fda12f561cfacf92273c57a98fede188a3f1a59b1f888d113f9cce08649", | ||
"hash_type": "data1", | ||
"args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" | ||
}, | ||
"type": null | ||
} | ||
], | ||
"outputs_data": [ | ||
"0x", | ||
"0x", | ||
"0x" | ||
], | ||
"witnesses": [ | ||
"0x550000001000000055000000550000004100000070b823564f7d1f814cc135ddd56fd8e8931b3a7040eaf1fb828adae29736a3cb0bc7f65021135b293d10a22da61fcc64f7cb660bf2c3276ad63630dad0b6099001" | ||
] | ||
} | ||
``` | ||
|
||
</details> | ||
|
||
The Transaction Hash is `0x9110ca9266f89938f09ae6f93cc914b2c856cc842440d56fda6d16ee62543f5c`. | ||
|
||
## Acknowledgments | ||
|
||
The authors would like to thank Jan (@janx) and Xuejie (@xxuejie) for their comments and insightful suggestions. The members of the CKB Dev team also helped by participating in the discussion and review. Boyu (@yangby-cryptape) is the primary author of the code changes, and his experiments and feedbacks are essential to complete this document. |