@@ -9,13 +9,17 @@ use sc_consensus::{BasicQueue, BoxBlockImport};
9
9
use sc_consensus_grandpa:: BlockNumberOps ;
10
10
use sc_consensus_slots:: BackoffAuthoringOnFinalizedHeadLagging ;
11
11
use sc_consensus_slots:: SlotProportion ;
12
+ use sc_keystore:: LocalKeystore ;
12
13
use sc_network:: config:: SyncMode ;
13
14
use sc_network_sync:: strategy:: warp:: { WarpSyncConfig , WarpSyncProvider } ;
14
15
use sc_service:: { Configuration , PartialComponents , TaskManager , error:: Error as ServiceError } ;
15
16
use sc_telemetry:: { Telemetry , TelemetryHandle , TelemetryWorker , log} ;
16
17
use sc_transaction_pool:: TransactionPoolHandle ;
17
18
use sc_transaction_pool_api:: OffchainTransactionPoolFactory ;
18
19
use sp_core:: H256 ;
20
+ use sp_core:: crypto:: KeyTypeId ;
21
+ use sp_keystore:: Keystore ;
22
+ use sp_runtime:: key_types;
19
23
use sp_runtime:: traits:: { Block as BlockT , NumberFor } ;
20
24
use std:: collections:: HashSet ;
21
25
use std:: str:: FromStr ;
@@ -31,6 +35,8 @@ use crate::ethereum::{
31
35
StorageOverrideHandler , db_config_dir, new_frontier_partial, spawn_frontier_tasks,
32
36
} ;
33
37
38
+ const LOG_TARGET : & str = "node-service" ;
39
+
34
40
/// The minimum period of blocks on which justifications will be
35
41
/// imported and generated.
36
42
const GRANDPA_JUSTIFICATION_PERIOD : u32 = 512 ;
@@ -94,6 +100,13 @@ pub fn new_partial(
94
100
executor,
95
101
) ?;
96
102
103
+ // Prepare keystore for authoring Babe blocks.
104
+ copy_keys (
105
+ & keystore_container. local_keystore ( ) ,
106
+ key_types:: AURA ,
107
+ key_types:: BABE ,
108
+ ) ?;
109
+
97
110
let client = Arc :: new ( client) ;
98
111
99
112
let telemetry = telemetry. map ( |( worker, telemetry) | {
@@ -758,3 +771,47 @@ fn run_manual_seal_authorship(
758
771
. spawn_blocking ( "manual-seal" , None , manual_seal) ;
759
772
Ok ( ( ) )
760
773
}
774
+
775
+ /// Copy `from_key_type` keys to also exist as `to_key_type`.
776
+ ///
777
+ /// Used for the Aura to Babe migration, where Aura validators need their keystore to copy their
778
+ /// Aura keys over to Babe. This works because Aura and Babe keys use identical crypto.
779
+ fn copy_keys (
780
+ keystore : & LocalKeystore ,
781
+ from_key_type : KeyTypeId ,
782
+ to_key_type : KeyTypeId ,
783
+ ) -> sc_keystore:: Result < ( ) > {
784
+ use std:: collections:: HashSet ;
785
+
786
+ let from_keys: HashSet < _ > = keystore
787
+ . raw_public_keys ( from_key_type) ?
788
+ . into_iter ( )
789
+ . collect ( ) ;
790
+ let to_keys: HashSet < _ > = keystore. raw_public_keys ( to_key_type) ?. into_iter ( ) . collect ( ) ;
791
+ let to_copy: Vec < _ > = from_keys. difference ( & to_keys) . collect ( ) ;
792
+
793
+ log:: debug!( target: LOG_TARGET , "from_keys: {:?}" , from_keys) ;
794
+ log:: debug!( target: LOG_TARGET , "to_keys: {:?}" , to_keys) ;
795
+ log:: debug!( target: LOG_TARGET , "to_copy: {:?} from {:?} to {:?}" , & to_copy, from_key_type, to_key_type) ;
796
+
797
+ for public in to_copy {
798
+ if let Some ( phrase) = keystore. key_phrase_by_type ( & public, from_key_type) ? {
799
+ if let Err ( _) = keystore. insert ( to_key_type, & phrase, & public) {
800
+ log:: error!(
801
+ target: LOG_TARGET ,
802
+ "Failed to copy key {:?} into keystore, insert operation failed." ,
803
+ & public,
804
+ ) ;
805
+ } ;
806
+ } else {
807
+ log:: error!(
808
+ target: LOG_TARGET ,
809
+ "Failed to copy key from {:?} to {:?} as the key phrase is not available" ,
810
+ from_key_type,
811
+ to_key_type
812
+ ) ;
813
+ }
814
+ }
815
+
816
+ Ok ( ( ) )
817
+ }
0 commit comments