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
//! An iroh node that just has the blobs transport
use std::{path::Path, sync::Arc};

use iroh_net::{Endpoint, NodeAddr, NodeId};
use iroh_router::Router;

use crate::{
    downloader::Downloader,
    net_protocol::Blobs,
    provider::{CustomEventSender, EventSender},
    rpc::client::blobs,
    util::local_pool::LocalPool,
};

/// An iroh node that just has the blobs transport
#[derive(Debug)]

pub struct Node {
    router: iroh_router::Router,
    client: blobs::MemClient,
    _local_pool: LocalPool,
}

/// An iroh node builder
#[derive(Debug)]
pub struct Builder<S> {
    store: S,
    events: EventSender,
    endpoint: Option<iroh_net::endpoint::Builder>,
}

impl<S: crate::store::Store> Builder<S> {
    /// Sets the event sender
    pub fn blobs_events(self, events: impl CustomEventSender) -> Self {
        Self {
            events: events.into(),
            ..self
        }
    }

    /// Set an endpoint builder
    pub fn endpoint(self, endpoint: iroh_net::endpoint::Builder) -> Self {
        Self {
            endpoint: Some(endpoint),
            ..self
        }
    }

    /// Build the node
    pub async fn build(self) -> anyhow::Result<Node> {
        let store = self.store;
        let events = self.events;
        let endpoint = self
            .endpoint
            .unwrap_or_else(|| Endpoint::builder().discovery_n0())
            .bind()
            .await?;
        let local_pool = LocalPool::single();
        let mut router = Router::builder(endpoint.clone());

        // Setup blobs
        let downloader =
            Downloader::new(store.clone(), endpoint.clone(), local_pool.handle().clone());
        let blobs = Arc::new(Blobs::new_with_events(
            store.clone(),
            local_pool.handle().clone(),
            events,
            downloader,
            endpoint.clone(),
        ));
        router = router.accept(crate::protocol::ALPN.to_vec(), blobs.clone());

        // Build the router
        let router = router.spawn().await?;

        // Setup RPC
        let client = blobs.client();
        Ok(Node {
            router,
            client,
            _local_pool: local_pool,
        })
    }
}

impl Node {
    /// Creates a new node with memory storage
    pub fn memory() -> Builder<crate::store::mem::Store> {
        Builder {
            store: crate::store::mem::Store::new(),
            events: Default::default(),
            endpoint: None,
        }
    }

    /// Creates a new node with persistent storage
    pub async fn persistent(
        path: impl AsRef<Path>,
    ) -> anyhow::Result<Builder<crate::store::fs::Store>> {
        Ok(Builder {
            store: crate::store::fs::Store::load(path).await?,
            events: Default::default(),
            endpoint: None,
        })
    }

    /// Returns the endpoint
    pub fn endpoint(&self) -> &Endpoint {
        self.router.endpoint()
    }

    /// Returns the node id
    pub fn node_id(&self) -> NodeId {
        self.router.endpoint().node_id()
    }

    /// Returns the node address
    pub async fn node_addr(&self) -> anyhow::Result<NodeAddr> {
        self.router.endpoint().node_addr().await
    }

    /// Shuts down the node
    pub async fn shutdown(self) -> anyhow::Result<()> {
        self.router.shutdown().await
    }

    /// Returns an in-memory blobs client
    pub fn blobs(&self) -> &blobs::MemClient {
        &self.client
    }
}