Skip to content

Use builder pattern for App init #388

@ethanfrey

Description

@ethanfrey

Extending #387

With the generic modules, we no longer have generic initialisation functions (like setting the balance).

I propose the following builder pattern.

Router::new() // this will set with BankKeeper, WasmKeeper, and the rest unimplemented
.with_staking(stakingKeeper) // so we can extend these later
.build_app() // this will create an app with MockApi and MockStorage

The main question I have is how to call the setup/init methods on custom keepers that go beyond the default module types (eg. init_balance). Here are some examples:

    // Add a new contract. Must be done on the base object, when no contracts running
    fn store_code(&mut self, code: Box<dyn Contract<C>>) -> usize;

    // Admin interface
    fn init_balance(
        &self,
        storage: &mut dyn Storage,
        account: &Addr,
        amount: Vec<Coin>,
    ) -> Result<(), String>;

We can either just set these on the router when building (and then pass the storage into the build_app constructor:

let mut router = Router::new();
let mut storage = MockStorage::new();
router.bank.init_balance(&mut storage, &owner, coins(1000, "etc"));
let mut app = router.build_app(storage);

Or we can expose these with some closure in the app.

let mut app = Router::new().build_app();
app.setup(|router: &Router, storage: &mut dyn Storage| {
  router.bank.init_balance(storage, &owner, coins(1000, "etc"));
  router.bank.init_balance(storage, &trader, coins(10, "btc"));
})

In either case, we must make the different keepers public on the router interface. I lean towards the second one.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions