#![deny(missing_docs)]
use holo_hash::*;
use holochain_serialized_bytes::prelude::*;
use holochain_types::prelude::*;
use kitsune_p2p::dependencies::kitsune_p2p_fetch::OpHashSized;
use std::sync::Arc;
mod types;
pub use types::actor::FetchContextExt;
pub use types::actor::HolochainP2pRef;
pub use types::actor::HolochainP2pSender;
pub use types::AgentPubKeyExt; pub use types::*;
mod spawn;
use ghost_actor::dependencies::tracing;
use ghost_actor::dependencies::tracing_futures::Instrument;
use kitsune_p2p_types::agent_info::AgentInfoSigned;
pub use spawn::*;
pub use test::stub_network;
pub use test::HolochainP2pDnaFixturator;
pub use kitsune_p2p;
#[allow(clippy::too_many_arguments)]
#[async_trait::async_trait]
pub trait HolochainP2pDnaT: Send + Sync {
fn dna_hash(&self) -> DnaHash;
async fn join(
&self,
agent: AgentPubKey,
maybe_agent_info: Option<AgentInfoSigned>,
initial_arc: Option<crate::dht_arc::DhtArc>,
) -> actor::HolochainP2pResult<()>;
async fn leave(&self, agent: AgentPubKey) -> actor::HolochainP2pResult<()>;
#[allow(clippy::too_many_arguments)]
async fn call_remote(
&self,
from_agent: AgentPubKey,
from_signature: Signature,
to_agent: AgentPubKey,
zome_name: ZomeName,
fn_name: FunctionName,
cap_secret: Option<CapSecret>,
payload: ExternIO,
nonce: Nonce256Bits,
expires_at: Timestamp,
) -> actor::HolochainP2pResult<SerializedBytes>;
async fn remote_signal(
&self,
from_agent: AgentPubKey,
to_agent_list: Vec<(Signature, AgentPubKey)>,
zome_name: ZomeName,
fn_name: FunctionName,
cap: Option<CapSecret>,
payload: ExternIO,
nonce: Nonce256Bits,
expires_at: Timestamp,
) -> actor::HolochainP2pResult<()>;
#[allow(clippy::ptr_arg)]
async fn publish(
&self,
request_validation_receipt: bool,
countersigning_session: bool,
basis_hash: holo_hash::OpBasis,
source: AgentPubKey,
op_hash_list: Vec<OpHashSized>,
timeout_ms: Option<u64>,
reflect_ops: Option<Vec<DhtOp>>,
) -> actor::HolochainP2pResult<()>;
async fn publish_countersign(
&self,
flag: bool,
basis_hash: holo_hash::OpBasis,
op: DhtOp,
) -> actor::HolochainP2pResult<()>;
async fn get(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetOptions,
) -> actor::HolochainP2pResult<Vec<WireOps>>;
async fn get_meta(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetMetaOptions,
) -> actor::HolochainP2pResult<Vec<MetadataSet>>;
async fn get_links(
&self,
link_key: WireLinkKey,
options: actor::GetLinksOptions,
) -> actor::HolochainP2pResult<Vec<WireLinkOps>>;
async fn count_links(
&self,
query: WireLinkQuery,
) -> actor::HolochainP2pResult<CountLinksResponse>;
async fn get_agent_activity(
&self,
agent: AgentPubKey,
query: ChainQueryFilter,
options: actor::GetActivityOptions,
) -> actor::HolochainP2pResult<Vec<AgentActivityResponse<ActionHash>>>;
async fn must_get_agent_activity(
&self,
author: AgentPubKey,
filter: holochain_zome_types::chain::ChainFilter,
) -> actor::HolochainP2pResult<Vec<MustGetAgentActivityResponse>>;
async fn send_validation_receipts(
&self,
to_agent: AgentPubKey,
receipts: ValidationReceiptBundle,
) -> actor::HolochainP2pResult<()>;
async fn authority_for_hash(
&self,
basis: holo_hash::OpBasis,
) -> actor::HolochainP2pResult<bool>;
async fn countersigning_session_negotiation(
&self,
agents: Vec<AgentPubKey>,
message: event::CountersigningSessionNegotiationMessage,
) -> actor::HolochainP2pResult<()>;
async fn new_integrated_data(&self) -> actor::HolochainP2pResult<()>;
fn chc(&self) -> Option<ChcImpl>;
}
#[cfg(feature = "test_utils")]
mockall::mock! {
pub HolochainP2pDnaT {}
#[async_trait::async_trait]
impl HolochainP2pDnaT for HolochainP2pDnaT {
fn dna_hash(&self) -> DnaHash;
async fn join(
&self,
agent: AgentPubKey,
maybe_agent_info: Option<AgentInfoSigned>,
initial_arc: Option<crate::dht_arc::DhtArc>,
) -> actor::HolochainP2pResult<()>;
async fn leave(&self, agent: AgentPubKey) -> actor::HolochainP2pResult<()>;
#[allow(clippy::too_many_arguments)]
async fn call_remote(
&self,
from_agent: AgentPubKey,
from_signature: Signature,
to_agent: AgentPubKey,
zome_name: ZomeName,
fn_name: FunctionName,
cap_secret: Option<CapSecret>,
payload: ExternIO,
nonce: Nonce256Bits,
expires_at: Timestamp,
) -> actor::HolochainP2pResult<SerializedBytes>;
#[allow(clippy::too_many_arguments)]
async fn remote_signal(
&self,
from_agent: AgentPubKey,
to_agent_list: Vec<(Signature, AgentPubKey)>,
zome_name: ZomeName,
fn_name: FunctionName,
cap: Option<CapSecret>,
payload: ExternIO,
nonce: Nonce256Bits,
expires_at: Timestamp,
) -> actor::HolochainP2pResult<()>;
#[allow(clippy::too_many_arguments)]
async fn publish(
&self,
request_validation_receipt: bool,
countersigning_session: bool,
basis_hash: holo_hash::OpBasis,
source: AgentPubKey,
op_hash_list: Vec<OpHashSized>,
timeout_ms: Option<u64>,
reflect_ops: Option<Vec<DhtOp>>,
) -> actor::HolochainP2pResult<()>;
async fn publish_countersign(
&self,
flag: bool,
basis_hash: holo_hash::OpBasis,
op: DhtOp,
) -> actor::HolochainP2pResult<()>;
async fn get(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetOptions,
) -> actor::HolochainP2pResult<Vec<WireOps>>;
async fn get_meta(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetMetaOptions,
) -> actor::HolochainP2pResult<Vec<MetadataSet>>;
async fn get_links(
&self,
link_key: WireLinkKey,
options: actor::GetLinksOptions,
) -> actor::HolochainP2pResult<Vec<WireLinkOps>>;
async fn count_links(
&self,
query: WireLinkQuery,
) -> actor::HolochainP2pResult<CountLinksResponse>;
async fn get_agent_activity(
&self,
agent: AgentPubKey,
query: ChainQueryFilter,
options: actor::GetActivityOptions,
) -> actor::HolochainP2pResult<Vec<AgentActivityResponse<ActionHash>>>;
async fn must_get_agent_activity(
&self,
author: AgentPubKey,
filter: holochain_zome_types::chain::ChainFilter,
) -> actor::HolochainP2pResult<Vec<MustGetAgentActivityResponse>>;
async fn send_validation_receipts(
&self,
to_agent: AgentPubKey,
receipts: ValidationReceiptBundle,
) -> actor::HolochainP2pResult<()>;
async fn authority_for_hash(
&self,
basis: holo_hash::OpBasis,
) -> actor::HolochainP2pResult<bool>;
async fn countersigning_session_negotiation(
&self,
agents: Vec<AgentPubKey>,
message: event::CountersigningSessionNegotiationMessage,
) -> actor::HolochainP2pResult<()>;
async fn new_integrated_data(&self) -> actor::HolochainP2pResult<()>;
fn chc(&self) -> Option<ChcImpl>;
}
impl Clone for HolochainP2pDnaT {
fn clone(&self) -> Self;
}
}
#[derive(Clone)]
pub struct HolochainP2pDna {
sender: ghost_actor::GhostSender<actor::HolochainP2p>,
dna_hash: Arc<DnaHash>,
chc: Option<ChcImpl>,
}
pub type ChcImpl = Arc<dyn 'static + Send + Sync + ChainHeadCoordinatorExt>;
#[async_trait::async_trait]
impl HolochainP2pDnaT for HolochainP2pDna {
fn dna_hash(&self) -> DnaHash {
(*self.dna_hash).clone()
}
async fn join(
&self,
agent: AgentPubKey,
maybe_agent_info: Option<AgentInfoSigned>,
initial_arc: Option<crate::dht_arc::DhtArc>,
) -> actor::HolochainP2pResult<()> {
self.sender
.join(
(*self.dna_hash).clone(),
agent,
maybe_agent_info,
initial_arc,
)
.await
}
async fn leave(&self, agent: AgentPubKey) -> actor::HolochainP2pResult<()> {
self.sender.leave((*self.dna_hash).clone(), agent).await
}
async fn call_remote(
&self,
from_agent: AgentPubKey,
from_signature: Signature,
to_agent: AgentPubKey,
zome_name: ZomeName,
fn_name: FunctionName,
cap_secret: Option<CapSecret>,
payload: ExternIO,
nonce: Nonce256Bits,
expires_at: Timestamp,
) -> actor::HolochainP2pResult<SerializedBytes> {
self.sender
.call_remote(
(*self.dna_hash).clone(),
from_agent,
from_signature,
to_agent,
zome_name,
fn_name,
cap_secret,
payload,
nonce,
expires_at,
)
.await
}
async fn remote_signal(
&self,
from_agent: AgentPubKey,
to_agent_list: Vec<(Signature, AgentPubKey)>,
zome_name: ZomeName,
fn_name: FunctionName,
cap: Option<CapSecret>,
payload: ExternIO,
nonce: Nonce256Bits,
expires_at: Timestamp,
) -> actor::HolochainP2pResult<()> {
self.sender
.remote_signal(
(*self.dna_hash).clone(),
from_agent,
to_agent_list,
zome_name,
fn_name,
cap,
payload,
nonce,
expires_at,
)
.await
}
async fn publish(
&self,
request_validation_receipt: bool,
countersigning_session: bool,
basis_hash: holo_hash::OpBasis,
source: AgentPubKey,
op_hash_list: Vec<OpHashSized>,
timeout_ms: Option<u64>,
reflect_ops: Option<Vec<DhtOp>>,
) -> actor::HolochainP2pResult<()> {
self.sender
.publish(
(*self.dna_hash).clone(),
request_validation_receipt,
countersigning_session,
basis_hash,
source,
op_hash_list,
timeout_ms,
reflect_ops,
)
.await
}
async fn publish_countersign(
&self,
flag: bool,
basis_hash: holo_hash::OpBasis,
op: DhtOp,
) -> actor::HolochainP2pResult<()> {
self.sender
.publish_countersign((*self.dna_hash).clone(), flag, basis_hash, op)
.await
}
async fn get(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetOptions,
) -> actor::HolochainP2pResult<Vec<WireOps>> {
self.sender
.get((*self.dna_hash).clone(), dht_hash, options)
.instrument(tracing::debug_span!("HolochainP2p::get"))
.await
}
async fn get_meta(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetMetaOptions,
) -> actor::HolochainP2pResult<Vec<MetadataSet>> {
self.sender
.get_meta((*self.dna_hash).clone(), dht_hash, options)
.await
}
async fn get_links(
&self,
link_key: WireLinkKey,
options: actor::GetLinksOptions,
) -> actor::HolochainP2pResult<Vec<WireLinkOps>> {
self.sender
.get_links((*self.dna_hash).clone(), link_key, options)
.await
}
async fn count_links(
&self,
query: WireLinkQuery,
) -> actor::HolochainP2pResult<CountLinksResponse> {
self.sender
.count_links((*self.dna_hash).clone(), query)
.await
}
async fn get_agent_activity(
&self,
agent: AgentPubKey,
query: ChainQueryFilter,
options: actor::GetActivityOptions,
) -> actor::HolochainP2pResult<Vec<AgentActivityResponse<ActionHash>>> {
self.sender
.get_agent_activity((*self.dna_hash).clone(), agent, query, options)
.await
}
async fn must_get_agent_activity(
&self,
author: AgentPubKey,
filter: holochain_zome_types::chain::ChainFilter,
) -> actor::HolochainP2pResult<Vec<MustGetAgentActivityResponse>> {
self.sender
.must_get_agent_activity((*self.dna_hash).clone(), author, filter)
.await
}
async fn send_validation_receipts(
&self,
to_agent: AgentPubKey,
receipts: ValidationReceiptBundle,
) -> actor::HolochainP2pResult<()> {
self.sender
.send_validation_receipts((*self.dna_hash).clone(), to_agent, receipts)
.await
}
async fn authority_for_hash(
&self,
dht_hash: holo_hash::OpBasis,
) -> actor::HolochainP2pResult<bool> {
self.sender
.authority_for_hash((*self.dna_hash).clone(), dht_hash)
.await
}
async fn countersigning_session_negotiation(
&self,
agents: Vec<AgentPubKey>,
message: event::CountersigningSessionNegotiationMessage,
) -> actor::HolochainP2pResult<()> {
self.sender
.countersigning_session_negotiation((*self.dna_hash).clone(), agents, message)
.await
}
async fn new_integrated_data(&self) -> actor::HolochainP2pResult<()> {
self.sender
.new_integrated_data((*self.dna_hash).clone())
.await
}
fn chc(&self) -> Option<ChcImpl> {
self.chc.clone()
}
}
pub use kitsune_p2p::dht;
pub use kitsune_p2p::dht_arc;
mod test;