From 927c5b45684b2477230a2344cfcde7baf78b81c6 Mon Sep 17 00:00:00 2001 From: Mohanson Date: Fri, 18 Mar 2022 10:27:54 +0800 Subject: [PATCH] RFC33: ckb vm version1 changes (#236) * docs: add ckb-vm version1 changes * chore: reorganize articles * doc: rename vm-syscalls-2 to ckb-hardfork * clean * fix: ckb_current_cycles returns uint64_t * Fix mop instructions * Update exec syscall * Fix my broken English by Ashlee Wang * Rename 0029-ckb-hardfork.md to 0029-vm-syscalls.md * Add a backlink to the old syscalls RFC * Memtion ckb-vm version 1 in RFC0003 * Memtion ckb-vm version 1 in RFC0003 * RFC number changes to 0000 * Give it a RFC number 0236 * Give it a RFC number 0236 * Update B extension and MOP instructions * Update rfc number to 33 --- rfcs/0003-ckb-vm/0003-ckb-vm.md | 10 ++ rfcs/0003-ckb-vm/0003-ckb-vm.zh.md | 10 ++ .../0033-ckb-vm-version-1.md | 108 ++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 rfcs/0033-ckb-vm-version-1/0033-ckb-vm-version-1.md diff --git a/rfcs/0003-ckb-vm/0003-ckb-vm.md b/rfcs/0003-ckb-vm/0003-ckb-vm.md index 67a5f7c40..9263dfa3e 100644 --- a/rfcs/0003-ckb-vm/0003-ckb-vm.md +++ b/rfcs/0003-ckb-vm/0003-ckb-vm.md @@ -368,3 +368,13 @@ int main(int argc, char* argv[]) ``` Here all UDT functions are linked dynamically from external cells, current contract can be minimized in terms of size. + +### Update + +Any new version of CKB-VM will not affect the execution results of the old transactions. We released CKB-VM version 1 in the CKB hardfork [1]. + +# Reference + +* [1]: [CKB-VM version 1][1] + +[1]: ../0033-ckb-vm-version-1/0033-ckb-vm-version-1.md diff --git a/rfcs/0003-ckb-vm/0003-ckb-vm.zh.md b/rfcs/0003-ckb-vm/0003-ckb-vm.zh.md index 25d3bb10e..3307a25a2 100644 --- a/rfcs/0003-ckb-vm/0003-ckb-vm.zh.md +++ b/rfcs/0003-ckb-vm/0003-ckb-vm.zh.md @@ -339,3 +339,13 @@ int main(int argc, char* argv[]) ``` 这里所有的 UDT 函数均通过动态链接的方式引用其他 Cell 里的内容,不占用当前 Cell 的空间。 + +### 更新 + +任何 CKB-VM 的新版本均不会影响旧有交易的执行结果. 我们在 CKB 硬分叉版本中发布了 CKB-VM version 1 [1]. + +# 参考 + +* [1]: [CKB-VM version 1][1] + +[1]: ../0033-ckb-vm-version-1/0033-ckb-vm-version-1.md diff --git a/rfcs/0033-ckb-vm-version-1/0033-ckb-vm-version-1.md b/rfcs/0033-ckb-vm-version-1/0033-ckb-vm-version-1.md new file mode 100644 index 000000000..2744125cf --- /dev/null +++ b/rfcs/0033-ckb-vm-version-1/0033-ckb-vm-version-1.md @@ -0,0 +1,108 @@ +--- +Number: "0033" +Category: Informational +Status: Draft +Author: Wanbiao Ye +Organization: Nervos Foundation +Created: 2021-05-25 +--- + +# VM version1 + +This RFC describes version 1 of the CKB-VM, in comparison to version 0, which + +- Fixed several bugs +- Behavioural changes not affecting execution results +- New features +- Performance optimisations + +## 1 Fixed Several Bugs + +CKB-VM Version 1 has fixed identified bugs discovered in Version 0. + +### 1.1 Enabling Stack Pointer SP To Be Always 16-byte Aligned + +In the previous version, SP incorrectly aligned during stack initialisation. See [issue](https://github.com/nervosnetwork/ckb-vm/issues/97). + +### 1.2 Added a NULL To Argv + +C Standard 5.1.2.2.1/2 states: `argv[argc]` should be a null pointer. `NULL` was unfortunately omitted during the initialization of the stack, and now it has returned. See [issue](https://github.com/nervosnetwork/ckb-vm/issues/98). + +### 1.3 JALR Caused Erroneous Behaviour on AsmMachine When rs1 and rd utilised the same register + +The problem arose with the JALR instruction, where the CKB-VM had made an error in the sequence of its different steps. The correct step to follow would be to calculate the pc first and then update the rd. See [problem](https://github.com/nervosnetwork/ckb-vm/issues/92). + +### 1.4 Error OutOfBound was triggered by reading the last byte of memory + +We have fixed it, as described in the title. + +### 1.5 Unaligned executable pages from loading binary would raise an error + +We have fixed it, as described in the title. + +### 1.6 Frozen writable pages by error + +This error occurred during the loading of elf. The CKB-VM has incorrectly set a freeze flag on a writeable page, which made the page unmodifiable. + +It happened mainly with external variables that have dynamic links. + +### 1.7 Update crate goblib + +goblin is a cross-platform trifecta of binary parsing and loading fun. ckb-vm uses it to load RISC-V programs. But in the past period of time goblin fixed many bugs and produced destructive upgrades, we decided to upgrade goblin: this will cause the binary that could not be loaded before can now be normal Load, or vice versa. + +## 2 Behavioural Changes that will not affect the execution outcomes + +### 2.1 Skip writing 0 to memory when argc equals 0 during stack initialisation + +For ckb scripts, argc is always 0 and the memory is initialised to 0, so memory writing can be safely skipped. Note that when "chaos_mode" is enabled and "argv" is empty, the reading of "argc" will return an unexpected data. This happens uncommonly, and never happens on the mainnet. + +### 2.2 Redesign of the internal instruction format + +For the sake of fast decoding and cache convenience, RISC-V instruction is decoded into the 64-bit unsigned integer. Such a format used only internally in ckb-vm rather than the original RISC-V instruction format. + +## 3 New features + +### 3.1 B extension + +We have added the RISC-V B extension (v1.0.0) [1]. This extension aims at covering the four major categories of bit manipulation: counting, extracting, inserting and swapping. For all B instructions, 1 cycle will be consumed. + +### 3.2 Chaos memory mode + +Chaos memory mode was added for the debugging tools. Under this mode, the program memory forcibly initializes randomly, helping us to discover uninitialized objects/values in the script. + +### 3.3 Suspend/resume a running VM + +It is possible to suspend a running CKB VM, save the state to a certain place and to resume the previously running VM later on, possibly even on a different machine. + +## 4 Performance optimization + +### 4.1 Lazy initialization memory + +In version 0, when the VM was initialised, the program memory would be initialised to zero value. Now, we have deferred the initialisation of program memory. The program memory is divided into several different frames, so that only when a frame is used (read, write), the corresponding program memory area of that frame will be initialised with zero value. As a result , small programs that do not need to use large volumes of memory will be able to run faster. + +### 4.2 MOP + +Macro-Operation Fusion (also Macro-Op Fusion, MOP Fusion, or Macrofusion) is a hardware optimization technique found in many modern microarchitectures whereby a series of adjacent macro-operations are merged into a single macro-operation prior or during decoding. Those instructions are later decoded into fused-µOPs. + +The cycle consumption of the merged instructions is the maximum cycle value of the two instructions before the merge. We have verified that the use of MOPs can lead to significant improvements in some encryption algorithms. + +| Opcode | Origin | Cycles | +| ---------------------------- | ---------------------------- | ----------------- | +| ADC [2] | add + sltu + add + sltu + or | 1 + 0 + 0 + 0 + 0 | +| SBB | sub + sltu + sub + sltu + or | 1 + 0 + 0 + 0 + 0 | +| WIDE_MUL | mulh + mul | 5 + 0 | +| WIDE_MULU | mulhu + mul | 5 + 0 | +| WIDE_MULSU | mulhsu + mul | 5 + 0 | +| WIDE_DIV | div + rem | 32 + 0 | +| WIDE_DIVU | divu + remu | 32 + 0 | +| FAR_JUMP_REL | auipc + jalr | 0 + 3 | +| FAR_JUMP_ABS | lui + jalr | 0 + 3 | +| LD_SIGN_EXTENDED_32_CONSTANT | lui + addiw | 1 + 0 | + +# Reference + +* [1]: [B extension][1] +* [2]: [Macro-op-fusion: Pattern design of ADC and SBB][2] + +[1]: https://github.com/riscv/riscv-bitmanip +[2]: https://github.com/nervosnetwork/ckb-vm/issues/169