spacemeshos / svm

SVM - Spacemesh Virtual Machine
https://spacemesh.io
MIT License
85 stars 14 forks source link

Storage Variables Section Index #447

Open YaronWittenstein opened 2 years ago

YaronWittenstein commented 2 years ago

Before implementing the Immutable Storage, we need to prepare for that.

As explained in the SVM Code Reuse between Templates adding another dimension called Section Index should simplify things (regardless of the code reuse).

Storage Host Functions

In order to introduce the Section Index we need to adjust each storage-related host function to require a section_idx parameter in addition to the current var_id one.

Instead of reading a variable by an absolute index, we'd turn the index local and add a section index. For example get32(var_id) would turn into get32(var_id, section_idx) etc.

Later, in order to enforce an Immutable Only policy when required, the host function will just have to check that the section_index given is zero (see future issue: #472).

AccountStorage

Similarly, the interface of the AccountStorage should ask for a section_idx alongside the current var_id. The key formula should take use the Section Index now since the var_id becomes a local value with its Storage Section.

SVM SDK

For the scope of this issue, as a stopgap to make the tests pass, I'd recommend to hardcode the value 1 as the section index used in the generated code.

The svm-sdk-macros crate should change under this file: https://github.com/spacemeshos/svm/blob/master/crates/sdk-macros/src/struct/storage.rs

For example: This line https://github.com/spacemeshos/svm/blob/6edb73de199fafce0953f82af061ca1090ff911c/crates/sdk-macros/src/struct/storage.rs#L165

will be changed to:

svm_sdk::storage::ops::get32::<StorageImpl>(#id, 1) as #ty

The sdk-storage will change the Storage trait to require section_idx as well: https://github.com/spacemeshos/svm/blob/6edb73de199fafce0953f82af061ca1090ff911c/crates/sdk-storage/src/lib.rs#L17

(and consequently, the sdk-storage-mock and sdk-storage-ffi crates will have to be updated)

For the long-term SDK changes - see issue: #473 The resulting code should probably look similar to this:


fn var_section(is_mutable: bool) -> u32 {
  // immutable variables go to `Section #0`,
  // and the rest (the mutable variables) will sit under `Section #1`
  is_mutable ? 1 : 0
}

fn getter_ast(var: &Var, must_mock: bool) -> TokenStream {
    let includes = include_storage_ast(must_mock);

    match var {
        Var::Primitive { id, name, ty, is_mutable, .. } => {
            let getter_name = getter_ident(name);
            let section_idx = var_section(is_mutable);

            match ty.as_str() {
                "i8" | "u8" | "i16" | "u16" | "i32" | "u32" => {
                    quote! {
                        fn #getter_name () -> #ty {
                            #includes

                            svm_sdk::storage::ops::get32::<StorageImpl>(#id, #section_idx) as #ty
                        }
                    }
                }
   ...
   ...