Substrate: Unable to instantiate multiple balances

Created on 6 May 2020  路  5Comments  路  Source: paritytech/substrate

I'm trying to configure my runtime to operate with two currencies by instantiating the balances pallet twice (as described here). To configure my test environment the genesis is built as follows:

            let mut storage = system::GenesisConfig::default()
                .build_storage::<Runtime>()
                .unwrap();

            balances::GenesisConfig::<Runtime, balances::Instance1> {
                balances: vec![
                    (AccountId::from(ALICE), 1_000_000),
                    (AccountId::from(BOB), 1_000_000),
                ],
            }
            .assimilate_storage(&mut storage)
            .unwrap();

            balances::GenesisConfig::<Runtime, balances::Instance2> {
                balances: vec![
                    (AccountId::from(ALICE), 500_000),
                    (AccountId::from(BOB), 500_000),
                ],
            }
            .assimilate_storage(&mut storage)
            .unwrap();

However, if I then call free_balance on each module they will both return 500_000 despite the fact that the former instantiation gives both accounts 1_000_000 in this case. Furthermore, deposit_into_existing updates the balance of the account for each currency.

I3-annoyance 馃

Most helpful comment

It is already possible to store the data in balances directly. This can be closed.

https://github.com/paritytech/substrate/blob/db8916a48e2bfc9ae9c18c3fa617f7302432c685/frame/balances/src/tests_local.rs#L110-L114

All 5 comments

Example runtime:

impl balances::Trait<balances::Instance1> for Runtime {
    type Balance = Balance;
    type Event = Event;
    type DustRemoval = ();
    type ExistentialDeposit = ExistentialDeposit;
    type AccountStore = System;
}

impl balances::Trait<balances::Instance2> for Runtime {
    type Balance = Balance;
    type Event = Event;
    type DustRemoval = ();
    type ExistentialDeposit = ExistentialDeposit;
    type AccountStore = System;
}

```rust
construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
...
Currency1: balances::::{Module, Call, Storage, Config, Event},
Currency2: balances::::{Module, Call, Storage, Config, Event},
....
}
);

Explanation from @AurevoirXavier seem to make sense to me; You need to change the AccountStore of the two to something else.

You could easily hack a module together to just store your account balances in the meantime.

Also, substrate should provide something like generic-acocunt-store that you can use if you don't want to use the system as account store. This can be a good first issue for someone working on the runtime. Basically look at how system::Module<T> is implementing StoredMap and replicate that in an isolated way in a new module. The new module will not have Call or anything else, only provides storage.

It is already possible to store the data in balances directly. This can be closed.

https://github.com/paritytech/substrate/blob/db8916a48e2bfc9ae9c18c3fa617f7302432c685/frame/balances/src/tests_local.rs#L110-L114

Yes, everything mentioned in this thread is correct, and I think the right solution is that @xlc mentioned here.

Simply update your pallet configuration to store your balances account in the pallet rather than in the System account.

Was this page helpful?
0 / 5 - 0 ratings