spacemeshos / SMIPS

Spacemesh Improvement Proposals
https://spacemesh.io
Creative Commons Zero v1.0 Universal
7 stars 1 forks source link

SMIP: SVM Storage-Layer MVP (WIP) #16

Closed avive closed 1 year ago

avive commented 4 years ago

Motivation

SVM MVP should come with the minimum set of features required for implementing the Smart Wallet App.

The implementation should be compatible with future SVM versions. It means that we need to think carefully about the next steps.

We must strive not to implement things that will have to be maintained only for the backward-compatibility of the Smart Wallet App.

Specification

Data-Layout

Each deployed App Template transaction will contain along with its code (i.e wasm program) a section containing metadata.

The metadata section will include the data-layout specification for the storage of the program.

Each fixed-size program variable will have an index (a.k.a var_id), offset and len (byte-length).

The var_id and offset are zero-indexed and length.

Here is an example of a data-layout.

+----------+---------+-------+
|  var_id  |  offset |  len  |
+--------------------+-------+
|    0     |    0    |   2   |
|    1     |    2    |   4   |
|    2     |    6    |   8   |
|    3     |   14    |   2   |
+----------------------------+

In case a program has no explicit data-layout, it'll fall back to a default data-layout where each variable is of 8 bytes. In that case, the variable #i will map to offset=8 * i.

Storage Layer WASM interface:

get32

Loads the content of variable var_id as i32. Panics if variable var_id consists of more than 4 bytes (determined by its layout)

func get32(var_id: i32) -> i32

set32

Sets the value of variable var_id to value parameter. Panics if variable var_id consists of more than 4 bytes (determined by its layout), when it has no enough bytes required by value

func set32(var_id: i32, value: i32)

get64

Loads the content of variable var_id as i64. Panics if variable var_id consists of more than 8 bytes (determined by its layout)

func get64(var_id: i32) -> i64

set64

Sets the value of variable var_id to value parameter. Panics if variable var_id consists of more than 8 bytes (determined by its layout), when it has no enough bytes required by value

func set64(var_id: i32, value: i64)

load160

Loads variable var_id into memory indexed mem_idx starting from offset mem_ptr.

Panics if the variable's var_id size is different than 20 bytes.

func load160(var_id: i32, mem_idx: i32, mem_ptr: i32)

store160

Stores the 20-byte memory mem_idx cells starting from offset mem_ptr into variable var_id.

Panics if the variable's var_id size is different than 20 bytes.

func store160(var_id: i32, mem_idx: i32, mem_ptr: i32)

load256

Loads variable var_id into memory indexed mem_idx starting from offset mem_ptr.

Panics if the variable's var_id size is different than 32 bytes.

func load256(var_id: i32, mem_idx: i32, mem_ptr: i32)

store256

Stores the 32-byte memory mem_idx cells starting from offset mem_ptr into variable var_id.

Panics if the variable's var_id size is different than 32 bytes.

func store256(var_id: i32, mem_idx: i32, mem_ptr: i32)

Storage Gas cost

TBD

Rationale

The design of SVM should be minimal, usable for the future, and gas-estimation friendly. Regarding minimal - having only the above imports should be enough for the Smart Wallet App.

Also, future programs will benefit from it. Almost any program will have fixed-size variables.

It still keeps the door open for adding future calls specifying the exact variable length but it's unlikely it'll be required.

A more important gas factor should that taken into account is the total size of the variables. This should incentivize written programs to specify the minimum required storage.

Open Subject (Gas activation cost):

Another gas-factor that we need to count on is the way data is persisted.

Given the same data-layout implemented by two different storage layers - if one implementation uses much less storage we might reflect that in the total gas. (For example, if we could tell as part of the program metadata the maximum blob size for the underlying key-value store used).