holochain 0.6.0

Holochain, a framework for distributed applications
Documentation
use crate::core::ribosome::CallContext;
use crate::core::ribosome::RibosomeT;
use holochain_types::prelude::*;
use holochain_wasmer_host::prelude::*;
use holochain_zome_types::block::Block;
use holochain_zome_types::block::BlockTarget;
use holochain_zome_types::block::CellBlockReason;
use std::sync::Arc;
use wasmer::RuntimeError;

pub fn block_agent(
    _ribosome: Arc<impl RibosomeT>,
    call_context: Arc<CallContext>,
    input: holochain_zome_types::block::BlockAgentInput,
) -> Result<(), RuntimeError> {
    tokio_helper::block_forever_on(async move {
        call_context
            .host_context()
            .call_zome_handle()
            .block(Block::new(
                BlockTarget::Cell(
                    CellId::new(
                        call_context
                            .host_context()
                            .call_zome_handle()
                            .cell_id()
                            .dna_hash()
                            .clone(),
                        input.target,
                    ),
                    CellBlockReason::App(input.reason),
                ),
                input.interval,
            ))
            .await
            .map_err(|e| -> RuntimeError { wasm_error!(e.to_string()).into() })
    })
}

#[cfg(test)]
mod test {
    use crate::conductor::api::error::ConductorApiResult;
    use crate::sweettest::*;
    use crate::test_utils::RibosomeTestFixture;
    use holo_hash::ActionHash;
    use holo_hash::AgentPubKey;
    use holochain_state::block::get_all_cell_blocks;
    use holochain_types::prelude::CapSecret;
    use holochain_types::prelude::ZomeCallResponse;
    use holochain_wasm_test_utils::TestWasm;
    use holochain_zome_types::block::{BlockTarget, CellBlockReason};

    #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
    pub struct CapFor(CapSecret, AgentPubKey);

    #[cfg(feature = "unstable-functions")]
    #[tokio::test(flavor = "multi_thread")]
    async fn zome_call_verify_block() {
        holochain_trace::test_run();
        let RibosomeTestFixture {
            conductor,
            alice,
            alice_pubkey,
            bob,
            bob_pubkey,
            ..
        } = RibosomeTestFixture::new(TestWasm::Capability).await;

        let secret: CapSecret = conductor.call(&bob, "cap_secret", ()).await;
        let _action_hash: ActionHash = conductor.call(&bob, "transferable_cap_grant", secret).await;
        let cap_for = CapFor(secret, bob_pubkey);
        let _response0: ZomeCallResponse = conductor
            .call(&alice, "try_cap_claim", cap_for.clone())
            .await;
        let _response1: ZomeCallResponse = conductor
            .call(&alice, "try_cap_claim", cap_for.clone())
            .await;

        let _: () = conductor
            .call(&bob, "block_agent", alice_pubkey.clone())
            .await;

        let response2: ConductorApiResult<ZomeCallResponse> = conductor
            .call_fallible(&alice, "try_cap_claim", cap_for.clone())
            .await;
        assert!(response2.is_err());

        let _: () = conductor.call(&bob, "unblock_agent", alice_pubkey).await;

        let _response3: ZomeCallResponse = conductor.call(&alice, "try_cap_claim", cap_for).await;
    }

    #[tokio::test(flavor = "multi_thread")]
    async fn hdk_cell_block_adds_block_to_blockspan_database() {
        holochain_trace::test_run();
        let (dna_file, _, _) = SweetDnaFile::unique_from_test_wasms(vec![TestWasm::Create]).await;
        let mut conductor = SweetConductor::from_standard_config().await;
        let app = conductor.setup_app("", [&dna_file]).await.unwrap();

        let blocks = conductor
            .spaces
            .conductor_db
            .test_read(|txn| get_all_cell_blocks(txn));
        assert!(blocks.is_empty());

        let agent_key = app.agent().clone();
        let cell_id = app.cells()[0].cell_id().clone();
        let zome = app.cells()[0].zome(TestWasm::Create);
        let _: () = conductor.call(&zome, "block_agent", agent_key).await;

        let blocks = conductor
            .spaces
            .conductor_db
            .test_read(|txn| get_all_cell_blocks(txn));

        let expected_cell_block_reason = CellBlockReason::App(vec![]);
        assert_eq!(blocks.len(), 1);
        assert!(
            matches!(blocks[0].target(), BlockTarget::Cell(id, reason) if *id == cell_id && *reason == expected_cell_block_reason)
        );
        assert_eq!(blocks[0].start(), holochain_timestamp::Timestamp::MIN);
        assert_eq!(blocks[0].end(), holochain_timestamp::Timestamp::MAX);
    }
}