@@ -131,10 +131,15 @@ impl ThresholdKey {
131
131
132
132
/// `DecryptionKeyCell` is a thread-safe container for an optional `DecryptionKey`
133
133
/// that allows asynchronous notification when the key is set.
134
- #[ derive( Debug , Clone , Default ) ]
134
+ #[ derive( Debug , Default ) ]
135
135
pub struct ThresholdKeyCell {
136
- key : Arc < RwLock < Option < ThresholdKey > > > ,
137
- notify : Arc < Notify > ,
136
+ inner : Arc < ThresholdKeyCellInner > ,
137
+ }
138
+
139
+ #[ derive( Debug , Default ) ]
140
+ struct ThresholdKeyCellInner {
141
+ key : RwLock < Option < ThresholdKey > > ,
142
+ notify : Notify ,
138
143
}
139
144
140
145
impl ThresholdKeyCell {
@@ -143,25 +148,25 @@ impl ThresholdKeyCell {
143
148
}
144
149
145
150
pub fn set ( & self , key : ThresholdKey ) {
146
- * self . key . write ( ) = Some ( key) ;
147
- self . notify . notify_waiters ( ) ;
151
+ * self . inner . key . write ( ) = Some ( key) ;
152
+ self . inner . notify . notify_waiters ( ) ;
148
153
}
149
154
150
155
pub fn get ( & self ) -> Option < ThresholdKey > {
151
- ( * self . key . read ( ) ) . clone ( )
156
+ ( * self . inner . key . read ( ) ) . clone ( )
152
157
}
153
158
154
159
pub fn enc_key ( & self ) -> Option < ThresholdEncKey > {
155
160
self . get ( ) . map ( |sk| sk. pubkey )
156
161
}
157
162
158
163
pub fn get_ref ( & self ) -> impl Deref < Target = Option < ThresholdKey > > {
159
- self . key . read ( )
164
+ self . inner . key . read ( )
160
165
}
161
166
162
167
pub async fn read ( & self ) -> ThresholdKey {
163
168
loop {
164
- let fut = self . notify . notified ( ) ;
169
+ let fut = self . inner . notify . notified ( ) ;
165
170
if let Some ( k) = self . get ( ) {
166
171
return k;
167
172
}
@@ -170,6 +175,14 @@ impl ThresholdKeyCell {
170
175
}
171
176
}
172
177
178
+ impl Clone for ThresholdKeyCell {
179
+ fn clone ( & self ) -> Self {
180
+ Self {
181
+ inner : self . inner . clone ( ) ,
182
+ }
183
+ }
184
+ }
185
+
173
186
/// A small, non-empty collection of KeyStores.
174
187
#[ derive( Debug , Default , Clone ) ]
175
188
#[ allow( clippy:: len_without_is_empty) ]
@@ -280,10 +293,10 @@ impl<const N: usize> From<KeyStore> for KeyStoreVec<N> {
280
293
281
294
/// A `KeyStore` with committee information and public keys used in the DKG or key resharing
282
295
#[ derive( Debug , Clone ) ]
283
- pub struct KeyStore ( Arc < Inner > ) ;
296
+ pub struct KeyStore ( Arc < KeyStoreInner > ) ;
284
297
285
298
#[ derive( Debug ) ]
286
- struct Inner {
299
+ struct KeyStoreInner {
287
300
committee : Committee ,
288
301
keys : BTreeMap < KeyId , DkgEncKey > ,
289
302
}
@@ -294,7 +307,7 @@ impl KeyStore {
294
307
I : IntoIterator < Item = ( T , DkgEncKey ) > ,
295
308
T : Into < KeyId > ,
296
309
{
297
- let this = Self ( Arc :: new ( Inner {
310
+ let this = Self ( Arc :: new ( KeyStoreInner {
298
311
committee : c,
299
312
keys : keys. into_iter ( ) . map ( |( i, k) | ( i. into ( ) , k) ) . collect ( ) ,
300
313
} ) ) ;
@@ -446,20 +459,19 @@ impl DkgAccumulator {
446
459
}
447
460
448
461
/// Try to finalize the accumulator into a subset if enough bundles are collected.
449
- pub fn try_finalize ( & mut self ) -> Option < DkgSubset > {
462
+ /// Returns a reference to the internal data to avoid cloning the bundles.
463
+ pub fn try_finalize ( & self ) -> Option < DkgSubsetRef < ' _ > > {
450
464
if self . complete {
451
465
let combkey = match & self . mode {
452
466
AccumulatorMode :: Dkg => None ,
453
467
AccumulatorMode :: Resharing ( combkey) => Some ( combkey. clone ( ) ) ,
454
468
} ;
455
469
456
- let subset = DkgSubset {
470
+ Some ( DkgSubsetRef {
457
471
committee_id : self . committee ( ) . id ( ) ,
458
- bundles : self . bundles . clone ( ) ,
472
+ bundles : & self . bundles ,
459
473
combkey,
460
- } ;
461
-
462
- Some ( subset)
474
+ } )
463
475
} else {
464
476
None
465
477
}
@@ -488,6 +500,14 @@ pub struct DkgSubset {
488
500
combkey : Option < ThresholdCombKey > ,
489
501
}
490
502
503
+ /// A reference-based version of DkgSubset to avoid cloning bundles.
504
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
505
+ pub struct DkgSubsetRef < ' a > {
506
+ committee_id : CommitteeId ,
507
+ bundles : & ' a [ DkgBundle ] ,
508
+ combkey : Option < ThresholdCombKey > ,
509
+ }
510
+
491
511
impl DkgSubset {
492
512
/// Create a new subset with DKG bundles.
493
513
pub fn new_dkg ( committee_id : CommitteeId , bundles : Vec < DkgBundle > ) -> Self {
@@ -536,6 +556,27 @@ impl DkgSubset {
536
556
self . combkey . is_some ( )
537
557
}
538
558
559
+ /// Convert this DkgSubset to a DkgSubsetRef.
560
+ pub fn as_ref ( & self ) -> DkgSubsetRef < ' _ > {
561
+ DkgSubsetRef {
562
+ committee_id : self . committee_id ,
563
+ bundles : & self . bundles ,
564
+ combkey : self . combkey . as_ref ( ) . cloned ( ) ,
565
+ }
566
+ }
567
+
568
+ /// Extract the new threshold decryption key from the subset.
569
+ pub fn extract_key (
570
+ & self ,
571
+ curr : & KeyStore ,
572
+ dkg_sk : & LabeledDkgDecKey ,
573
+ prev : Option < & KeyStore > ,
574
+ ) -> anyhow:: Result < ThresholdKey > {
575
+ self . as_ref ( ) . extract_key ( curr, dkg_sk, prev)
576
+ }
577
+ }
578
+
579
+ impl < ' a > DkgSubsetRef < ' a > {
539
580
/// Extract the new threshold decryption key from the subset.
540
581
pub fn extract_key (
541
582
& self ,
@@ -547,7 +588,7 @@ impl DkgSubset {
547
588
548
589
match & self . combkey {
549
590
None => {
550
- let mut dealings_iter = ResultIter :: new ( self . bundles ( ) . iter ( ) . map ( |b| {
591
+ let mut dealings_iter = ResultIter :: new ( self . bundles . iter ( ) . map ( |b| {
551
592
vess. decrypt_share ( curr. committee ( ) , dkg_sk, b. vess_ct ( ) , DKG_AAD )
552
593
. map ( |s| ( s, b. comm ( ) . clone ( ) ) )
553
594
} ) ) ;
@@ -568,7 +609,7 @@ impl DkgSubset {
568
609
} ;
569
610
570
611
let dealings: Vec < _ > = self
571
- . bundles ( )
612
+ . bundles
572
613
. iter ( )
573
614
. map ( |b| {
574
615
let node_idx = b. origin ( ) . 0 . into ( ) ;
0 commit comments