use miden_protocol::account::component::{AccountComponentCode, AccountComponentMetadata};
use miden_protocol::account::{AccountComponent, AccountComponentName, AccountProcedureRoot};
use crate::account::account_component_code;
use crate::procedure_root;
account_component_code!(CODE_INSPECTION_CODE, "miden-standards-inspection-code-inspection.masp");
procedure_root!(
CODE_INSPECTION_HAS_PROCEDURE,
CodeInspection::NAME,
CodeInspection::HAS_PROCEDURE_PROC_NAME,
CodeInspection::code()
);
procedure_root!(
CODE_INSPECTION_GET_CODE_COMMITMENT,
CodeInspection::NAME,
CodeInspection::GET_CODE_COMMITMENT_PROC_NAME,
CodeInspection::code()
);
procedure_root!(
CODE_INSPECTION_GET_NUM_PROCEDURES,
CodeInspection::NAME,
CodeInspection::GET_NUM_PROCEDURES_PROC_NAME,
CodeInspection::code()
);
procedure_root!(
CODE_INSPECTION_GET_PROCEDURE_ROOT,
CodeInspection::NAME,
CodeInspection::GET_PROCEDURE_ROOT_PROC_NAME,
CodeInspection::code()
);
pub struct CodeInspection;
impl CodeInspection {
pub const NAME: &'static str = "miden::standards::components::inspection::code_inspection";
const HAS_PROCEDURE_PROC_NAME: &str = "has_procedure";
const GET_CODE_COMMITMENT_PROC_NAME: &str = "get_code_commitment";
const GET_NUM_PROCEDURES_PROC_NAME: &str = "get_num_procedures";
const GET_PROCEDURE_ROOT_PROC_NAME: &str = "get_procedure_root";
pub const fn name() -> AccountComponentName {
AccountComponentName::from_static_str(Self::NAME)
}
pub fn code() -> &'static AccountComponentCode {
&CODE_INSPECTION_CODE
}
pub fn has_procedure_root() -> AccountProcedureRoot {
*CODE_INSPECTION_HAS_PROCEDURE
}
pub fn get_code_commitment_root() -> AccountProcedureRoot {
*CODE_INSPECTION_GET_CODE_COMMITMENT
}
pub fn get_num_procedures_root() -> AccountProcedureRoot {
*CODE_INSPECTION_GET_NUM_PROCEDURES
}
pub fn get_procedure_root_root() -> AccountProcedureRoot {
*CODE_INSPECTION_GET_PROCEDURE_ROOT
}
pub fn component_metadata() -> AccountComponentMetadata {
AccountComponentMetadata::new(Self::NAME)
.with_description("Read-only introspection over the account's own code")
}
}
impl From<CodeInspection> for AccountComponent {
fn from(_: CodeInspection) -> Self {
let metadata = CodeInspection::component_metadata();
AccountComponent::new(CodeInspection::code().clone(), vec![], metadata).expect(
"code inspection component should satisfy the requirements of a valid account component",
)
}
}
#[cfg(test)]
mod tests {
use miden_protocol::account::{AccountBuilder, AccountType};
use super::CodeInspection;
use crate::account::auth::NoAuth;
#[test]
fn get_code_inspection_procedures() {
let _has_procedure_root = CodeInspection::has_procedure_root();
let _get_code_commitment_root = CodeInspection::get_code_commitment_root();
let _get_num_procedures_root = CodeInspection::get_num_procedures_root();
let _get_procedure_root_root = CodeInspection::get_procedure_root_root();
}
#[test]
fn account_exposes_code_inspection_procedures() -> anyhow::Result<()> {
let account = AccountBuilder::new([1; 32])
.account_type(AccountType::Public)
.with_auth_component(NoAuth)
.with_component(CodeInspection)
.build_existing()?;
let code = account.code();
assert!(code.has_procedure(*CodeInspection::has_procedure_root().mast_root()));
assert!(code.has_procedure(*CodeInspection::get_code_commitment_root().mast_root()));
assert!(code.has_procedure(*CodeInspection::get_num_procedures_root().mast_root()));
assert!(code.has_procedure(*CodeInspection::get_procedure_root_root().mast_root()));
Ok(())
}
}