How are the development keys (Alice) added to the local keystore from `chain_specs.rs`?

Viewed 262

I am trying to understand the internal logic of adding development keys to the local keystore in Substrate for development purposes. For example I can see that the session keys for Alice are being generated and added to the genesis config in /bin/node/cli/src/chain_spec.rs file as follows:

pub fn development_config() -> Result<ChainSpec, String> {
    let wasm_binary =
        WASM_BINARY.ok_or_else(|| "Development wasm binary not available".to_string())?;

    Ok(ChainSpec::from_genesis(
        // Name
        "Development",
        // ID
        "dev",
        ChainType::Development,
        move || {
            testnet_genesis(
                wasm_binary,
                // Initial PoA authorities
                vec![authority_keys_from_seed("Alice")],
                // Sudo account
                get_account_id_from_seed::<sr25519::Public>("Alice"),
                // Pre-funded accounts
                vec![
                    get_account_id_from_seed::<sr25519::Public>("Alice"),
                    get_account_id_from_seed::<sr25519::Public>("Bob"),
                    get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
                    get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
                ],
                true,
            )
        },
        // Bootnodes
        vec![],
        // Telemetry
        None,
        // Protocol ID
        None,
        // Properties
        None,
        // Extensions
        None,
    ))
}

From my understanding the session keys for development also includes ImOnlineId. My question is how exactly are the keys added to the local keystore so that I am able to access my keys as such in the im-online pallet:

    fn local_authority_keys() -> impl Iterator<Item=(u32, T::AuthorityId)> {
        // on-chain storage
        //
        // At index `idx`:
        // 1. A (ImOnline) public key to be used by a validator at index `idx` to send im-online
        //          heartbeats.
        let authorities = Keys::<T>::get();

        // local keystore
        //
        // All `ImOnline` public (+private) keys currently in the local keystore.
        let mut local_keys = T::AuthorityId::all();

        local_keys.sort();

        authorities.into_iter()
            .enumerate()
            .filter_map(move |(index, authority)| {
                local_keys.binary_search(&authority)
                    .ok()
                    .map(|location| (index as u32, local_keys[location].clone()))
            })
    }

While debugging I can find the public key for Alice in local_keys. Asking because I want to develop something similar and testing in development is made easier this way rather than manually putting keys into the keystore.

1 Answers
Related