5

I am trying to benchmark pallet_election_provider_multi_phase and after quite some time of normal running I get this error which halts the benchmark:

Running Benchmark:  pallet_election_provider_multi_phase    elect_queued    100/50  0/1    
Running Benchmark:  pallet_election_provider_multi_phase    elect_queued    101/50  0/1    
[0] 💸 generated 1 npos voters, 1 from validators and 0 nominators    
[#0] 🗳  creating a snapshot with metadata SolutionOrSnapshotSize { voters: 1, targets: 1 } 
[#0] 🗳  Starting signed phase round 1.    
[0] 💸 generated 1 npos voters, 1 from validators and 0 nominators    
[#0] 🗳  creating a snapshot with metadata SolutionOrSnapshotSize { voters: 1, targets: 1 } 
[#0] 🗳  Starting signed phase round 1.    
Error: Input("SignedCannotPayDeposit")

With pallet_election_phragmen I get a different error message:

Error: Input("failed to submit candidacy")

How can I fix this? Here's my dev chain spec:


fn development_config_genesis() -> GenesisConfig {
    let wasm_binary = WASM_BINARY.expect("Development wasm not available");
    testnet_genesis(
        wasm_binary,
        // Initial authorities aka stakers
        vec![
            authority_keys_from_seed("Alice"),
        ],
        // Sudo account
        get_account_id_from_seed::<sr25519::Public>("Alice"),
        // Initial nominators
        vec![],
    )
}
fn testnet_genesis(
    wasm_binary: &[u8],
    initial_authorities: Vec<(
        AccountId, // Stash
        AccountId, // Controller
        GrandpaId,
        BabeId,
        ImOnlineId,
        AuthorityDiscoveryId,
    )>,
    root_key: AccountId,
    initial_nominators: Vec<AccountId>,
) -> GenesisConfig {
    let mut rng = rand::thread_rng();
    let mut endowed_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>("Charlie"),
        get_account_id_from_seed::<sr25519::Public>("Ferdie"),
        get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
        get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
        get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
    ];
    let stakers = initial_authorities
        .iter()
        .map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator))
        .chain(initial_nominators.iter().map(|n| {
            use rand::{seq::SliceRandom, Rng};
            let limit = (MAX_NOMINATIONS as usize).min(initial_authorities.len());
            let count = rng.gen::<usize>() % limit;
            let nominations = initial_authorities
                .as_slice()
                .choose_multiple(&mut rng, count)
                .into_iter()
                .map(|choice| choice.0.clone())
                .collect::<Vec<_>>();
            (n.clone(), n.clone(), STASH, StakerStatus::Nominator(nominations))
        }))
        .collect::<Vec<_>>();

    let num_endowed_accounts = endowed_accounts.len();
    const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
    const STASH: Balance = ENDOWMENT / 1000;

    initial_authorities
        .iter()
        .map(|x| &x.0)
        .chain(initial_nominators.iter())
        .for_each(|x| {
            if !endowed_accounts.contains(x) {
                endowed_accounts.push(x.clone())
            }
        });

    GenesisConfig {
        system: SystemConfig {
            // Add Wasm runtime to storage.
            code: wasm_binary.to_vec(),
            changes_trie_config: Default::default(),
        },
        authority_discovery: AuthorityDiscoveryConfig { keys: vec![] },
        balances: BalancesConfig {
            balances: endowed_accounts
                .iter()
                .cloned()
                .map(|k| (k, ENDOWMENT))
                .collect(),
        },
        babe: BabeConfig {
            authorities: vec![],
            epoch_config: Some(BabeEpochConfiguration {
                c: (1, 4),
                allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
            }),
        },
        grandpa: GrandpaConfig { authorities: vec![] },
        im_online: ImOnlineConfig { keys: vec![] },
        session: SessionConfig {
            keys: initial_authorities
                .iter()
                .map(|x| {
                    (
                        x.0.clone(),
                        x.0.clone(),
                        session_keys(x.3.clone(), x.2.clone(), x.4.clone(), x.5.clone()),
                    )
                })
                .collect::<Vec<_>>(),
        },
        sudo: SudoConfig {
            // Assign network admin rights.
            key: root_key,
        },
        staking: StakingConfig {
            validator_count: initial_authorities.len() as u32,
            minimum_validator_count: initial_authorities.len() as u32,
            invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
            slash_reward_fraction: Perbill::from_percent(10),
            stakers,
            ..Default::default()
        },
        treasury: Default::default(),
        council: CouncilConfig::default(),
        indices: IndicesConfig { indices: vec![] },
        elections: ElectionsConfig {
            members: endowed_accounts
                .iter()
                .take((num_endowed_accounts + 1) / 2)
                .cloned()
                .map(|member| (member, STASH))
                .collect(),
        },
    }
}
2
  • What command did you use to run that? Which runtime are you using? I am currently working on fixing the phragmen benchmark for the kusama runtime. Commented Mar 29, 2022 at 17:58
  • Can you provide a repo where we can reproduce the issue?
    – Shawn Tabrizi
    Commented Mar 30, 2022 at 0:40

1 Answer 1

4
+50

The cause of the error message failed to submit candidacy may be because when calling the extrinsic function submit_candidacy of the pallet_election_phragmen pallet to add a new endowed account candidate and the current amount of candidates as witness data, either the actual amount of candidates differs from the witness data, it is preventing duplicate candidacy as the candidate being submitted is a candidate already, the candidate being submitted is not currently an active member or active runner-up, or the candidate being submitted has insufficient funds to bond.

In order to have sufficient funds to submit the CandidacyBond as a candidate, doing so must not cause their account balance to fall below the value of the ExistentialDeposit that is defined in your runtime in runtime/src/lib.rs, extract below:

...
impl pallet_balances::Config for Runtime {
    type ExistentialDeposit = <EXISTENTIAL_DEPOSIT>;
    ...
}
...

impl pallet_elections_phragmen::Config for Runtime {
    type CandidacyBond = <CANDIDACY_BOND>;
    ...
}
...

In the extract of the chain specification file node/src/chain_spec.rs that you have shared, it shows that you are making each account in the endowed_accounts a current elected member and giving each of them a balance value of STASH, where that is calculated from the following, however you have not shown what value you are using for DOLLARS. Please check that the value you are using for DOLLARS allows the STASH value to be at least the ExistentialDeposit plus the CandidacyBond.

const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
const STASH: Balance = ENDOWMENT / 1000;

The cause of the error message SignedCannotPayDeposit is the origin failed to pay the deposit to store a solution when calling the extrinsic function submit of the pallet_election_provider_multi_phase pallet, where the deposit required to be collected is calculated using deposit_for. Please also try increasing the value of ENDOWMENT, since in the extract of the chain specification file node/src/chain_spec.rs that you have shared, it shows that endowed_accounts is the list of accounts that are being endowed with that balance at genesis.

const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
const STASH: Balance = ENDOWMENT / 1000;

GenesisConfig {
    ...
    balances: BalancesConfig {
        balances: endowed_accounts
            .iter()
            .cloned()
            .map(|k| (k, ENDOWMENT))
            .collect(),
    },

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.