背景
SSVM 概览
-
SSVMRPC —— 使用 Rust 编写的远程过程调用 (RPC) 实现,可以方便地与 SecondState 的无状态(Stateless)虚拟机 SSVM 进行代码部署和代码执行交互 -
SSVMContainer ーー处在网络和 SSVM 传入请求之间的 Rust 应用程序。 此应用程序处理 Wasm 应用程序的部署并管理服务的执行(即,Wasm 应用程序内部的可调用函数)。 因为 SSVM 执行无状态执行,它还管理应用程序状态。 -
SSVM ( https://github.com/second-state/SSVM )ーー 高性能、硬件优化、无状态、基于堆栈的 Wasm 虚拟机。 SSVM 可以执行 任意二进制文件 ,同时对于 AI 和 区块链 特定的应用也是高度优化的。
技术解析
安装Rust
sudo apt-get update
sudo apt-get -y upgrade
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
创建新的应用程序
cd ~
cargo new --lib add
cd add
设置 Wasm 特定的系统配置
[lib]
name = "add_lib"
path = "src/lib.rs"
crate-type =["cdylib"]
编写源代码
src/lib.rs
并加上以下代码
#[no_mangle]
pub extern fn add_two_numbers(_x: i32, _y: i32) -> i32{
_x + _y
}
Wasm 系统配置
rustup target add wasm32-wasi
rustup override set nightly
编译到Wasm
cargo build --release --target=wasm32-wasi
target/wasm32-wasi/release/add_lib.wasm
创建新的Wasm文件。
这个文件我们将部署在 SecondState 的 Wasm 基础设施 SSVM 上。
快速了解已编译的 Wasm 文件
WAT
./wasm2wat ~/add/target/wasm32-wasi/release/add_lib.wasm -o ~/add/target/wasm32-wasi/release/add_lib.wat
(module
(type (;0;) (func (param i32 i32) (result i32)))
(func $add_two_numbers (type 0) (param i32 i32) (result i32)
local.get 1
local.get 0
i32.add)
(table (;0;) 1 1 funcref)
(memory (;0;) 16)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "__data_end" (global 1))
(export "__heap_base" (global 2))
(export "add_two_numbers" (func $add_two_numbers)))
Wasm
add_lib.wasm
无法随意查看, 因为它是一个可执行的二进制文件。
此外,在没有任何优化的情况下,默认由 Rust 编译生成 Wasm 文件大约为1800000字节。
就Wasm而言,这是很大的。
xxd
命令将 Wasm 文件转换为十六进制(用于 HTTP POST 的 JSON 数据)。
但是,我建议在转换之前,缩小原来的 Wasm 文件。
xxd -p target/wasm32-wasi/release/add_lib.wasm | tr -d $'\n'
./wat2wasm ~/add/target/wasm32-wasi/release/add_lib.wat -o ~/add/target/wasm32-wasi/release/add_lib.wasm
xxd
命令了。
0061736d0100000001070160027f7f017f030201000405017001010105030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073704066d656d6f727902000a5f5f646174615f656e6403010b5f5f686561705f6261736503020f6164645f74776f5f6e756d6265727300000a09010700200120006a0b
部署应用
0x
。
Curl
0x
,在字节码的开头!
curl --header "Content-Type: application/json" \
--request POST \
--data '{
"request": {
"application": {
"storage": "file_system",
"bytecode": "0x0061736d0100000001070160027f7f017f030201000405017001010105030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073704066d656d6f727902000a5f5f646174615f656e6403010b5f5f686561705f6261736503020f6164645f74776f5f6e756d6265727300000a09010700200120006a0b","name": "Add"}}}' \
http://13.54.168.1:8080/deploy_wasm_application
Postman — GUI HTTP 客户端
0x
!
{
"request": {
"application": {
"storage": "file_system",
"bytecode": "0x0061736d0100000001070160027f7f017f030201000405017001010105030100100619037f01418080c0000b7f00418080c0000b7f00418080c0000b073704066d656d6f727902000a5f5f646174615f656e6403010b5f5f686561705f6261736503020f6164645f74776f5f6e756d6265727300000a09010700200120006a0b",
"name": "Add"
}
}
}
响应
{"response":{"application":{"name":"Add","uuid":"0xa9d57ac0f5046512"},"status":"success"}}
应用成功部署
调用一个应用的函数
命令行ー Curl 语法示例
--data
弄得晕头转向, 它实际上是相当简单明了的。
更多信息参见
HTTP POST 规范
。
实际上,我们只是调用函数
add_two_numbers
将两个数字相加并传入两个数字
[“2” ,“2”]
,期望返回值为
“4”
。
curl --header "Content-Type: application/json" \
--request POST \
--data '{"request": {"application": {"storage": "file_system", "uuid": "0xa9d57ac0f5046512"},"function": {"name": "add_two_numbers", "arguments": ["2", "2"],"argument_types": ["i32", "i32"], "return_types": ["i32"]},"modules": ["rust"] }}' \
http://13.54.168.1:8080/execute_wasm_function
GUI — Postman JSON 示例
{
"request": {
"application": {
"storage": "file_system",
"uuid": "*0xa9d57ac0f5046512*"
},
"function": {
"name": "*add_two_numbers*",
"arguments": ["*2*", "*2*"],
"argument_types": ["i32", "i32"],
"return_types": ["i32"]
},
"modules": ["rust"]
}
}
响应
"return_value":["4"]
,结果是正确的。
{
"result": {
"error_message": "",
"gas": 0,
"gas_used": 6,
"return_value": [
"4"
],
"status": "Succeeded",
"vm_snapshot": {
"global": [
[
0,
"0x0000000000100000"
],
[
1,
"0x0000000000100000"
],
[
2,
"0x0000000000100000"
]
]
}
},
"service_name": "0xa9d57ac0f5046512_1578786333_add_two_numbers",
"uuid": "0xa9d57ac0f5046512"
}
vm_snapshot
。
vm_snapshot
是什么呢?
虚拟机快照
vm_snapshot
数据允许总体系统存储 SSVM 的最新已知状态。
通过存储这个
vm_snapshot
信息,我们可以确保 SSVM 能够从上次没完成的地方继续。
使用这种方法,可以在下一次执行期间恢复 SSVM 的最后已知状态。
vm_snapshot
(VM 状态)。
有状态的 Wasm 执行即服务
add_two_numbers
添加两个数字,但当然,您可以按照需求自由编写任何逻辑。
本文分享自微信公众号 - WebAssembly 中文社区(webassemblywasm)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。