Skip to content

refactor module_store method #161

@rnbguy

Description

@rnbguy

for IdentifiedModule { id, module } in modules.iter_mut() {
module
.store_mut()
.commit()
.expect("failed to commit to state");
let mut state = self.store.write_access();
state
.set(id.clone().into(), module.store().root_hash())
.expect("failed to update sub-store commitment");
}
let mut state = self.store.write_access();
let data = state.commit().expect("failed to commit to state");

Currently, the basecoin app uses a single tree for the whole app state. So, this essentially increases the chain height multiple times.

Also, we update the module identifier paths to their recent module storage hash - which may look like never saturating. As in, after each commit, the module storage hashes will change.

This is not wrong - as the height is still monotonically increasing, but it is inefficient. Ideally, there should be a top tree storage, and each module should have its sub-tree storage at its identifier. The proofs for such tree structures will be chained.

This required the MainStorage to be modified to look something like this.

pub struct MainStorage<S> {
  main: S,
  modules: Map<ModuleIdentifier, S>
}

I was wrong. The current implementation already does this.

My confusion came from the fact the module stores are initialized as follows,

// instantiate the application with a KV store implementation of choice
let app_builder = Builder::new(GrowingStore::<InMemoryStore>::default());
// instantiate modules and setup inter-module communication (if required)
let auth = Auth::new(app_builder.module_store(&prefix::Auth {}.identifier()));

My thought was, why app_builder.module_store(&prefix::Auth {}.identifier()) is called here if it is not using the same store for the application and also the modules.

And it shouldn't. If the module is absent in app_builder, app_builder.module_store creates a new store and returns it. That's how the individual module stores are initialized.

pub fn module_store(&self, prefix: &Identifier) -> SharedStore<ModuleStore<S>> {
let modules = self.modules.read_access();
modules
.iter()
.find(|m| &m.id == prefix)
.map(|IdentifiedModule { module, .. }| module.store().share())
.unwrap_or_else(|| SharedStore::new(ModuleStore::new(S::default())))
}

Rather, the modules should be initialized as follows to avoid confusion.

let auth = Auth::new(SharedStore::new(ModuleStore::new(S::default())));

And module_store should be refactored to return Option.

 pub fn module_store(&self, prefix: &Identifier) -> Option<SharedStore<ModuleStore<S>>> { 
     let modules = self.modules.read_access(); 
     modules 
         .iter() 
         .find(|m| &m.id == prefix) 
         .map(|IdentifiedModule { module, .. }| module.store().share())
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions