#![deny(missing_docs)]
use holo_hash::*;
use holochain_chc::ChcImpl;
use holochain_serialized_bytes::prelude::*;
use holochain_types::prelude::*;
use kitsune2_api::{AgentInfoSigned, BoxFut};
use kitsune2_api::{SpaceId, StoredOp};
use mockall::automock;
use std::sync::Arc;
use tracing::Instrument;
mod types;
pub use types::*;
mod spawn;
pub use spawn::*;
#[cfg(feature = "test_utils")]
pub use test::stub_network;
mod peer_meta_store;
pub use peer_meta_store::*;
mod local_agent;
pub use local_agent::*;
mod op_store;
pub use op_store::*;
mod metrics;
#[automock]
#[allow(clippy::too_many_arguments)]
#[async_trait::async_trait]
pub trait HolochainP2pDnaT: Send + Sync + 'static {
fn dna_hash(&self) -> DnaHash;
async fn join(
&self,
agent: AgentPubKey,
maybe_agent_info: Option<AgentInfoSigned>,
) -> HolochainP2pResult<()>;
async fn leave(&self, agent: AgentPubKey) -> HolochainP2pResult<()>;
async fn new_integrated_data(&self, ops: Vec<StoredOp>) -> HolochainP2pResult<()>;
#[allow(clippy::too_many_arguments)]
async fn call_remote(
&self,
to_agent: AgentPubKey,
zome_call_params_serialized: ExternIO,
signature: Signature,
) -> HolochainP2pResult<SerializedBytes>;
async fn send_remote_signal(
&self,
to_agent_list: Vec<(AgentPubKey, ExternIO, Signature)>,
) -> HolochainP2pResult<()>;
#[allow(clippy::ptr_arg)]
async fn publish(
&self,
request_validation_receipt: bool,
basis_hash: holo_hash::OpBasis,
source: AgentPubKey,
op_hash_list: Vec<DhtOpHash>,
timeout_ms: Option<u64>,
reflect_ops: Option<Vec<DhtOp>>,
) -> HolochainP2pResult<()>;
async fn publish_countersign(
&self,
basis_hash: holo_hash::OpBasis,
op: ChainOp,
) -> HolochainP2pResult<()>;
async fn get(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetOptions,
) -> HolochainP2pResult<Vec<WireOps>>;
async fn get_meta(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetMetaOptions,
) -> HolochainP2pResult<Vec<MetadataSet>>;
async fn get_links(
&self,
link_key: WireLinkKey,
options: actor::GetLinksOptions,
) -> HolochainP2pResult<Vec<WireLinkOps>>;
async fn count_links(&self, query: WireLinkQuery) -> HolochainP2pResult<CountLinksResponse>;
async fn get_agent_activity(
&self,
agent: AgentPubKey,
query: ChainQueryFilter,
options: actor::GetActivityOptions,
) -> HolochainP2pResult<Vec<AgentActivityResponse>>;
async fn must_get_agent_activity(
&self,
author: AgentPubKey,
filter: holochain_zome_types::chain::ChainFilter,
) -> HolochainP2pResult<Vec<MustGetAgentActivityResponse>>;
async fn send_validation_receipts(
&self,
to_agent: AgentPubKey,
receipts: ValidationReceiptBundle,
) -> HolochainP2pResult<()>;
async fn authority_for_hash(&self, basis: holo_hash::OpBasis) -> HolochainP2pResult<bool>;
async fn countersigning_session_negotiation(
&self,
agents: Vec<AgentPubKey>,
message: event::CountersigningSessionNegotiationMessage,
) -> HolochainP2pResult<()>;
async fn target_arcs(&self) -> HolochainP2pResult<Vec<kitsune2_api::DhtArc>>;
fn chc(&self) -> Option<ChcImpl>;
}
pub type DynHolochainP2pDna = Arc<dyn HolochainP2pDnaT>;
#[derive(Clone)]
pub struct HolochainP2pDna {
sender: actor::DynHcP2p,
dna_hash: Arc<DnaHash>,
chc: Option<ChcImpl>,
}
impl HolochainP2pDna {
pub fn new(hc_p2p: actor::DynHcP2p, dna_hash: DnaHash, chc: Option<ChcImpl>) -> Self {
Self {
sender: hc_p2p,
dna_hash: dna_hash.into(),
chc,
}
}
}
#[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>,
) -> HolochainP2pResult<()> {
self.sender
.join((*self.dna_hash).clone(), agent, maybe_agent_info)
.await
}
async fn leave(&self, agent: AgentPubKey) -> HolochainP2pResult<()> {
self.sender.leave((*self.dna_hash).clone(), agent).await
}
async fn new_integrated_data(&self, ops: Vec<StoredOp>) -> HolochainP2pResult<()> {
self.sender
.new_integrated_data(self.dna_hash.to_k2_space(), ops)
.await
}
async fn call_remote(
&self,
to_agent: AgentPubKey,
zome_call_params_serialized: ExternIO,
signature: Signature,
) -> HolochainP2pResult<SerializedBytes> {
self.sender
.call_remote(
(*self.dna_hash).clone(),
to_agent,
zome_call_params_serialized,
signature,
)
.await
}
async fn send_remote_signal(
&self,
to_agent_list: Vec<(AgentPubKey, ExternIO, Signature)>,
) -> HolochainP2pResult<()> {
self.sender
.send_remote_signal((*self.dna_hash).clone(), to_agent_list)
.await
}
async fn publish(
&self,
request_validation_receipt: bool,
basis_hash: holo_hash::OpBasis,
source: AgentPubKey,
op_hash_list: Vec<DhtOpHash>,
timeout_ms: Option<u64>,
reflect_ops: Option<Vec<DhtOp>>,
) -> HolochainP2pResult<()> {
self.sender
.publish(
(*self.dna_hash).clone(),
request_validation_receipt,
basis_hash,
source,
op_hash_list,
timeout_ms,
reflect_ops,
)
.await
}
async fn publish_countersign(
&self,
basis_hash: holo_hash::OpBasis,
op: ChainOp,
) -> HolochainP2pResult<()> {
self.sender
.publish_countersign((*self.dna_hash).clone(), basis_hash, op)
.await
}
async fn get(
&self,
dht_hash: holo_hash::AnyDhtHash,
options: actor::GetOptions,
) -> 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,
) -> 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,
) -> HolochainP2pResult<Vec<WireLinkOps>> {
self.sender
.get_links((*self.dna_hash).clone(), link_key, options)
.await
}
async fn count_links(&self, query: WireLinkQuery) -> 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,
) -> HolochainP2pResult<Vec<AgentActivityResponse>> {
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,
) -> 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,
) -> 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) -> 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,
) -> HolochainP2pResult<()> {
self.sender
.countersigning_session_negotiation((*self.dna_hash).clone(), agents, message)
.await
}
async fn target_arcs(&self) -> HolochainP2pResult<Vec<kitsune2_api::DhtArc>> {
self.sender.target_arcs((*self.dna_hash).clone()).await
}
fn chc(&self) -> Option<ChcImpl> {
self.chc.clone()
}
}
#[allow(unused)]
#[cfg(any(test, feature = "test_utils"))]
mod test;