@@ -9,13 +9,17 @@ use sc_consensus::{BasicQueue, BoxBlockImport};
99use sc_consensus_grandpa:: BlockNumberOps ;
1010use sc_consensus_slots:: BackoffAuthoringOnFinalizedHeadLagging ;
1111use sc_consensus_slots:: SlotProportion ;
12+ use sc_keystore:: LocalKeystore ;
1213use sc_network:: config:: SyncMode ;
1314use sc_network_sync:: strategy:: warp:: { WarpSyncConfig , WarpSyncProvider } ;
1415use sc_service:: { Configuration , PartialComponents , TaskManager , error:: Error as ServiceError } ;
1516use sc_telemetry:: { Telemetry , TelemetryHandle , TelemetryWorker , log} ;
1617use sc_transaction_pool:: TransactionPoolHandle ;
1718use sc_transaction_pool_api:: OffchainTransactionPoolFactory ;
1819use sp_core:: H256 ;
20+ use sp_core:: crypto:: KeyTypeId ;
21+ use sp_keystore:: Keystore ;
22+ use sp_runtime:: key_types;
1923use sp_runtime:: traits:: { Block as BlockT , NumberFor } ;
2024use std:: collections:: HashSet ;
2125use std:: str:: FromStr ;
@@ -31,6 +35,8 @@ use crate::ethereum::{
3135 StorageOverrideHandler , db_config_dir, new_frontier_partial, spawn_frontier_tasks,
3236} ;
3337
38+ const LOG_TARGET : & str = "node-service" ;
39+
3440/// The minimum period of blocks on which justifications will be
3541/// imported and generated.
3642const GRANDPA_JUSTIFICATION_PERIOD : u32 = 512 ;
@@ -94,6 +100,13 @@ pub fn new_partial(
94100 executor,
95101 ) ?;
96102
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+
97110 let client = Arc :: new ( client) ;
98111
99112 let telemetry = telemetry. map ( |( worker, telemetry) | {
@@ -758,3 +771,47 @@ fn run_manual_seal_authorship(
758771 . spawn_blocking ( "manual-seal" , None , manual_seal) ;
759772 Ok ( ( ) )
760773}
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