26
26
//! Blocks from future steps will be either deferred or rejected depending on how
27
27
//! far in the future they are.
28
28
29
- use std:: { sync:: Arc , time:: Duration , thread} ;
29
+ use std:: { sync:: Arc , time:: Duration , thread, marker :: PhantomData , hash :: Hash , fmt :: Debug } ;
30
30
31
- use parity_codec:: Encode ;
31
+ use parity_codec:: { Encode , Decode } ;
32
32
use consensus_common:: {
33
33
Authorities , BlockImport , Environment , Proposer , ForkChoiceStrategy
34
34
} ;
@@ -41,7 +41,7 @@ use runtime_primitives::{generic, generic::BlockId, Justification};
41
41
use runtime_primitives:: traits:: {
42
42
Block , Header , Digest , DigestItemFor , DigestItem , ProvideRuntimeApi
43
43
} ;
44
- use primitives:: { ed25519 , Pair } ;
44
+ use primitives:: Pair ;
45
45
use inherents:: { InherentDataProviders , InherentData , RuntimeString } ;
46
46
47
47
use futures:: { Stream , Future , IntoFuture , future} ;
@@ -60,8 +60,8 @@ pub use aura_slots::SlotDuration;
60
60
pub use aura_primitives:: * ;
61
61
pub use consensus_common:: SyncOracle ;
62
62
63
- type AuthorityId = ed25519 :: Public ;
64
- type Signature = ed25519 :: Signature ;
63
+ type AuthorityId < P > = < P as Pair > :: Public ;
64
+ type Signature < P > = < P as Pair > :: Signature ;
65
65
66
66
/// A handle to the network. This is generally implemented by providing some
67
67
/// handle to a gossip service or similar.
@@ -76,7 +76,9 @@ pub trait Network: Clone {
76
76
}
77
77
78
78
/// Get slot author for given block along with authorities.
79
- fn slot_author ( slot_num : u64 , authorities : & [ AuthorityId ] ) -> Option < AuthorityId > {
79
+ fn slot_author < P : Pair > ( slot_num : u64 , authorities : & [ AuthorityId < P > ] ) -> Option < AuthorityId < P > >
80
+ where P :: Public : Clone ,
81
+ {
80
82
if authorities. is_empty ( ) { return None }
81
83
82
84
let idx = slot_num % ( authorities. len ( ) as u64 ) ;
@@ -88,7 +90,7 @@ fn slot_author(slot_num: u64, authorities: &[AuthorityId]) -> Option<AuthorityId
88
90
this is a valid index; qed")
89
91
. clone ( ) ;
90
92
91
- Some ( current_author)
93
+ Some ( current_author. clone ( ) )
92
94
}
93
95
94
96
fn duration_now ( ) -> Option < Duration > {
@@ -110,25 +112,27 @@ fn inherent_to_common_error(err: RuntimeString) -> consensus_common::Error {
110
112
}
111
113
112
114
/// A digest item which is usable with aura consensus.
113
- pub trait CompatibleDigestItem : Sized {
115
+ pub trait CompatibleDigestItem < T : Pair > : Sized {
114
116
/// Construct a digest item which is a slot number and a signature on the
115
117
/// hash.
116
- fn aura_seal ( slot_number : u64 , signature : Signature ) -> Self ;
118
+ fn aura_seal ( slot_number : u64 , signature : Signature < T > ) -> Self ;
117
119
118
120
/// If this item is an Aura seal, return the slot number and signature.
119
- fn as_aura_seal ( & self ) -> Option < ( u64 , Signature ) > ;
121
+ fn as_aura_seal ( & self ) -> Option < ( u64 , Signature < T > ) > ;
120
122
}
121
123
122
- impl < Hash , AuthorityId > CompatibleDigestItem for generic:: DigestItem < Hash , AuthorityId , Signature > {
124
+ impl < T : Pair , Hash , AuthorityId > CompatibleDigestItem < T > for generic:: DigestItem < Hash , AuthorityId , Signature < T > >
125
+ where T :: Signature : Clone
126
+ {
123
127
/// Construct a digest item which is a slot number and a signature on the
124
128
/// hash.
125
- fn aura_seal ( slot_number : u64 , signature : Signature ) -> Self {
129
+ fn aura_seal ( slot_number : u64 , signature : Signature < T > ) -> Self {
126
130
generic:: DigestItem :: Seal ( slot_number, signature)
127
131
}
128
132
/// If this item is an Aura seal, return the slot number and signature.
129
- fn as_aura_seal ( & self ) -> Option < ( u64 , Signature ) > {
133
+ fn as_aura_seal ( & self ) -> Option < ( u64 , Signature < T > ) > {
130
134
match self {
131
- generic:: DigestItem :: Seal ( slot, ref sig) => Some ( ( * slot, sig . clone ( ) . into ( ) ) ) ,
135
+ generic:: DigestItem :: Seal ( slot, ref sig) => Some ( ( * slot, ( * sig ) . clone ( ) ) ) ,
132
136
_ => None
133
137
}
134
138
}
@@ -147,9 +151,9 @@ impl SlotCompatible for AuraSlotCompatible {
147
151
}
148
152
149
153
/// Start the aura worker in a separate thread.
150
- pub fn start_aura_thread < B , C , E , I , SO , Error , OnExit > (
154
+ pub fn start_aura_thread < B , C , E , I , P , SO , Error , OnExit > (
151
155
slot_duration : SlotDuration ,
152
- local_key : Arc < ed25519 :: Pair > ,
156
+ local_key : Arc < P > ,
153
157
client : Arc < C > ,
154
158
block_import : Arc < I > ,
155
159
env : Arc < E > ,
@@ -164,9 +168,11 @@ pub fn start_aura_thread<B, C, E, I, SO, Error, OnExit>(
164
168
<<E :: Proposer as Proposer < B > >:: Create as IntoFuture >:: Future : Send + ' static ,
165
169
I : BlockImport < B > + Send + Sync + ' static ,
166
170
Error : From < C :: Error > + From < I :: Error > + ' static ,
171
+ P : Pair + Send + Sync + ' static ,
172
+ P :: Public : Encode + Decode + Eq + Clone + Debug + Hash + Send + Sync + ' static ,
167
173
SO : SyncOracle + Send + Sync + Clone + ' static ,
168
174
OnExit : Future < Item =( ) , Error =( ) > + Send + ' static ,
169
- DigestItemFor < B > : CompatibleDigestItem + DigestItem < AuthorityId =AuthorityId > + ' static ,
175
+ DigestItemFor < B > : CompatibleDigestItem < P > + DigestItem < AuthorityId =AuthorityId < P > > + ' static ,
170
176
Error : :: std:: error:: Error + Send + From < :: consensus_common:: Error > + ' static ,
171
177
{
172
178
let worker = AuraWorker {
@@ -184,9 +190,9 @@ pub fn start_aura_thread<B, C, E, I, SO, Error, OnExit>(
184
190
}
185
191
186
192
/// Start the aura worker. The returned future should be run in a tokio runtime.
187
- pub fn start_aura < B , C , E , I , SO , Error , OnExit > (
193
+ pub fn start_aura < B , C , E , I , P , SO , Error , OnExit > (
188
194
slot_duration : SlotDuration ,
189
- local_key : Arc < ed25519 :: Pair > ,
195
+ local_key : Arc < P > ,
190
196
client : Arc < C > ,
191
197
block_import : Arc < I > ,
192
198
env : Arc < E > ,
@@ -201,8 +207,10 @@ pub fn start_aura<B, C, E, I, SO, Error, OnExit>(
201
207
<<E :: Proposer as Proposer < B > >:: Create as IntoFuture >:: Future : Send + ' static ,
202
208
I : BlockImport < B > + Send + Sync + ' static ,
203
209
Error : From < C :: Error > + From < I :: Error > ,
210
+ P : Pair + Send + Sync + ' static ,
211
+ P :: Public : Hash + Eq + Send + Sync + Clone + Debug + Encode + Decode + ' static ,
204
212
SO : SyncOracle + Send + Sync + Clone ,
205
- DigestItemFor < B > : CompatibleDigestItem + DigestItem < AuthorityId =AuthorityId > ,
213
+ DigestItemFor < B > : CompatibleDigestItem < P > + DigestItem < AuthorityId =AuthorityId < P > > ,
206
214
Error : :: std:: error:: Error + Send + ' static + From < :: consensus_common:: Error > ,
207
215
OnExit : Future < Item =( ) , Error =( ) > ,
208
216
{
@@ -219,24 +227,26 @@ pub fn start_aura<B, C, E, I, SO, Error, OnExit>(
219
227
)
220
228
}
221
229
222
- struct AuraWorker < C , E , I , SO > {
230
+ struct AuraWorker < C , E , I , P , SO > {
223
231
client : Arc < C > ,
224
232
block_import : Arc < I > ,
225
233
env : Arc < E > ,
226
- local_key : Arc < ed25519 :: Pair > ,
234
+ local_key : Arc < P > ,
227
235
sync_oracle : SO ,
228
236
inherent_data_providers : InherentDataProviders ,
229
237
}
230
238
231
- impl < B : Block , C , E , I , Error , SO > SlotWorker < B > for AuraWorker < C , E , I , SO > where
239
+ impl < B : Block , C , E , I , P , Error , SO > SlotWorker < B > for AuraWorker < C , E , I , P , SO > where
232
240
C : Authorities < B > ,
233
241
E : Environment < B , Error =Error > ,
234
242
E :: Proposer : Proposer < B , Error =Error > ,
235
243
<<E :: Proposer as Proposer < B > >:: Create as IntoFuture >:: Future : Send + ' static ,
236
244
I : BlockImport < B > + Send + Sync + ' static ,
245
+ P : Pair + Send + Sync + ' static ,
246
+ P :: Public : Hash + Eq + Send + Sync + Clone + Debug + Encode + Decode + ' static ,
237
247
Error : From < C :: Error > + From < I :: Error > ,
238
248
SO : SyncOracle + Send + Clone ,
239
- DigestItemFor < B > : CompatibleDigestItem + DigestItem < AuthorityId =AuthorityId > ,
249
+ DigestItemFor < B > : CompatibleDigestItem < P > + DigestItem < AuthorityId =AuthorityId < P > > ,
240
250
Error : :: std:: error:: Error + Send + ' static + From < :: consensus_common:: Error > ,
241
251
{
242
252
type OnSlot = Box < Future < Item =( ) , Error =consensus_common:: Error > + Send > ;
@@ -284,10 +294,10 @@ impl<B: Block, C, E, I, Error, SO> SlotWorker<B> for AuraWorker<C, E, I, SO> whe
284
294
) ;
285
295
return Box :: new ( future:: ok ( ( ) ) ) ;
286
296
}
287
-
288
- let proposal_work = match slot_author ( slot_num , & authorities ) {
297
+ let maybe_author = slot_author :: < P > ( slot_num , & authorities ) ;
298
+ let proposal_work = match maybe_author {
289
299
None => return Box :: new ( future:: ok ( ( ) ) ) ,
290
- Some ( author) => if author. 0 == public_key. 0 {
300
+ Some ( author) => if author == public_key {
291
301
debug ! (
292
302
target: "aura" , "Starting authorship at slot {}; timestamp = {}" ,
293
303
slot_num,
@@ -347,7 +357,7 @@ impl<B: Block, C, E, I, Error, SO> SlotWorker<B> for AuraWorker<C, E, I, SO> whe
347
357
// add it to a digest item.
348
358
let to_sign = ( slot_num, pre_hash) . encode ( ) ;
349
359
let signature = pair. sign ( & to_sign[ ..] ) ;
350
- let item = <DigestItemFor < B > as CompatibleDigestItem >:: aura_seal (
360
+ let item = <DigestItemFor < B > as CompatibleDigestItem < P > >:: aura_seal (
351
361
slot_num,
352
362
signature,
353
363
) ;
@@ -391,9 +401,10 @@ impl<B: Block, C, E, I, Error, SO> SlotWorker<B> for AuraWorker<C, E, I, SO> whe
391
401
/// if it's successful, returns the pre-header, the slot number, and the signat.
392
402
//
393
403
// FIXME #1018 needs misbehavior types
394
- fn check_header < B : Block > ( slot_now : u64 , mut header : B :: Header , hash : B :: Hash , authorities : & [ AuthorityId ] )
395
- -> Result < CheckedHeader < B :: Header , ed25519:: Signature > , String >
396
- where DigestItemFor < B > : CompatibleDigestItem
404
+ fn check_header < B : Block , P : Pair > ( slot_now : u64 , mut header : B :: Header , hash : B :: Hash , authorities : & [ AuthorityId < P > ] )
405
+ -> Result < CheckedHeader < B :: Header , P :: Signature > , String >
406
+ where DigestItemFor < B > : CompatibleDigestItem < P > ,
407
+ P :: Public : Clone + AsRef < P :: Public > ,
397
408
{
398
409
let digest_item = match header. digest_mut ( ) . pop ( ) {
399
410
Some ( x) => x,
@@ -411,16 +422,16 @@ fn check_header<B: Block>(slot_now: u64, mut header: B::Header, hash: B::Hash, a
411
422
// check the signature is valid under the expected authority and
412
423
// chain state.
413
424
414
- let expected_author = match slot_author ( slot_num, & authorities) {
425
+ let expected_author = match slot_author :: < P > ( slot_num, & authorities) {
415
426
None => return Err ( "Slot Author not found" . to_string ( ) ) ,
416
427
Some ( author) => author
417
428
} ;
418
429
419
430
let pre_hash = header. hash ( ) ;
420
431
let to_sign = ( slot_num, pre_hash) . encode ( ) ;
421
- let public = ed25519 :: Public ( expected_author. 0 ) ;
432
+ let public = expected_author;
422
433
423
- if ed25519 :: Pair :: verify ( & sig, & to_sign[ ..] , public) {
434
+ if P :: verify ( & sig, & to_sign[ ..] , public) {
424
435
Ok ( CheckedHeader :: Checked ( header, slot_num, sig) )
425
436
} else {
426
437
Err ( format ! ( "Bad signature on {:?}" , hash) )
@@ -442,13 +453,15 @@ pub trait ExtraVerification<B: Block>: Send + Sync {
442
453
}
443
454
444
455
/// A verifier for Aura blocks.
445
- pub struct AuraVerifier < C , E > {
456
+ pub struct AuraVerifier < C , E , P > {
446
457
client : Arc < C > ,
447
458
extra : E ,
459
+ phantom : PhantomData < P > ,
448
460
inherent_data_providers : inherents:: InherentDataProviders ,
449
461
}
450
462
451
- impl < C , E > AuraVerifier < C , E >
463
+ impl < C , E , P > AuraVerifier < C , E , P >
464
+ where P : Send + Sync + ' static
452
465
{
453
466
fn check_inherents < B : Block > (
454
467
& self ,
@@ -511,19 +524,21 @@ impl<B: Block> ExtraVerification<B> for NothingExtra {
511
524
}
512
525
}
513
526
514
- impl < B : Block , C , E > Verifier < B > for AuraVerifier < C , E > where
527
+ impl < B : Block , C , E , P > Verifier < B > for AuraVerifier < C , E , P > where
515
528
C : Authorities < B > + ProvideRuntimeApi + Send + Sync ,
516
529
C :: Api : BlockBuilderApi < B > ,
517
- DigestItemFor < B > : CompatibleDigestItem + DigestItem < AuthorityId =AuthorityId > ,
530
+ DigestItemFor < B > : CompatibleDigestItem < P > + DigestItem < AuthorityId =AuthorityId < P > > ,
518
531
E : ExtraVerification < B > ,
532
+ P : Pair + Send + Sync + ' static ,
533
+ P :: Public : Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + AsRef < P :: Public > + ' static ,
519
534
{
520
535
fn verify (
521
536
& self ,
522
537
origin : BlockOrigin ,
523
538
header : B :: Header ,
524
539
justification : Option < Justification > ,
525
540
mut body : Option < Vec < B :: Extrinsic > > ,
526
- ) -> Result < ( ImportBlock < B > , Option < Vec < AuthorityId > > ) , String > {
541
+ ) -> Result < ( ImportBlock < B > , Option < Vec < AuthorityId < P > > > ) , String > {
527
542
let mut inherent_data = self . inherent_data_providers . create_inherent_data ( ) . map_err ( String :: from) ?;
528
543
let ( timestamp_now, slot_now) = AuraSlotCompatible :: extract_timestamp_and_slot ( & inherent_data)
529
544
. map_err ( |e| format ! ( "Could not extract timestamp and slot: {:?}" , e) ) ?;
@@ -539,7 +554,7 @@ impl<B: Block, C, E> Verifier<B> for AuraVerifier<C, E> where
539
554
540
555
// we add one to allow for some small drift.
541
556
// FIXME #1019 in the future, alter this queue to allow deferring of headers
542
- let checked_header = check_header :: < B > ( slot_now + 1 , header, hash, & authorities[ ..] ) ?;
557
+ let checked_header = check_header :: < B , P > ( slot_now + 1 , header, hash, & authorities[ ..] ) ?;
543
558
match checked_header {
544
559
CheckedHeader :: Checked ( pre_header, slot_num, sig) => {
545
560
let item = <DigestItemFor < B > >:: aura_seal ( slot_num, sig) ;
@@ -617,7 +632,7 @@ fn register_aura_inherent_data_provider(
617
632
}
618
633
619
634
/// Start an import queue for the Aura consensus algorithm.
620
- pub fn import_queue < B , C , E > (
635
+ pub fn import_queue < B , C , E , P > (
621
636
slot_duration : SlotDuration ,
622
637
block_import : SharedBlockImport < B > ,
623
638
justification_import : Option < SharedJustificationImport < B > > ,
@@ -628,13 +643,20 @@ pub fn import_queue<B, C, E>(
628
643
B : Block ,
629
644
C : ' static + Authorities < B > + ProvideRuntimeApi + Send + Sync ,
630
645
C :: Api : BlockBuilderApi < B > ,
631
- DigestItemFor < B > : CompatibleDigestItem + DigestItem < AuthorityId =AuthorityId > ,
646
+ DigestItemFor < B > : CompatibleDigestItem < P > + DigestItem < AuthorityId =AuthorityId < P > > ,
632
647
E : ' static + ExtraVerification < B > ,
648
+ P : Pair + Send + Sync + ' static ,
649
+ P :: Public : Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode + AsRef < P :: Public > ,
633
650
{
634
651
register_aura_inherent_data_provider ( & inherent_data_providers, slot_duration. get ( ) ) ?;
635
652
636
653
let verifier = Arc :: new (
637
- AuraVerifier { client : client. clone ( ) , extra, inherent_data_providers }
654
+ AuraVerifier {
655
+ client : client. clone ( ) ,
656
+ extra,
657
+ inherent_data_providers,
658
+ phantom : PhantomData ,
659
+ }
638
660
) ;
639
661
Ok ( BasicQueue :: new ( verifier, block_import, justification_import) )
640
662
}
@@ -650,6 +672,7 @@ mod tests {
650
672
use parking_lot:: Mutex ;
651
673
use tokio:: runtime:: current_thread;
652
674
use keyring:: ed25519:: Keyring ;
675
+ use primitives:: ed25519;
653
676
use client:: BlockchainEvents ;
654
677
use test_client;
655
678
@@ -664,7 +687,7 @@ mod tests {
664
687
type Proposer = DummyProposer ;
665
688
type Error = Error ;
666
689
667
- fn init ( & self , parent_header : & <TestBlock as BlockT >:: Header , _authorities : & [ AuthorityId ] )
690
+ fn init ( & self , parent_header : & <TestBlock as BlockT >:: Header , _authorities : & [ AuthorityId < ed25519 :: Pair > ] )
668
691
-> Result < DummyProposer , Error >
669
692
{
670
693
Ok ( DummyProposer ( parent_header. number + 1 , self . 0 . clone ( ) ) )
@@ -690,7 +713,7 @@ mod tests {
690
713
691
714
impl TestNetFactory for AuraTestNet {
692
715
type Specialization = DummySpecialization ;
693
- type Verifier = AuraVerifier < PeersClient , NothingExtra > ;
716
+ type Verifier = AuraVerifier < PeersClient , NothingExtra , ed25519 :: Pair > ;
694
717
type PeerData = ( ) ;
695
718
696
719
/// Create new test network with peers and given config.
@@ -717,6 +740,7 @@ mod tests {
717
740
client,
718
741
extra : NothingExtra ,
719
742
inherent_data_providers,
743
+ phantom : Default :: default ( ) ,
720
744
} )
721
745
}
722
746
@@ -775,7 +799,7 @@ mod tests {
775
799
& inherent_data_providers, slot_duration. get ( )
776
800
) . expect ( "Registers aura inherent data provider" ) ;
777
801
778
- let aura = start_aura (
802
+ let aura = start_aura :: < _ , _ , _ , _ , ed25519 :: Pair , _ , _ , _ > (
779
803
slot_duration,
780
804
Arc :: new ( key. clone ( ) . into ( ) ) ,
781
805
client. clone ( ) ,
0 commit comments