Entropy-Foundation / aptos-core

Aptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.
https://aptoslabs.com
Other
0 stars 2 forks source link

Quadratic complexity for creating accounts at genesis #123

Closed davidsupra closed 5 days ago

davidsupra commented 6 days ago

The following function in genesis.move incurs quadratic complexity, due to duplicate checking:

fun create_accounts(aptos_framework: &signer, accounts: vector<AccountMap>) {
    let unique_accounts = vector::empty();
    vector::for_each_ref(&accounts, |account_map| {
        let account_map: &AccountMap = account_map;
        assert!(
            !vector::contains(&unique_accounts, &account_map.account_address),
            error::already_exists(EDUPLICATE_ACCOUNT),
        );
        vector::push_back(&mut unique_accounts, account_map.account_address);

        create_account(
            aptos_framework,
            account_map.account_address,
            account_map.balance,
        );
    });
}

This makes account creation extremely slow at genesis. One workaround is to create accounts one by one. Specifically, let's change the function "create_accounts" in aptos_move/vm_genesis/src/lib.rs to as follows:

fn create_accounts(session: &mut SessionExt, accounts: &[AccountBalance]) { for account in accounts { let accounts = vec![account]; let accounts_bytes = bcs::to_bytes(accounts.as_slice()).expect("AccountMaps can be serialized"); let mut serialized_values = serialize_values(&vec![MoveValue::Signer(CORE_CODE_ADDRESS)]); serialized_values.push(accounts_bytes); exec_function( session, GENESIS_MODULE_NAME, "create_accounts", vec![], serialized_values, ); } }

With this change, account creation has linear complexity and thus is much faster.