ic-memory 0.44.0

Durable stable-memory allocation governance for Internet Computer canisters
Documentation
#[path = "support/host.rs"]
mod host;
use host::RUNTIME;

const AUTHORITY: &str = "wasm_runtime_integration_size_probe";
const KEY: &str = "wasm_runtime_integration_size_probe.rows.v1";

#[unsafe(no_mangle)]
pub extern "C" fn ic_memory_wasm_runtime_integration_size_probe_bootstrap() -> u64 {
    let Ok(declarations) = probe_declarations() else {
        return 0;
    };
    RUNTIME.with(|slot| {
        let Ok(mut slot) = slot.try_borrow_mut() else {
            return 0;
        };
        if slot.is_none() {
            let Ok(config) = ic_memory::MemoryManagerConfig::new(16) else {
                return 0;
            };
            let Ok(runtime) = host::Runtime::new_with_config(
                ic_memory::ic_stable_structures::DefaultMemoryImpl::default(),
                config,
            ) else {
                return 0;
            };
            *slot = Some(runtime);
        }
        let Some(runtime) = slot.as_mut() else {
            return 0;
        };
        runtime
            .bootstrap(&declarations, &pool(), &ic_memory::GenericAllocationPolicy)
            .map_or(0, ic_memory::CommittedAllocations::generation)
    })
}

#[unsafe(no_mangle)]
pub extern "C" fn ic_memory_wasm_runtime_integration_size_probe_grow(pages: u64) -> u32 {
    RUNTIME
        .with(|slot| {
            slot.try_borrow()
                .ok()?
                .as_ref()?
                .open_memory(KEY)
                .ok()?
                .grow(pages)
                .ok()
                .and_then(|previous| u32::try_from(previous).ok())
        })
        .unwrap_or(u32::MAX)
}

#[unsafe(no_mangle)]
pub extern "C" fn ic_memory_wasm_runtime_integration_size_probe_adopt() -> u32 {
    RUNTIME
        .with(|slot| {
            let slot = slot.try_borrow().ok()?;
            let runtime = slot.as_ref()?;
            runtime
                .verify_authority(&probe_declarations().ok()?, AUTHORITY)
                .ok()?;
            runtime.memory_id(KEY).ok().map(u32::from)
        })
        .unwrap_or(u32::MAX)
}

#[unsafe(no_mangle)]
pub extern "C" fn ic_memory_wasm_runtime_integration_size_probe_summary() -> u32 {
    RUNTIME
        .with(|slot| {
            let slot = slot.try_borrow().ok()?;
            let summary = slot.as_ref()?.memory_allocation_summary().ok()?;
            let mut bytes = Vec::new();
            ciborium::into_writer(&summary, &mut bytes).ok()?;
            u32::try_from(bytes.len()).ok()
        })
        .unwrap_or(u32::MAX)
}

fn pool() -> ic_memory::MemoryAllocationPool {
    ic_memory::MemoryAllocationPool::new(
        vec![
            ic_memory::MemoryAuthority::new(
                "wasm_runtime_integration_size_probe",
                "wasm_runtime_integration_size_probe.",
            )
            .unwrap(),
        ],
        vec![],
    )
    .unwrap()
}

fn probe_declarations()
-> Result<ic_memory::SealedDeclarationSnapshot, ic_memory::MemoryDeclarationError> {
    let request = ic_memory::MemoryRequest::new(
        AUTHORITY,
        "wasm_runtime_integration_size_probe.rows.v1",
        ic_memory::SchemaMetadata::default(),
    )?;
    ic_memory::SealedDeclarationSnapshot::new(vec![request])
}