1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use anyhow::{bail, Result};
use sov_modules_api::PublicKey;
use sov_state::WorkingSet;

use crate::{Account, Accounts};

impl<C: sov_modules_api::Context> Accounts<C> {
    pub(crate) fn init_module(
        &self,
        config: &<Self as sov_modules_api::Module>::Config,
        working_set: &mut WorkingSet<C::Storage>,
    ) -> Result<()> {
        for pub_key in config.pub_keys.iter() {
            if self.accounts.get(pub_key, working_set).is_some() {
                bail!("Account already exists")
            }

            self.create_default_account(pub_key.clone(), working_set)?;
        }

        Ok(())
    }

    pub(crate) fn create_default_account(
        &self,
        pub_key: C::PublicKey,
        working_set: &mut WorkingSet<C::Storage>,
    ) -> Result<Account<C>> {
        let default_address = pub_key.to_address();
        self.exit_if_address_exists(&default_address, working_set)?;

        let new_account = Account {
            addr: default_address.clone(),
            nonce: 0,
        };

        self.accounts.set(&pub_key, &new_account, working_set);

        self.public_keys
            .set(&default_address, &pub_key, working_set);
        Ok(new_account)
    }

    fn exit_if_address_exists(
        &self,
        address: &C::Address,
        working_set: &mut WorkingSet<C::Storage>,
    ) -> Result<()> {
        anyhow::ensure!(
            self.public_keys.get(address, working_set).is_none(),
            "Address already exists"
        );
        Ok(())
    }
}