paritytech / substrate

Substrate: The platform for blockchain innovators
Apache License 2.0
8.39k stars 2.65k forks source link

`AssetDetails` & `AssetMetadata` can not be populated from a storage migration #13174

Open NachoPal opened 1 year ago

NachoPal commented 1 year ago

I was trying to populate my chain with some assets via a runtime upgrade + storage migration, but it seems it is not possible because AssetDetails & AssetMetadata fields are private.

Here an example of a migration that will not compile:

pub struct PopulateAssets;
impl frame_support::traits::OnRuntimeUpgrade for PopulateAssets {
    fn on_runtime_upgrade() -> Weight {
        let sudo_account: [u8; 32] = [225,173,32,170,226,57,204,187,96,154,165,55,213,21,220,157,83,197,147,110,166,125,138,204,159,224,97,137,37,39,159,125];
        let sudo = MultiSigner::Sr25519(sr25519::Public(sudo_account));

        let asset: pallet_assets::AssetDetails::<Balance, AccountId, Balance> = pallet_assets::AssetDetails {
            owner: sudo.clone().into_account(),
            issuer: sudo.clone().into_account(),
            admin: sudo.clone().into_account(),
            freezer: sudo.clone().into_account(),
            supply: Zero::zero(),
            deposit: Zero::zero(),
            min_balance: 100_000,
            is_sufficient: true,
            accounts: 0,
            sufficients: 0,
            approvals: 0,
            is_frozen: false,
        };

        let asset_id: AssetId = 1;
        let key = asset_id.blake2_128_concat();
        frame_support::migration::put_storage_value(b"Assets", b"Asset", &key, asset);

        <Runtime as frame_system::Config>::DbWeight::get().writes(1)
    }
 }

What I am trying to do is actually not possible? or I am missing something? Might it be possible to make those Structs public?

ruseinov commented 1 year ago

TBH I'm not sure why the storage items are private. For example in Staking the storage is public, which allows building upon it. It's really useful for 3rd-party developers that want to introduce their own logic building upon frame.

Currently a lot of 3rd party projects implement their own Assets and other pallets, because there is no easy way to customize the current design or reuse some of it's parts.

And all the storage is public anyway when you access it from the outside world.

One concern is it exposes some internal structs that are subject to change, but that's not such a big problem as this will produce compile-time errors if some other pallet depends on those and any changes to pallet storage should be accompanied by migrations anyway.

The other concern is storage modification bypassing the rules a pallet imposes in it's logic, but that's the price one might want to pay for extensibility. Or at the very least being able to expose storage as RO is already a big win.