Skip to main content

miden_standards/account/
upgrade.rs

1use miden_protocol::account::component::{AccountComponentCode, AccountComponentMetadata};
2use miden_protocol::account::{AccountComponent, AccountComponentName, AccountProcedureRoot};
3
4use crate::account::account_component_code;
5use crate::procedure_root;
6
7// UPGRADE MANAGER COMPONENT
8// ================================================================================================
9
10account_component_code!(UPGRADE_MANAGER_CODE, "miden-standards-upgrade-manager.masp");
11
12// PROCEDURE ROOTS
13// ================================================================================================
14
15/// MASL library namespace used for procedure-root lookups. Distinct from [`UpgradeManager::NAME`],
16/// which mirrors the standards-side MASM module path.
17const UPGRADE_MANAGER_LIBRARY_PATH: &str = "miden::standards::components::upgrade::manager";
18
19procedure_root!(
20    UPGRADE_MANAGER_UPGRADE,
21    UPGRADE_MANAGER_LIBRARY_PATH,
22    UpgradeManager::UPGRADE_PROC_NAME,
23    UpgradeManager::code()
24);
25
26/// Account component exposing an `upgrade` admin procedure, gated by the account-wide
27/// [`crate::account::access::Authority`] component via `exec.authority::assert_authorized`.
28///
29/// The procedure wraps the protocol `native_account::upgrade` kernel procedure, letting an account
30/// replace its own code. Storage upgrades are not yet supported, so the new code must use the same
31/// storage layout as the current code. Otherwise, the account can become unusable. See
32/// [`AccountCodeUpgrade`](miden_protocol::account::AccountCodeUpgrade).
33///
34/// The account's authority must authorize every upgrade.
35///
36/// `UpgradeManager` works with every standard access scheme that installs an [`Authority`]
37/// component.
38///
39/// Companion component required:
40/// - [`Authority`].
41///
42/// [`Authority`]: crate::account::access::Authority
43#[derive(Debug, Clone, Copy, Default)]
44pub struct UpgradeManager;
45
46impl UpgradeManager {
47    /// The name of the component.
48    const NAME: &'static str = "miden::standards::upgrade::manager";
49
50    const UPGRADE_PROC_NAME: &'static str = "upgrade";
51
52    /// Returns the canonical [`AccountComponentName`] of this component.
53    pub const fn name() -> AccountComponentName {
54        AccountComponentName::from_static_str(Self::NAME)
55    }
56
57    /// Returns the [`AccountComponentCode`] of this component.
58    pub fn code() -> &'static AccountComponentCode {
59        &UPGRADE_MANAGER_CODE
60    }
61
62    /// Returns the procedure root of the `upgrade` procedure exposed by this component.
63    pub fn upgrade_root() -> AccountProcedureRoot {
64        *UPGRADE_MANAGER_UPGRADE
65    }
66}
67
68impl From<UpgradeManager> for AccountComponent {
69    fn from(_: UpgradeManager) -> Self {
70        let metadata = AccountComponentMetadata::new(UpgradeManager::NAME)
71            .with_description("Code upgrades for accounts");
72
73        AccountComponent::new(UpgradeManager::code().clone(), vec![], metadata).expect(
74            "upgrade manager component should satisfy the requirements of a valid account component",
75        )
76    }
77}