35
35
//! well, without going through [`client`](crate::client::Iroh))
36
36
//!
37
37
//! To shut down the node, call [`Node::shutdown`].
38
- use std:: collections:: { BTreeMap , BTreeSet } ;
38
+ use std:: collections:: BTreeSet ;
39
39
use std:: fmt:: Debug ;
40
+ use std:: marker:: PhantomData ;
40
41
use std:: net:: SocketAddr ;
41
42
use std:: path:: { Path , PathBuf } ;
42
43
use std:: sync:: Arc ;
@@ -47,14 +48,14 @@ use futures_lite::StreamExt;
47
48
use futures_util:: future:: MapErr ;
48
49
use futures_util:: future:: Shared ;
49
50
use iroh_base:: key:: PublicKey ;
51
+ use iroh_blobs:: protocol:: Closed ;
50
52
use iroh_blobs:: store:: Store as BaoStore ;
51
53
use iroh_blobs:: util:: local_pool:: { LocalPool , LocalPoolHandle } ;
52
- use iroh_blobs:: { downloader:: Downloader , protocol:: Closed } ;
53
- use iroh_blobs:: { HashAndFormat , TempTag } ;
54
- use iroh_gossip:: net:: Gossip ;
54
+ use iroh_docs:: net:: DOCS_ALPN ;
55
+ use iroh_gossip:: net:: { Gossip , GOSSIP_ALPN } ;
55
56
use iroh_net:: endpoint:: { DirectAddrsStream , RemoteInfo } ;
56
- use iroh_net:: key:: SecretKey ;
57
57
use iroh_net:: { AddrInfo , Endpoint , NodeAddr } ;
58
+ use protocol:: BlobsProtocol ;
58
59
use quic_rpc:: transport:: ServerEndpoint as _;
59
60
use quic_rpc:: RpcServer ;
60
61
use tokio:: task:: { JoinError , JoinSet } ;
@@ -64,7 +65,6 @@ use tracing::{debug, error, info, info_span, trace, warn, Instrument};
64
65
65
66
use crate :: node:: nodes_storage:: store_node_addrs;
66
67
use crate :: node:: { docs:: DocsEngine , protocol:: ProtocolMap } ;
67
- use crate :: rpc_protocol:: blobs:: BatchId ;
68
68
69
69
mod builder;
70
70
mod docs;
@@ -118,70 +118,14 @@ pub(crate) type JoinErrToStr = Box<dyn Fn(JoinError) -> String + Send + Sync + '
118
118
119
119
#[ derive( derive_more:: Debug ) ]
120
120
struct NodeInner < D > {
121
- db : D ,
121
+ db : PhantomData < D > ,
122
122
rpc_addr : Option < SocketAddr > ,
123
- docs : Option < DocsEngine > ,
124
123
endpoint : Endpoint ,
125
- gossip : Gossip ,
126
- secret_key : SecretKey ,
127
124
cancel_token : CancellationToken ,
128
125
client : crate :: client:: Iroh ,
129
- downloader : Downloader ,
130
- blob_batches : tokio:: sync:: Mutex < BlobBatches > ,
131
126
local_pool_handle : LocalPoolHandle ,
132
127
}
133
128
134
- /// Keeps track of all the currently active batch operations of the blobs api.
135
- #[ derive( Debug , Default ) ]
136
- struct BlobBatches {
137
- /// Currently active batches
138
- batches : BTreeMap < BatchId , BlobBatch > ,
139
- /// Used to generate new batch ids.
140
- max : u64 ,
141
- }
142
-
143
- /// A single batch of blob operations
144
- #[ derive( Debug , Default ) ]
145
- struct BlobBatch {
146
- /// The tags in this batch.
147
- tags : BTreeMap < HashAndFormat , Vec < TempTag > > ,
148
- }
149
-
150
- impl BlobBatches {
151
- /// Create a new unique batch id.
152
- fn create ( & mut self ) -> BatchId {
153
- let id = self . max ;
154
- self . max += 1 ;
155
- BatchId ( id)
156
- }
157
-
158
- /// Store a temp tag in a batch identified by a batch id.
159
- fn store ( & mut self , batch : BatchId , tt : TempTag ) {
160
- let entry = self . batches . entry ( batch) . or_default ( ) ;
161
- entry. tags . entry ( tt. hash_and_format ( ) ) . or_default ( ) . push ( tt) ;
162
- }
163
-
164
- /// Remove a tag from a batch.
165
- fn remove_one ( & mut self , batch : BatchId , content : & HashAndFormat ) -> Result < ( ) > {
166
- if let Some ( batch) = self . batches . get_mut ( & batch) {
167
- if let Some ( tags) = batch. tags . get_mut ( content) {
168
- tags. pop ( ) ;
169
- if tags. is_empty ( ) {
170
- batch. tags . remove ( content) ;
171
- }
172
- return Ok ( ( ) ) ;
173
- }
174
- }
175
- // this can happen if we try to upgrade a tag from an expired batch
176
- anyhow:: bail!( "tag not found in batch" ) ;
177
- }
178
-
179
- /// Remove an entire batch.
180
- fn remove ( & mut self , batch : BatchId ) {
181
- self . batches . remove ( & batch) ;
182
- }
183
- }
184
-
185
129
/// In memory node.
186
130
pub type MemNode = Node < iroh_blobs:: store:: mem:: Store > ;
187
131
@@ -245,7 +189,7 @@ impl<D: BaoStore> Node<D> {
245
189
246
190
/// Returns the [`PublicKey`] of the node.
247
191
pub fn node_id ( & self ) -> PublicKey {
248
- self . inner . secret_key . public ( )
192
+ self . inner . endpoint . secret_key ( ) . public ( )
249
193
}
250
194
251
195
/// Return a client to control this node over an in-memory channel.
@@ -344,32 +288,40 @@ impl<D: iroh_blobs::store::Store> NodeInner<D> {
344
288
let external_rpc = RpcServer :: new ( external_rpc) ;
345
289
let internal_rpc = RpcServer :: new ( internal_rpc) ;
346
290
291
+ let gossip = protocols
292
+ . get_typed :: < Gossip > ( GOSSIP_ALPN )
293
+ . expect ( "missing gossip" ) ;
294
+
347
295
// TODO(frando): I think this is not needed as we do the same in a task just below.
348
296
// forward the initial endpoints to the gossip protocol.
349
297
// it may happen the the first endpoint update callback is missed because the gossip cell
350
298
// is only initialized once the endpoint is fully bound
351
299
if let Some ( direct_addresses) = self . endpoint . direct_addresses ( ) . next ( ) . await {
352
300
debug ! ( me = ?self . endpoint. node_id( ) , "gossip initial update: {direct_addresses:?}" ) ;
353
- self . gossip . update_direct_addresses ( & direct_addresses) . ok ( ) ;
301
+ gossip. update_direct_addresses ( & direct_addresses) . ok ( ) ;
354
302
}
355
303
356
304
// Spawn a task for the garbage collection.
357
305
if let GcPolicy :: Interval ( gc_period) = gc_policy {
358
- let inner = self . clone ( ) ;
306
+ let protocols = protocols . clone ( ) ;
359
307
let handle = local_pool. spawn ( move || async move {
360
- let inner2 = inner. clone ( ) ;
361
- inner
362
- . db
308
+ let docs_engine = protocols. get_typed :: < DocsEngine > ( DOCS_ALPN ) ;
309
+ let blobs = protocols
310
+ . get_typed :: < BlobsProtocol < D > > ( iroh_blobs:: protocol:: ALPN )
311
+ . expect ( "missing blobs" ) ;
312
+
313
+ blobs
314
+ . store ( )
363
315
. gc_run (
364
316
iroh_blobs:: store:: GcConfig {
365
317
period : gc_period,
366
318
done_callback : gc_done_callback,
367
319
} ,
368
320
move || {
369
- let inner2 = inner2 . clone ( ) ;
321
+ let docs_engine = docs_engine . clone ( ) ;
370
322
async move {
371
323
let mut live = BTreeSet :: default ( ) ;
372
- if let Some ( docs) = & inner2 . docs {
324
+ if let Some ( docs) = docs_engine {
373
325
let doc_hashes = match docs. sync . content_hashes ( ) . await {
374
326
Ok ( hashes) => hashes,
375
327
Err ( err) => {
@@ -449,7 +401,7 @@ impl<D: iroh_blobs::store::Store> NodeInner<D> {
449
401
join_set. spawn ( async move {
450
402
let mut stream = inner. endpoint . direct_addresses ( ) ;
451
403
while let Some ( eps) = stream. next ( ) . await {
452
- if let Err ( err) = inner . gossip . update_direct_addresses ( & eps) {
404
+ if let Err ( err) = gossip. update_direct_addresses ( & eps) {
453
405
warn ! ( "Failed to update direct addresses for gossip: {err:?}" ) ;
454
406
}
455
407
}
@@ -468,7 +420,7 @@ impl<D: iroh_blobs::store::Store> NodeInner<D> {
468
420
request = external_rpc. accept( ) => {
469
421
match request {
470
422
Ok ( accepting) => {
471
- rpc:: Handler :: spawn_rpc_request( self . clone( ) , & mut join_set, accepting) ;
423
+ rpc:: Handler :: spawn_rpc_request( self . clone( ) , & mut join_set, accepting, protocols . clone ( ) ) ;
472
424
}
473
425
Err ( e) => {
474
426
info!( "rpc request error: {:?}" , e) ;
@@ -479,7 +431,7 @@ impl<D: iroh_blobs::store::Store> NodeInner<D> {
479
431
request = internal_rpc. accept( ) => {
480
432
match request {
481
433
Ok ( accepting) => {
482
- rpc:: Handler :: spawn_rpc_request( self . clone( ) , & mut join_set, accepting) ;
434
+ rpc:: Handler :: spawn_rpc_request( self . clone( ) , & mut join_set, accepting, protocols . clone ( ) ) ;
483
435
}
484
436
Err ( e) => {
485
437
info!( "internal rpc request error: {:?}" , e) ;
@@ -533,18 +485,6 @@ impl<D: iroh_blobs::store::Store> NodeInner<D> {
533
485
async fn shutdown ( & self , protocols : Arc < ProtocolMap > ) {
534
486
let error_code = Closed :: ProviderTerminating ;
535
487
536
- // Shutdown future for the docs engine, if enabled.
537
- let docs_shutdown = {
538
- let docs = self . docs . clone ( ) ;
539
- async move {
540
- if let Some ( docs) = docs {
541
- docs. shutdown ( ) . await
542
- } else {
543
- Ok ( ( ) )
544
- }
545
- }
546
- } ;
547
-
548
488
// We ignore all errors during shutdown.
549
489
let _ = tokio:: join!(
550
490
// Close the endpoint.
@@ -554,10 +494,6 @@ impl<D: iroh_blobs::store::Store> NodeInner<D> {
554
494
self . endpoint
555
495
. clone( )
556
496
. close( error_code. into( ) , error_code. reason( ) ) ,
557
- // Shutdown docs engine.
558
- docs_shutdown,
559
- // Shutdown blobs store engine.
560
- self . db. shutdown( ) ,
561
497
// Shutdown protocol handlers.
562
498
protocols. shutdown( ) ,
563
499
) ;
@@ -636,7 +572,7 @@ mod tests {
636
572
use bytes:: Bytes ;
637
573
use iroh_base:: node_addr:: AddrInfoOptions ;
638
574
use iroh_blobs:: { provider:: AddProgress , util:: SetTagOption , BlobFormat } ;
639
- use iroh_net:: { relay:: RelayMode , test_utils:: DnsPkarrServer , NodeAddr } ;
575
+ use iroh_net:: { key :: SecretKey , relay:: RelayMode , test_utils:: DnsPkarrServer , NodeAddr } ;
640
576
641
577
use crate :: client:: blobs:: { AddOutcome , WrapOption } ;
642
578
0 commit comments