kitsune_p2p/
host_api.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
use crate::dht::prelude::ArqSet;
use kitsune_p2p_fetch::{OpHashSized, RoughSized, TransferMethod};
use kitsune_p2p_timestamp::Timestamp;
use must_future::MustBoxFuture;
use std::sync::Arc;

use kitsune_p2p_types::{
    bin_types::KitsuneSpace,
    dependencies::lair_keystore_api,
    dht::{
        region::{Region, RegionCoords},
        region_set::RegionSetLtcs,
        spacetime::Topology,
    },
    dht_arc::DhtArcSet,
    KOpData, KOpHash,
};

use crate::event::GetAgentInfoSignedEvt;

/// A boxed future result with dynamic error type
pub type KitsuneHostResult<'a, T> =
    MustBoxFuture<'a, Result<T, Box<dyn Send + Sync + std::error::Error>>>;

/// The interface to be implemented by the host, which handles various requests
/// for data
pub trait KitsuneHost: 'static + Send + Sync + std::fmt::Debug {
    /// We are requesting a block.
    fn block(&self, input: kitsune_p2p_block::Block) -> KitsuneHostResult<()>;

    /// We are requesting an unblock.
    fn unblock(&self, input: kitsune_p2p_block::Block) -> KitsuneHostResult<()>;

    /// We want to know if a target is blocked.
    fn is_blocked(
        &self,
        input: kitsune_p2p_block::BlockTargetId,
        timestamp: Timestamp,
    ) -> KitsuneHostResult<bool>;

    /// We need to get previously stored agent info.
    fn get_agent_info_signed(
        &self,
        input: GetAgentInfoSignedEvt,
    ) -> KitsuneHostResult<Option<crate::types::agent_store::AgentInfoSigned>>;

    /// Remove an agent info from storage
    fn remove_agent_info_signed(&self, input: GetAgentInfoSignedEvt) -> KitsuneHostResult<bool>;

    /// Extrapolated Peer Coverage.
    fn peer_extrapolated_coverage(
        &self,
        space: Arc<KitsuneSpace>,
        dht_arc_set: DhtArcSet,
    ) -> KitsuneHostResult<Vec<f64>>;

    /// Query aggregate dht op data to form an LTCS set of region data.
    fn query_region_set(
        &self,
        space: Arc<KitsuneSpace>,
        arq_set: ArqSet,
    ) -> KitsuneHostResult<RegionSetLtcs>;

    /// Given an input list of regions, return a list of equal or greater length
    /// such that each region's size is less than the `size_limit`, by recursively
    /// subdividing regions which are over the size limit.
    fn query_size_limited_regions(
        &self,
        space: Arc<KitsuneSpace>,
        size_limit: u32,
        regions: Vec<Region>,
    ) -> KitsuneHostResult<Vec<Region>>;

    /// Get all op hashes within a region
    fn query_op_hashes_by_region(
        &self,
        space: Arc<KitsuneSpace>,
        region: RegionCoords,
    ) -> KitsuneHostResult<Vec<OpHashSized>>;

    /// Record a set of metric records.
    fn record_metrics(
        &self,
        space: Arc<KitsuneSpace>,
        records: Vec<MetricRecord>,
    ) -> KitsuneHostResult<()>;

    /// Get the quantum Topology associated with this Space.
    fn get_topology(&self, space: Arc<KitsuneSpace>) -> KitsuneHostResult<Topology>;

    /// Hashing function to get an op_hash from op_data.
    fn op_hash(&self, op_data: KOpData) -> KitsuneHostResult<KOpHash>;

    /// Check which hashes we have data for.
    fn check_op_data(
        &self,
        space: Arc<KitsuneSpace>,
        op_hash_list: Vec<KOpHash>,
        _context: Option<kitsune_p2p_fetch::FetchContext>,
    ) -> KitsuneHostResult<Vec<bool>> {
        let _space = space;
        futures::FutureExt::boxed(
            async move { Ok(op_hash_list.into_iter().map(|_| false).collect()) },
        )
        .into()
    }

    /// Do something whenever a batch of op hashes was received and stored in the FetchPool
    // NOTE: currently only needed for aitia, could be removed and the aitia log could be created
    // directly in kitsune.
    fn handle_op_hash_received(
        &self,
        _space: &KitsuneSpace,
        _op_hash: &RoughSized<KOpHash>,
        _transfer_method: TransferMethod,
    ) {
    }

    /// Do something whenever a batch of op hashes was sent to another node
    // NOTE: currently only needed for aitia, could be removed and the aitia log could be created
    // directly in kitsune.
    fn handle_op_hash_transmitted(
        &self,
        _space: &KitsuneSpace,
        _op_hash: &RoughSized<KOpHash>,
        _transfer_method: TransferMethod,
    ) {
    }

    /// Get the lair "tag" identifying the id seed to use for crypto signing.
    /// (this is currently only used in tx5/WebRTC if that feature is enabled.)
    fn lair_tag(&self) -> Option<Arc<str>> {
        None
    }

    /// Get the lair client to use as the backend keystore.
    /// (this is currently only used in tx5/WebRTC if that feature is enabled.)
    fn lair_client(&self) -> Option<lair_keystore_api::LairClient> {
        None
    }
}

/// Trait object for the host interface
pub type HostApi = std::sync::Arc<dyn KitsuneHost>;

/// A HostApi paired with a ghost_actor sender (legacy)
/// When all legacy functions have been moved to the API,
/// this type can be replaced by `HostApi`.
#[derive(Clone, Debug, derive_more::Constructor, derive_more::Deref, derive_more::Into)]
pub struct HostApiLegacy {
    /// The new API
    #[deref]
    pub api: HostApi,
    /// The old ghost_actor sender based API
    pub legacy: futures::channel::mpsc::Sender<crate::event::KitsuneP2pEvent>,
}

// Test-only stub which mostly panics
#[cfg(any(test, feature = "test_utils"))]
mod host_stub;
#[cfg(any(test, feature = "test_utils"))]
pub use host_stub::*;

#[cfg(any(test, feature = "test_utils"))]
mod host_default_error;
#[cfg(any(test, feature = "test_utils"))]
pub use host_default_error::*;
use kitsune_p2p_types::metrics::MetricRecord;