Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bc7d132

Browse files
rakanalhbkchr
andauthoredOct 9, 2020
Update to work with async keystore – Companion PR for paritytech#7000 (paritytech#1740)
* Fix keystore types * Use SyncCryptoStorePtr * Borrow keystore * Fix unused imports * Fix polkadot service * Fix bitfield-distribution tests * Fix indentation * Fix backing tests * Fix tests * Fix provisioner tests * Removed SyncCryptoStorePtr * Fix services * Address PR feedback * Address PR feedback - 2 * Update CryptoStorePtr imports to be from sp_keystore * Typo * Fix CryptoStore import * Document the reason behind using filesystem keystore * Remove VALIDATORS * Fix duplicate dependency * Mark sp-keystore as optional * Fix availability distribution * Fix call to sign_with * Fix keystore usage * Remove tokio and fix parachains Cargo config * Typos * Fix keystore dereferencing * Fix CryptoStore import * Fix provisioner * Fix node backing * Update services * Cleanup dependencies * Use sync_keystore * Fix node service * Fix node service - 2 * Fix node service - 3 * Rename CryptoStorePtr to SyncCryptoStorePtr * "Update Substrate" * Apply suggestions from code review * Update node/core/backing/Cargo.toml * Update primitives/src/v0.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Fix wasm build * Update Cargo.lock Co-authored-by: parity-processbot <> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
1 parent 479cc3d commit bc7d132

File tree

23 files changed

+664
-396
lines changed

23 files changed

+664
-396
lines changed
 

‎Cargo.lock

+200-146
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎node/core/backing/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ edition = "2018"
77
[dependencies]
88
futures = "0.3.5"
99
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
10+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
1011
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
1112
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
12-
keystore = { package = "sc-keystore", git = "https://github.com/paritytech/substrate", branch = "master" }
1313
polkadot-primitives = { path = "../../../primitives" }
1414
polkadot-node-primitives = { path = "../../primitives" }
1515
polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
@@ -22,7 +22,9 @@ log = "0.4.8"
2222

2323
[dev-dependencies]
2424
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
25+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
2526
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
27+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
2628
futures = { version = "0.3.5", features = ["thread-pool"] }
2729
assert_matches = "1.3.0"
2830
polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" }

‎node/core/backing/src/lib.rs

+83-37
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use futures::{
2727
Future, FutureExt, SinkExt, StreamExt,
2828
};
2929

30-
use keystore::KeyStorePtr;
30+
use sp_keystore::SyncCryptoStorePtr;
3131
use polkadot_primitives::v1::{
3232
CommittedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorId,
3333
ValidatorIndex, SigningContext, PoV,
@@ -101,6 +101,7 @@ struct CandidateBackingJob {
101101
seconded: Option<Hash>,
102102
/// We have already reported misbehaviors for these validators.
103103
reported_misbehavior_for: HashSet<ValidatorIndex>,
104+
keystore: SyncCryptoStorePtr,
104105
table: Table<TableContext>,
105106
table_context: TableContext,
106107
metrics: Metrics,
@@ -328,9 +329,12 @@ impl CandidateBackingJob {
328329
};
329330

330331
let issued_statement = statement.is_some();
331-
if let Some(signed_statement) = statement.and_then(|s| self.sign_statement(s)) {
332-
self.import_statement(&signed_statement).await?;
333-
self.distribute_signed_statement(signed_statement).await?;
332+
333+
if let Some(statement) = statement {
334+
if let Some(signed_statement) = self.sign_statement(statement).await {
335+
self.import_statement(&signed_statement).await?;
336+
self.distribute_signed_statement(signed_statement).await?;
337+
}
334338
}
335339

336340
Ok(issued_statement)
@@ -530,7 +534,7 @@ impl CandidateBackingJob {
530534

531535
self.issued_statements.insert(candidate_hash);
532536

533-
if let Some(signed_statement) = self.sign_statement(statement) {
537+
if let Some(signed_statement) = self.sign_statement(statement).await {
534538
self.distribute_signed_statement(signed_statement).await?;
535539
}
536540

@@ -553,8 +557,13 @@ impl CandidateBackingJob {
553557
Ok(())
554558
}
555559

556-
fn sign_statement(&self, statement: Statement) -> Option<SignedFullStatement> {
557-
let signed = self.table_context.validator.as_ref()?.sign(statement);
560+
async fn sign_statement(&self, statement: Statement) -> Option<SignedFullStatement> {
561+
let signed = self.table_context
562+
.validator
563+
.as_ref()?
564+
.sign(self.keystore.clone(), statement)
565+
.await
566+
.ok()?;
558567
self.metrics.on_statement_signed();
559568
Some(signed)
560569
}
@@ -694,14 +703,14 @@ impl util::JobTrait for CandidateBackingJob {
694703
type ToJob = ToJob;
695704
type FromJob = FromJob;
696705
type Error = Error;
697-
type RunArgs = KeyStorePtr;
706+
type RunArgs = SyncCryptoStorePtr;
698707
type Metrics = Metrics;
699708

700709
const NAME: &'static str = "CandidateBackingJob";
701710

702711
fn run(
703712
parent: Hash,
704-
keystore: KeyStorePtr,
713+
keystore: SyncCryptoStorePtr,
705714
metrics: Metrics,
706715
rx_to: mpsc::Receiver<Self::ToJob>,
707716
mut tx_from: mpsc::Sender<Self::FromJob>,
@@ -748,7 +757,7 @@ impl util::JobTrait for CandidateBackingJob {
748757
&validators,
749758
signing_context,
750759
keystore.clone(),
751-
) {
760+
).await {
752761
Ok(v) => v,
753762
Err(util::Error::NotAValidator) => { return Ok(()) },
754763
Err(e) => {
@@ -802,6 +811,7 @@ impl util::JobTrait for CandidateBackingJob {
802811
issued_statements: HashSet::new(),
803812
seconded: None,
804813
reported_misbehavior_for: HashSet::new(),
814+
keystore,
805815
table: Table::default(),
806816
table_context,
807817
metrics,
@@ -859,24 +869,26 @@ impl metrics::Metrics for Metrics {
859869
}
860870
}
861871

862-
delegated_subsystem!(CandidateBackingJob(KeyStorePtr, Metrics) <- ToJob as CandidateBackingSubsystem);
872+
delegated_subsystem!(CandidateBackingJob(SyncCryptoStorePtr, Metrics) <- ToJob as CandidateBackingSubsystem);
863873

864874
#[cfg(test)]
865875
mod tests {
866876
use super::*;
867877
use assert_matches::assert_matches;
868-
use futures::{executor, future, Future};
878+
use futures::{future, Future};
869879
use polkadot_primitives::v1::{
870880
ScheduledCore, BlockData, CandidateCommitments,
871881
PersistedValidationData, ValidationData, TransientValidationData, HeadData,
872-
ValidatorPair, ValidityAttestation, GroupRotationInfo,
882+
ValidityAttestation, GroupRotationInfo,
873883
};
874884
use polkadot_subsystem::{
875885
messages::RuntimeApiRequest,
876886
ActiveLeavesUpdate, FromOverseer, OverseerSignal,
877887
};
878888
use polkadot_node_primitives::InvalidCandidate;
879889
use sp_keyring::Sr25519Keyring;
890+
use sp_application_crypto::AppKey;
891+
use sp_keystore::{CryptoStore, SyncCryptoStore};
880892
use std::collections::HashMap;
881893

882894
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec<ValidatorId> {
@@ -885,7 +897,7 @@ mod tests {
885897

886898
struct TestState {
887899
chain_ids: Vec<ParaId>,
888-
keystore: KeyStorePtr,
900+
keystore: SyncCryptoStorePtr,
889901
validators: Vec<Sr25519Keyring>,
890902
validator_public: Vec<ValidatorId>,
891903
validation_data: ValidationData,
@@ -912,9 +924,9 @@ mod tests {
912924
Sr25519Keyring::Ferdie,
913925
];
914926

915-
let keystore = keystore::Store::new_in_memory();
927+
let keystore = Arc::new(sc_keystore::LocalKeystore::in_memory());
916928
// Make sure `Alice` key is in the keystore, so this mocked node will be a parachain validator.
917-
keystore.write().insert_ephemeral_from_seed::<ValidatorPair>(&validators[0].to_seed())
929+
SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&validators[0].to_seed()))
918930
.expect("Insert key into keystore");
919931

920932
let validator_public = validator_pubkeys(&validators);
@@ -985,7 +997,7 @@ mod tests {
985997
virtual_overseer: polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle<CandidateBackingMessage>,
986998
}
987999

988-
fn test_harness<T: Future<Output=()>>(keystore: KeyStorePtr, test: impl FnOnce(TestHarness) -> T) {
1000+
fn test_harness<T: Future<Output=()>>(keystore: SyncCryptoStorePtr, test: impl FnOnce(TestHarness) -> T) {
9891001
let pool = sp_core::testing::TaskExecutor::new();
9901002

9911003
let (context, virtual_overseer) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool.clone());
@@ -998,8 +1010,7 @@ mod tests {
9981010

9991011
futures::pin_mut!(test_fut);
10001012
futures::pin_mut!(subsystem);
1001-
1002-
executor::block_on(future::select(test_fut, subsystem));
1013+
futures::executor::block_on(future::select(test_fut, subsystem));
10031014
}
10041015

10051016
fn make_erasure_root(test: &TestState, pov: PoV) -> Hash {
@@ -1203,20 +1214,29 @@ mod tests {
12031214
}.build();
12041215

12051216
let candidate_a_hash = candidate_a.hash();
1206-
1217+
let public0 = CryptoStore::sr25519_generate_new(
1218+
&*test_state.keystore,
1219+
ValidatorId::ID, Some(&test_state.validators[0].to_seed())
1220+
).await.expect("Insert key into keystore");
1221+
let public2 = CryptoStore::sr25519_generate_new(
1222+
&*test_state.keystore,
1223+
ValidatorId::ID, Some(&test_state.validators[2].to_seed())
1224+
).await.expect("Insert key into keystore");
12071225
let signed_a = SignedFullStatement::sign(
1226+
&test_state.keystore,
12081227
Statement::Seconded(candidate_a.clone()),
12091228
&test_state.signing_context,
12101229
2,
1211-
&test_state.validators[2].pair().into(),
1212-
);
1230+
&public2.into(),
1231+
).await.expect("should be signed");
12131232

12141233
let signed_b = SignedFullStatement::sign(
1234+
&test_state.keystore,
12151235
Statement::Valid(candidate_a_hash),
12161236
&test_state.signing_context,
12171237
0,
1218-
&test_state.validators[0].pair().into(),
1219-
);
1238+
&public0.into(),
1239+
).await.expect("should be signed");
12201240

12211241
let statement = CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone());
12221242

@@ -1330,27 +1350,37 @@ mod tests {
13301350
}.build();
13311351

13321352
let candidate_a_hash = candidate_a.hash();
1333-
1353+
let public0 = CryptoStore::sr25519_generate_new(
1354+
&*test_state.keystore,
1355+
ValidatorId::ID, Some(&test_state.validators[0].to_seed())
1356+
).await.expect("Insert key into keystore");
1357+
let public2 = CryptoStore::sr25519_generate_new(
1358+
&*test_state.keystore,
1359+
ValidatorId::ID, Some(&test_state.validators[2].to_seed())
1360+
).await.expect("Insert key into keystore");
13341361
let signed_a = SignedFullStatement::sign(
1362+
&test_state.keystore,
13351363
Statement::Seconded(candidate_a.clone()),
13361364
&test_state.signing_context,
13371365
2,
1338-
&test_state.validators[2].pair().into(),
1339-
);
1366+
&public2.into(),
1367+
).await.expect("should be signed");
13401368

13411369
let signed_b = SignedFullStatement::sign(
1370+
&test_state.keystore,
13421371
Statement::Valid(candidate_a_hash),
13431372
&test_state.signing_context,
13441373
0,
1345-
&test_state.validators[0].pair().into(),
1346-
);
1374+
&public0.into(),
1375+
).await.expect("should be signed");
13471376

13481377
let signed_c = SignedFullStatement::sign(
1378+
&test_state.keystore,
13491379
Statement::Invalid(candidate_a_hash),
13501380
&test_state.signing_context,
13511381
0,
1352-
&test_state.validators[0].pair().into(),
1353-
);
1382+
&public0.into(),
1383+
).await.expect("should be signed");
13541384

13551385
let statement = CandidateBackingMessage::Statement(test_state.relay_parent, signed_a.clone());
13561386

@@ -1600,12 +1630,18 @@ mod tests {
16001630

16011631
let candidate_hash = candidate.hash();
16021632

1633+
let validator2 = CryptoStore::sr25519_generate_new(
1634+
&*test_state.keystore,
1635+
ValidatorId::ID, Some(&test_state.validators[2].to_seed())
1636+
).await.expect("Insert key into keystore");
1637+
16031638
let signed_a = SignedFullStatement::sign(
1639+
&test_state.keystore,
16041640
Statement::Seconded(candidate.clone()),
16051641
&test_state.signing_context,
16061642
2,
1607-
&test_state.validators[2].pair().into(),
1608-
);
1643+
&validator2.into(),
1644+
).await.expect("should be signed");
16091645

16101646
// Send in a `Statement` with a candidate.
16111647
let statement = CandidateBackingMessage::Statement(
@@ -1733,12 +1769,17 @@ mod tests {
17331769
..Default::default()
17341770
}.build();
17351771

1772+
let public2 = CryptoStore::sr25519_generate_new(
1773+
&*test_state.keystore,
1774+
ValidatorId::ID, Some(&test_state.validators[2].to_seed())
1775+
).await.expect("Insert key into keystore");
17361776
let signed_a = SignedFullStatement::sign(
1777+
&test_state.keystore,
17371778
Statement::Seconded(candidate.clone()),
17381779
&test_state.signing_context,
17391780
2,
1740-
&test_state.validators[2].pair().into(),
1741-
);
1781+
&public2.into(),
1782+
).await.expect("should be signed");
17421783

17431784
// Send in a `Statement` with a candidate.
17441785
let statement = CandidateBackingMessage::Statement(
@@ -1869,12 +1910,17 @@ mod tests {
18691910
..Default::default()
18701911
}.build();
18711912

1913+
let public2 = CryptoStore::sr25519_generate_new(
1914+
&*test_state.keystore,
1915+
ValidatorId::ID, Some(&test_state.validators[2].to_seed())
1916+
).await.expect("Insert key into keystore");
18721917
let seconding = SignedFullStatement::sign(
1918+
&test_state.keystore,
18731919
Statement::Seconded(candidate_a.clone()),
18741920
&test_state.signing_context,
18751921
2,
1876-
&test_state.validators[2].pair().into(),
1877-
);
1922+
&public2.into(),
1923+
).await.expect("should be signed");
18781924

18791925
let statement = CandidateBackingMessage::Statement(
18801926
test_state.relay_parent,

‎node/core/bitfield-signing/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ log = "0.4.8"
1212
polkadot-primitives = { path = "../../../primitives" }
1313
polkadot-node-subsystem = { path = "../../subsystem" }
1414
polkadot-node-subsystem-util = { path = "../../subsystem-util" }
15-
keystore = { package = "sc-keystore", git = "https://github.com/paritytech/substrate", branch = "master" }
15+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
1616
wasm-timer = "0.2.4"

‎node/core/bitfield-signing/src/lib.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use futures::{
2222
prelude::*,
2323
stream, Future,
2424
};
25-
use keystore::KeyStorePtr;
25+
use sp_keystore::{Error as KeystoreError, SyncCryptoStorePtr};
2626
use polkadot_node_subsystem::{
2727
messages::{
2828
self, AllMessages, AvailabilityStoreMessage, BitfieldDistributionMessage,
@@ -132,6 +132,9 @@ pub enum Error {
132132
/// the runtime API failed to return what we wanted
133133
#[from]
134134
Runtime(RuntimeApiError),
135+
/// the keystore failed to process signing request
136+
#[from]
137+
Keystore(KeystoreError),
135138
}
136139

137140
// if there is a candidate pending availability, query the Availability Store
@@ -289,7 +292,7 @@ impl JobTrait for BitfieldSigningJob {
289292
type ToJob = ToJob;
290293
type FromJob = FromJob;
291294
type Error = Error;
292-
type RunArgs = KeyStorePtr;
295+
type RunArgs = SyncCryptoStorePtr;
293296
type Metrics = Metrics;
294297

295298
const NAME: &'static str = "BitfieldSigningJob";
@@ -308,7 +311,7 @@ impl JobTrait for BitfieldSigningJob {
308311

309312
// now do all the work we can before we need to wait for the availability store
310313
// if we're not a validator, we can just succeed effortlessly
311-
let validator = match Validator::new(relay_parent, keystore, sender.clone()).await {
314+
let validator = match Validator::new(relay_parent, keystore.clone(), sender.clone()).await {
312315
Ok(validator) => validator,
313316
Err(util::Error::NotAValidator) => return Ok(()),
314317
Err(err) => return Err(Error::Util(err)),
@@ -329,7 +332,10 @@ impl JobTrait for BitfieldSigningJob {
329332
Ok(bitfield) => bitfield,
330333
};
331334

332-
let signed_bitfield = validator.sign(bitfield);
335+
let signed_bitfield = validator
336+
.sign(keystore.clone(), bitfield)
337+
.await
338+
.map_err(|e| Error::Keystore(e))?;
333339
metrics.on_bitfield_signed();
334340

335341
// make an anonymous scope to contain some use statements to simplify creating the outbound message

‎node/core/provisioner/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ polkadot-node-subsystem-util = { path = "../../subsystem-util" }
1616
[dev-dependencies]
1717
lazy_static = "1.4"
1818
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
19+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
20+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
21+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
1922
futures-timer = "3.0.2"
23+
tempfile = "3.1.0"

‎node/core/provisioner/src/lib.rs

+38-27
Original file line numberDiff line numberDiff line change
@@ -549,46 +549,47 @@ mod tests {
549549
mod select_availability_bitfields {
550550
use super::super::*;
551551
use super::{default_bitvec, occupied_core};
552-
use lazy_static::lazy_static;
553-
use polkadot_primitives::v1::{SigningContext, ValidatorIndex, ValidatorPair};
554-
use sp_core::crypto::Pair;
555-
use std::sync::Mutex;
556-
557-
lazy_static! {
558-
// we can use a normal mutex here, not a futures-aware one, because we don't use any futures-based
559-
// concurrency when accessing this. The risk of contention is that multiple tests are run in parallel,
560-
// in independent threads, in which case a standard mutex suffices.
561-
static ref VALIDATORS: Mutex<HashMap<ValidatorIndex, ValidatorPair>> = Mutex::new(HashMap::new());
562-
}
563-
564-
fn signed_bitfield(
552+
use futures::executor::block_on;
553+
use std::sync::Arc;
554+
use polkadot_primitives::v1::{SigningContext, ValidatorIndex, ValidatorId};
555+
use sp_application_crypto::AppKey;
556+
use sp_keystore::{CryptoStore, SyncCryptoStorePtr};
557+
use sc_keystore::LocalKeystore;
558+
559+
async fn signed_bitfield(
560+
keystore: &SyncCryptoStorePtr,
565561
field: CoreAvailability,
566562
validator_idx: ValidatorIndex,
567563
) -> SignedAvailabilityBitfield {
568-
let mut lock = VALIDATORS.lock().unwrap();
569-
let validator = lock
570-
.entry(validator_idx)
571-
.or_insert_with(|| ValidatorPair::generate().0);
564+
let public = CryptoStore::sr25519_generate_new(&**keystore, ValidatorId::ID, None)
565+
.await
566+
.expect("generated sr25519 key");
572567
SignedAvailabilityBitfield::sign(
568+
&keystore,
573569
field.into(),
574570
&<SigningContext<Hash>>::default(),
575571
validator_idx,
576-
validator,
577-
)
572+
&public.into(),
573+
).await.expect("Should be signed")
578574
}
579575

580576
#[test]
581577
fn not_more_than_one_per_validator() {
578+
// Configure filesystem-based keystore as generating keys without seed
579+
// would trigger the key to be generated on the filesystem.
580+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
581+
let keystore : SyncCryptoStorePtr = Arc::new(LocalKeystore::open(keystore_path.path(), None)
582+
.expect("Creates keystore"));
582583
let bitvec = default_bitvec();
583584

584585
let cores = vec![occupied_core(0), occupied_core(1)];
585586

586587
// we pass in three bitfields with two validators
587588
// this helps us check the postcondition that we get two bitfields back, for which the validators differ
588589
let bitfields = vec![
589-
signed_bitfield(bitvec.clone(), 0),
590-
signed_bitfield(bitvec.clone(), 1),
591-
signed_bitfield(bitvec, 1),
590+
block_on(signed_bitfield(&keystore, bitvec.clone(), 0)),
591+
block_on(signed_bitfield(&keystore, bitvec.clone(), 1)),
592+
block_on(signed_bitfield(&keystore, bitvec, 1)),
592593
];
593594

594595
let mut selected_bitfields = select_availability_bitfields(&cores, &bitfields);
@@ -602,14 +603,19 @@ mod tests {
602603

603604
#[test]
604605
fn each_corresponds_to_an_occupied_core() {
606+
// Configure filesystem-based keystore as generating keys without seed
607+
// would trigger the key to be generated on the filesystem.
608+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
609+
let keystore : SyncCryptoStorePtr = Arc::new(LocalKeystore::open(keystore_path.path(), None)
610+
.expect("Creates keystore"));
605611
let bitvec = default_bitvec();
606612

607613
let cores = vec![CoreState::Free, CoreState::Scheduled(Default::default())];
608614

609615
let bitfields = vec![
610-
signed_bitfield(bitvec.clone(), 0),
611-
signed_bitfield(bitvec.clone(), 1),
612-
signed_bitfield(bitvec, 1),
616+
block_on(signed_bitfield(&keystore, bitvec.clone(), 0)),
617+
block_on(signed_bitfield(&keystore, bitvec.clone(), 1)),
618+
block_on(signed_bitfield(&keystore, bitvec, 1)),
613619
];
614620

615621
let mut selected_bitfields = select_availability_bitfields(&cores, &bitfields);
@@ -621,6 +627,11 @@ mod tests {
621627

622628
#[test]
623629
fn more_set_bits_win_conflicts() {
630+
// Configure filesystem-based keystore as generating keys without seed
631+
// would trigger the key to be generated on the filesystem.
632+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
633+
let keystore : SyncCryptoStorePtr = Arc::new(LocalKeystore::open(keystore_path.path(), None)
634+
.expect("Creates keystore"));
624635
let bitvec_zero = default_bitvec();
625636
let bitvec_one = {
626637
let mut bitvec = bitvec_zero.clone();
@@ -631,8 +642,8 @@ mod tests {
631642
let cores = vec![occupied_core(0)];
632643

633644
let bitfields = vec![
634-
signed_bitfield(bitvec_zero, 0),
635-
signed_bitfield(bitvec_one.clone(), 0),
645+
block_on(signed_bitfield(&keystore, bitvec_zero, 0)),
646+
block_on(signed_bitfield(&keystore, bitvec_one.clone(), 0)),
636647
];
637648

638649
// this test is probablistic: chances are excellent that it does what it claims to.

‎node/network/availability-distribution/Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@ futures = "0.3.5"
99
log = "0.4.11"
1010
streamunordered = "0.5.1"
1111
codec = { package="parity-scale-codec", version = "1.3.4", features = ["std"] }
12+
derive_more = "0.99.9"
1213
polkadot-primitives = { path = "../../../primitives" }
1314
polkadot-erasure-coding = { path = "../../../erasure-coding" }
1415
polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../../subsystem" }
1516
polkadot-network-bridge = { path = "../../network/bridge" }
1617
polkadot-node-network-protocol = { path = "../../network/protocol" }
1718
polkadot-node-subsystem-util = { path = "../../subsystem-util" }
18-
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
19-
derive_more = "0.99.9"
2019
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] }
20+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
2121

2222
[dev-dependencies]
2323
polkadot-subsystem-testhelpers = { package = "polkadot-node-subsystem-test-helpers", path = "../../subsystem-test-helpers" }
2424
bitvec = { version = "0.17.4", default-features = false, features = ["alloc"] }
2525
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["std"] }
26+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
2627
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
28+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
2729
parking_lot = "0.11.0"
2830
futures-timer = "3.0.2"
2931
env_logger = "0.7.1"

‎node/network/availability-distribution/src/lib.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,8 @@
2525
use codec::{Decode, Encode};
2626
use futures::{channel::oneshot, FutureExt};
2727

28-
use keystore::KeyStorePtr;
29-
use sp_core::{
30-
crypto::Public,
31-
traits::BareCryptoStore,
32-
};
33-
use sc_keystore as keystore;
28+
use sp_core::crypto::Public;
29+
use sp_keystore::{CryptoStore, SyncCryptoStorePtr};
3430

3531
use log::{trace, warn};
3632
use polkadot_erasure_coding::branch_hash;
@@ -293,7 +289,7 @@ impl ProtocolState {
293289
/// which depends on the message type received.
294290
async fn handle_network_msg<Context>(
295291
ctx: &mut Context,
296-
keystore: KeyStorePtr,
292+
keystore: &SyncCryptoStorePtr,
297293
state: &mut ProtocolState,
298294
metrics: &Metrics,
299295
bridge_message: NetworkBridgeEvent<protocol_v1::AvailabilityDistributionMessage>,
@@ -332,7 +328,7 @@ where
332328
/// Handle the changes necessary when our view changes.
333329
async fn handle_our_view_change<Context>(
334330
ctx: &mut Context,
335-
keystore: KeyStorePtr,
331+
keystore: &SyncCryptoStorePtr,
336332
state: &mut ProtocolState,
337333
view: View,
338334
metrics: &Metrics,
@@ -353,7 +349,7 @@ where
353349
let validator_index = obtain_our_validator_index(
354350
&validators,
355351
keystore.clone(),
356-
);
352+
).await;
357353
state.add_relay_parent(ctx, added, validators, validator_index).await?;
358354
}
359355

@@ -579,18 +575,16 @@ where
579575
/// Obtain the first key which has a signing key.
580576
/// Returns the index within the validator set as `ValidatorIndex`, if there exists one,
581577
/// otherwise, `None` is returned.
582-
fn obtain_our_validator_index(
578+
async fn obtain_our_validator_index(
583579
validators: &[ValidatorId],
584-
keystore: KeyStorePtr,
580+
keystore: SyncCryptoStorePtr,
585581
) -> Option<ValidatorIndex> {
586-
let keystore = keystore.read();
587-
validators.iter().enumerate().find_map(|(idx, validator)| {
588-
if keystore.has_keys(&[(validator.to_raw_vec(), PARACHAIN_KEY_TYPE_ID)]) {
589-
Some(idx as ValidatorIndex)
590-
} else {
591-
None
582+
for (idx, validator) in validators.iter().enumerate() {
583+
if CryptoStore::has_keys(&*keystore, &[(validator.to_raw_vec(), PARACHAIN_KEY_TYPE_ID)]).await {
584+
return Some(idx as ValidatorIndex)
592585
}
593-
})
586+
}
587+
None
594588
}
595589

596590
/// Handle an incoming message from a peer.
@@ -712,7 +706,7 @@ where
712706
/// The bitfield distribution subsystem.
713707
pub struct AvailabilityDistributionSubsystem {
714708
/// Pointer to a keystore, which is required for determining this nodes validator index.
715-
keystore: KeyStorePtr,
709+
keystore: SyncCryptoStorePtr,
716710
/// Prometheus metrics.
717711
metrics: Metrics,
718712
}
@@ -722,7 +716,7 @@ impl AvailabilityDistributionSubsystem {
722716
const K: usize = 3;
723717

724718
/// Create a new instance of the availability distribution.
725-
pub fn new(keystore: KeyStorePtr, metrics: Metrics) -> Self {
719+
pub fn new(keystore: SyncCryptoStorePtr, metrics: Metrics) -> Self {
726720
Self { keystore, metrics }
727721
}
728722

@@ -741,7 +735,7 @@ impl AvailabilityDistributionSubsystem {
741735
} => {
742736
if let Err(e) = handle_network_msg(
743737
&mut ctx,
744-
self.keystore.clone(),
738+
&self.keystore.clone(),
745739
&mut state,
746740
&self.metrics,
747741
event,

‎node/network/availability-distribution/src/tests.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use polkadot_erasure_coding::{branches, obtain_chunks_v1 as obtain_chunks};
2020
use polkadot_primitives::v1::{
2121
AvailableData, BlockData, CandidateCommitments, CandidateDescriptor, GroupIndex,
2222
GroupRotationInfo, HeadData, PersistedValidationData, OccupiedCore,
23-
PoV, ScheduledCore, ValidatorPair,
23+
PoV, ScheduledCore,
2424
};
2525
use polkadot_subsystem_testhelpers::{self as test_helpers};
2626
use polkadot_node_subsystem_util::TimeoutExt;
@@ -29,7 +29,10 @@ use polkadot_node_network_protocol::ObservedRole;
2929
use futures::{executor, future, Future};
3030
use futures_timer::Delay;
3131
use smallvec::smallvec;
32-
use std::time::Duration;
32+
use std::{sync::Arc, time::Duration};
33+
use sc_keystore::LocalKeystore;
34+
use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore};
35+
use sp_application_crypto::AppKey;
3336

3437
macro_rules! view {
3538
( $( $hash:expr ),* $(,)? ) => [
@@ -57,7 +60,7 @@ struct TestHarness {
5760
}
5861

5962
fn test_harness<T: Future<Output = ()>>(
60-
keystore: KeyStorePtr,
63+
keystore: SyncCryptoStorePtr,
6164
test: impl FnOnce(TestHarness) -> T,
6265
) {
6366
let _ = env_logger::builder()
@@ -144,7 +147,7 @@ struct TestState {
144147
validator_index: Option<ValidatorIndex>,
145148
validator_groups: (Vec<Vec<ValidatorIndex>>, GroupRotationInfo),
146149
head_data: HashMap<ParaId, HeadData>,
147-
keystore: KeyStorePtr,
150+
keystore: SyncCryptoStorePtr,
148151
relay_parent: Hash,
149152
ancestors: Vec<Hash>,
150153
availability_cores: Vec<CoreState>,
@@ -170,11 +173,9 @@ impl Default for TestState {
170173
Sr25519Keyring::Dave,
171174
];
172175

173-
let keystore = keystore::Store::new_in_memory();
176+
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
174177

175-
keystore
176-
.write()
177-
.insert_ephemeral_from_seed::<ValidatorPair>(&validators[0].to_seed())
178+
SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, Some(&validators[0].to_seed()))
178179
.expect("Insert key into keystore");
179180

180181
let validator_public = validator_pubkeys(&validators);

‎node/network/bitfield-distribution/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ sc-network = { git = "https://github.com/paritytech/substrate", branch = "master
2222
polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" }
2323
bitvec = { version = "0.17.4", default-features = false, features = ["alloc"] }
2424
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
25+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
26+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
27+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
2528
parking_lot = "0.11.0"
2629
maplit = "1.0.2"
2730
smol = "0.3.3"
2831
env_logger = "0.7.1"
2932
assert_matches = "1.3.0"
33+
tempfile = "3.1.0"

‎node/network/bitfield-distribution/src/lib.rs

+42-23
Original file line numberDiff line numberDiff line change
@@ -674,10 +674,13 @@ mod test {
674674
use bitvec::bitvec;
675675
use futures::executor;
676676
use maplit::hashmap;
677-
use polkadot_primitives::v1::{Signed, ValidatorPair, AvailabilityBitfield};
677+
use polkadot_primitives::v1::{Signed, AvailabilityBitfield};
678678
use polkadot_node_subsystem_test_helpers::make_subsystem_context;
679679
use polkadot_node_subsystem_util::TimeoutExt;
680-
use sp_core::crypto::Pair;
680+
use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore};
681+
use sp_application_crypto::AppKey;
682+
use sc_keystore::LocalKeystore;
683+
use std::sync::Arc;
681684
use std::time::Duration;
682685
use assert_matches::assert_matches;
683686
use polkadot_node_network_protocol::ObservedRole;
@@ -735,22 +738,28 @@ mod test {
735738
}
736739
}
737740

738-
fn state_with_view(view: View, relay_parent: Hash) -> (ProtocolState, SigningContext, ValidatorPair) {
741+
fn state_with_view(
742+
view: View,
743+
relay_parent: Hash,
744+
keystore_path: &tempfile::TempDir,
745+
) -> (ProtocolState, SigningContext, SyncCryptoStorePtr, ValidatorId) {
739746
let mut state = ProtocolState::default();
740747

741-
let (validator_pair, _seed) = ValidatorPair::generate();
742-
let validator = validator_pair.public();
743-
744748
let signing_context = SigningContext {
745749
session_index: 1,
746750
parent_hash: relay_parent.clone(),
747751
};
748752

753+
let keystore : SyncCryptoStorePtr = Arc::new(LocalKeystore::open(keystore_path.path(), None)
754+
.expect("Creates keystore"));
755+
let validator = SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, None)
756+
.expect("generating sr25519 key not to fail");
757+
749758
state.per_relay_parent = view.0.iter().map(|relay_parent| {(
750759
relay_parent.clone(),
751760
PerRelayParentData {
752761
signing_context: signing_context.clone(),
753-
validator_set: vec![validator.clone()],
762+
validator_set: vec![validator.clone().into()],
754763
one_per_validator: hashmap!{},
755764
message_received_from_peer: hashmap!{},
756765
message_sent_to_peer: hashmap!{},
@@ -759,7 +768,7 @@ mod test {
759768

760769
state.view = view;
761770

762-
(state, signing_context, validator_pair)
771+
(state, signing_context, keystore, validator.into())
763772
}
764773

765774
#[test]
@@ -780,16 +789,19 @@ mod test {
780789
parent_hash: hash_a.clone(),
781790
};
782791

783-
// validator 0 key pair
784-
let (validator_pair, _seed) = ValidatorPair::generate();
785-
let validator = validator_pair.public();
786-
787792
// another validator not part of the validatorset
788-
let (mallicious, _seed) = ValidatorPair::generate();
793+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
794+
let keystore : SyncCryptoStorePtr = Arc::new(LocalKeystore::open(keystore_path.path(), None)
795+
.expect("Creates keystore"));
796+
let malicious = SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, None)
797+
.expect("Malicious key created");
798+
let validator = SyncCryptoStore::sr25519_generate_new(&*keystore, ValidatorId::ID, None)
799+
.expect("Malicious key created");
789800

790801
let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]);
791802
let signed =
792-
Signed::<AvailabilityBitfield>::sign(payload, &signing_context, 0, &mallicious);
803+
executor::block_on(Signed::<AvailabilityBitfield>::sign(&keystore, payload, &signing_context, 0, &malicious.into()))
804+
.expect("should be signed");
793805

794806
let msg = BitfieldGossipMessage {
795807
relay_parent: hash_a.clone(),
@@ -801,7 +813,7 @@ mod test {
801813
make_subsystem_context::<BitfieldDistributionMessage, _>(pool);
802814

803815
let mut state = prewarmed_state(
804-
validator.clone(),
816+
validator.into(),
805817
signing_context.clone(),
806818
msg.clone(),
807819
vec![peer_b.clone()],
@@ -842,15 +854,17 @@ mod test {
842854
let peer_b = PeerId::random();
843855
assert_ne!(peer_a, peer_b);
844856

857+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
845858
// validator 0 key pair
846-
let (mut state, signing_context, validator_pair) =
847-
state_with_view(view![hash_a, hash_b], hash_a.clone());
859+
let (mut state, signing_context, keystore, validator) =
860+
state_with_view(view![hash_a, hash_b], hash_a.clone(), &keystore_path);
848861

849862
state.peer_views.insert(peer_b.clone(), view![hash_a]);
850863

851864
let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]);
852865
let signed =
853-
Signed::<AvailabilityBitfield>::sign(payload, &signing_context, 42, &validator_pair);
866+
executor::block_on(Signed::<AvailabilityBitfield>::sign(&keystore, payload, &signing_context, 42, &validator))
867+
.expect("should be signed");
854868

855869
let msg = BitfieldGossipMessage {
856870
relay_parent: hash_a.clone(),
@@ -896,14 +910,16 @@ mod test {
896910
let peer_b = PeerId::random();
897911
assert_ne!(peer_a, peer_b);
898912

913+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
899914
// validator 0 key pair
900-
let (mut state, signing_context, validator_pair) =
901-
state_with_view(view![hash_a, hash_b], hash_a.clone());
915+
let (mut state, signing_context, keystore, validator) =
916+
state_with_view(view![hash_a, hash_b], hash_a.clone(), &keystore_path);
902917

903918
// create a signed message by validator 0
904919
let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]);
905920
let signed_bitfield =
906-
Signed::<AvailabilityBitfield>::sign(payload, &signing_context, 0, &validator_pair);
921+
executor::block_on(Signed::<AvailabilityBitfield>::sign(&keystore, payload, &signing_context, 0, &validator))
922+
.expect("should be signed");
907923

908924
let msg = BitfieldGossipMessage {
909925
relay_parent: hash_a.clone(),
@@ -1007,13 +1023,16 @@ mod test {
10071023
let peer_b = PeerId::random();
10081024
assert_ne!(peer_a, peer_b);
10091025

1026+
let keystore_path = tempfile::tempdir().expect("Creates keystore path");
10101027
// validator 0 key pair
1011-
let (mut state, signing_context, validator_pair) = state_with_view(view![hash_a, hash_b], hash_a.clone());
1028+
let (mut state, signing_context, keystore, validator) =
1029+
state_with_view(view![hash_a, hash_b], hash_a.clone(), &keystore_path);
10121030

10131031
// create a signed message by validator 0
10141032
let payload = AvailabilityBitfield(bitvec![bitvec::order::Lsb0, u8; 1u8; 32]);
10151033
let signed_bitfield =
1016-
Signed::<AvailabilityBitfield>::sign(payload, &signing_context, 0, &validator_pair);
1034+
executor::block_on(Signed::<AvailabilityBitfield>::sign(&keystore, payload, &signing_context, 0, &validator))
1035+
.expect("should be signed");
10171036

10181037
let msg = BitfieldGossipMessage {
10191038
relay_parent: hash_a.clone(),

‎node/network/statement-distribution/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" }
2727
assert_matches = "1.3.0"
2828
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
2929
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
30+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
31+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
32+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }

‎node/network/statement-distribution/src/lib.rs

+65-27
Original file line numberDiff line numberDiff line change
@@ -978,11 +978,15 @@ impl metrics::Metrics for Metrics {
978978
#[cfg(test)]
979979
mod tests {
980980
use super::*;
981+
use std::sync::Arc;
981982
use sp_keyring::Sr25519Keyring;
983+
use sp_application_crypto::AppKey;
982984
use node_primitives::Statement;
983985
use polkadot_primitives::v1::CommittedCandidateReceipt;
984986
use assert_matches::assert_matches;
985-
use futures::executor;
987+
use futures::executor::{self, block_on};
988+
use sp_keystore::{CryptoStore, SyncCryptoStorePtr, SyncCryptoStore};
989+
use sc_keystore::LocalKeystore;
986990

987991
#[test]
988992
fn active_head_accepts_only_2_seconded_per_validator() {
@@ -1022,13 +1026,22 @@ mod tests {
10221026

10231027
let mut head_data = ActiveHeadData::new(validators, session_index);
10241028

1029+
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
1030+
let alice_public = SyncCryptoStore::sr25519_generate_new(
1031+
&*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
1032+
).unwrap();
1033+
let bob_public = SyncCryptoStore::sr25519_generate_new(
1034+
&*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed())
1035+
).unwrap();
1036+
10251037
// note A
1026-
let a_seconded_val_0 = SignedFullStatement::sign(
1038+
let a_seconded_val_0 = block_on(SignedFullStatement::sign(
1039+
&keystore,
10271040
Statement::Seconded(candidate_a.clone()),
10281041
&signing_context,
10291042
0,
1030-
&Sr25519Keyring::Alice.pair().into(),
1031-
);
1043+
&alice_public.into(),
1044+
)).expect("should be signed");
10321045
let noted = head_data.note_statement(a_seconded_val_0.clone());
10331046

10341047
assert_matches!(noted, NotedStatement::Fresh(_));
@@ -1039,42 +1052,46 @@ mod tests {
10391052
assert_matches!(noted, NotedStatement::UsefulButKnown);
10401053

10411054
// note B
1042-
let noted = head_data.note_statement(SignedFullStatement::sign(
1055+
let noted = head_data.note_statement(block_on(SignedFullStatement::sign(
1056+
&keystore,
10431057
Statement::Seconded(candidate_b.clone()),
10441058
&signing_context,
10451059
0,
1046-
&Sr25519Keyring::Alice.pair().into(),
1047-
));
1060+
&alice_public.into(),
1061+
)).expect("should be signed"));
10481062

10491063
assert_matches!(noted, NotedStatement::Fresh(_));
10501064

10511065
// note C (beyond 2 - ignored)
1052-
let noted = head_data.note_statement(SignedFullStatement::sign(
1066+
let noted = head_data.note_statement(block_on(SignedFullStatement::sign(
1067+
&keystore,
10531068
Statement::Seconded(candidate_c.clone()),
10541069
&signing_context,
10551070
0,
1056-
&Sr25519Keyring::Alice.pair().into(),
1057-
));
1071+
&alice_public.into(),
1072+
)).expect("should be signed"));
10581073

10591074
assert_matches!(noted, NotedStatement::NotUseful);
10601075

10611076
// note B (new validator)
1062-
let noted = head_data.note_statement(SignedFullStatement::sign(
1077+
let noted = head_data.note_statement(block_on(SignedFullStatement::sign(
1078+
&keystore,
10631079
Statement::Seconded(candidate_b.clone()),
10641080
&signing_context,
10651081
1,
1066-
&Sr25519Keyring::Bob.pair().into(),
1067-
));
1082+
&bob_public.into(),
1083+
)).expect("should be signed"));
10681084

10691085
assert_matches!(noted, NotedStatement::Fresh(_));
10701086

10711087
// note C (new validator)
1072-
let noted = head_data.note_statement(SignedFullStatement::sign(
1088+
let noted = head_data.note_statement(block_on(SignedFullStatement::sign(
1089+
&keystore,
10731090
Statement::Seconded(candidate_c.clone()),
10741091
&signing_context,
10751092
1,
1076-
&Sr25519Keyring::Bob.pair().into(),
1077-
));
1093+
&bob_public.into(),
1094+
)).expect("should be signed"));
10781095

10791096
assert_matches!(noted, NotedStatement::Fresh(_));
10801097
}
@@ -1252,33 +1269,48 @@ mod tests {
12521269
session_index,
12531270
};
12541271

1272+
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
1273+
1274+
let alice_public = SyncCryptoStore::sr25519_generate_new(
1275+
&*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
1276+
).unwrap();
1277+
let bob_public = SyncCryptoStore::sr25519_generate_new(
1278+
&*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Bob.to_seed())
1279+
).unwrap();
1280+
let charlie_public = SyncCryptoStore::sr25519_generate_new(
1281+
&*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Charlie.to_seed())
1282+
).unwrap();
1283+
12551284
let new_head_data = {
12561285
let mut data = ActiveHeadData::new(validators, session_index);
12571286

1258-
let noted = data.note_statement(SignedFullStatement::sign(
1287+
let noted = data.note_statement(block_on(SignedFullStatement::sign(
1288+
&keystore,
12591289
Statement::Seconded(candidate.clone()),
12601290
&signing_context,
12611291
0,
1262-
&Sr25519Keyring::Alice.pair().into(),
1263-
));
1292+
&alice_public.into(),
1293+
)).expect("should be signed"));
12641294

12651295
assert_matches!(noted, NotedStatement::Fresh(_));
12661296

1267-
let noted = data.note_statement(SignedFullStatement::sign(
1297+
let noted = data.note_statement(block_on(SignedFullStatement::sign(
1298+
&keystore,
12681299
Statement::Valid(candidate_hash),
12691300
&signing_context,
12701301
1,
1271-
&Sr25519Keyring::Bob.pair().into(),
1272-
));
1302+
&bob_public.into(),
1303+
)).expect("should be signed"));
12731304

12741305
assert_matches!(noted, NotedStatement::Fresh(_));
12751306

1276-
let noted = data.note_statement(SignedFullStatement::sign(
1307+
let noted = data.note_statement(block_on(SignedFullStatement::sign(
1308+
&keystore,
12771309
Statement::Valid(candidate_hash),
12781310
&signing_context,
12791311
2,
1280-
&Sr25519Keyring::Charlie.pair().into(),
1281-
));
1312+
&charlie_public.into(),
1313+
)).expect("should be signed"));
12821314

12831315
assert_matches!(noted, NotedStatement::Fresh(_));
12841316

@@ -1399,12 +1431,18 @@ mod tests {
13991431
session_index,
14001432
};
14011433

1434+
let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::in_memory());
1435+
let alice_public = CryptoStore::sr25519_generate_new(
1436+
&*keystore, ValidatorId::ID, Some(&Sr25519Keyring::Alice.to_seed())
1437+
).await.unwrap();
1438+
14021439
let statement = SignedFullStatement::sign(
1440+
&keystore,
14031441
Statement::Seconded(candidate),
14041442
&signing_context,
14051443
0,
1406-
&Sr25519Keyring::Alice.pair().into(),
1407-
);
1444+
&alice_public.into(),
1445+
).await.expect("should be signed");
14081446

14091447
StoredStatement {
14101448
comparator: StoredStatementComparator {

‎node/service/src/lib.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ fn new_partial<RuntimeApi, Executor>(config: &mut Configuration) -> Result<
169169

170170
let inherent_data_providers = inherents::InherentDataProviders::new();
171171

172-
let (client, backend, keystore, task_manager) =
172+
let (client, backend, keystore_container, task_manager) =
173173
service::new_full_parts::<Block, RuntimeApi, Executor>(&config)?;
174174
let client = Arc::new(client);
175175

@@ -231,7 +231,7 @@ fn new_partial<RuntimeApi, Executor>(config: &mut Configuration) -> Result<
231231

232232
let rpc_extensions_builder = {
233233
let client = client.clone();
234-
let keystore = keystore.clone();
234+
let keystore = keystore_container.sync_keystore();
235235
let transaction_pool = transaction_pool.clone();
236236
let select_chain = select_chain.clone();
237237

@@ -260,7 +260,7 @@ fn new_partial<RuntimeApi, Executor>(config: &mut Configuration) -> Result<
260260
};
261261

262262
Ok(service::PartialComponents {
263-
client, backend, task_manager, keystore, select_chain, import_queue, transaction_pool,
263+
client, backend, task_manager, keystore_container, select_chain, import_queue, transaction_pool,
264264
inherent_data_providers,
265265
other: (rpc_extensions_builder, import_setup, rpc_setup)
266266
})
@@ -338,8 +338,6 @@ pub fn new_full<RuntimeApi, Executor>(
338338
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
339339
Executor: NativeExecutionDispatch + 'static,
340340
{
341-
use sp_core::traits::BareCryptoStorePtr;
342-
343341
let is_collator = collating_for.is_some();
344342
let role = config.role.clone();
345343
let is_authority = role.is_authority() && !is_collator;
@@ -351,7 +349,7 @@ pub fn new_full<RuntimeApi, Executor>(
351349
client,
352350
backend,
353351
mut task_manager,
354-
keystore,
352+
keystore_container,
355353
select_chain,
356354
import_queue,
357355
transaction_pool,
@@ -388,7 +386,7 @@ pub fn new_full<RuntimeApi, Executor>(
388386
config,
389387
backend: backend.clone(),
390388
client: client.clone(),
391-
keystore: keystore.clone(),
389+
keystore: keystore_container.sync_keystore(),
392390
network: network.clone(),
393391
rpc_extensions_builder: Box::new(rpc_extensions_builder),
394392
transaction_pool: transaction_pool.clone(),
@@ -454,7 +452,7 @@ pub fn new_full<RuntimeApi, Executor>(
454452
);
455453

456454
let babe_config = babe::BabeParams {
457-
keystore: keystore.clone(),
455+
keystore: keystore_container.sync_keystore(),
458456
client: client.clone(),
459457
select_chain,
460458
block_import,
@@ -473,7 +471,7 @@ pub fn new_full<RuntimeApi, Executor>(
473471
// if the node isn't actively participating in consensus then it doesn't
474472
// need a keystore, regardless of which protocol we use below.
475473
let keystore_opt = if is_authority {
476-
Some(keystore.clone() as BareCryptoStorePtr)
474+
Some(keystore_container.sync_keystore())
477475
} else {
478476
None
479477
};
@@ -546,7 +544,7 @@ pub fn new_full<RuntimeApi, Executor>(
546544
Role::Authority { ref sentry_nodes } => (
547545
sentry_nodes.clone(),
548546
authority_discovery::Role::Authority (
549-
keystore.clone(),
547+
keystore_container.keystore(),
550548
),
551549
),
552550
Role::Sentry {..} => (
@@ -560,17 +558,17 @@ pub fn new_full<RuntimeApi, Executor>(
560558
let dht_event_stream = network_event_stream.filter_map(|e| async move { match e {
561559
Event::Dht(e) => Some(e),
562560
_ => None,
563-
}}).boxed();
561+
}});
564562
let (authority_discovery_worker, _service) = authority_discovery::new_worker_and_service(
565563
client.clone(),
566564
network.clone(),
567565
sentries,
568-
dht_event_stream,
566+
Box::pin(dht_event_stream),
569567
authority_discovery_role,
570568
prometheus_registry.clone(),
571569
);
572570

573-
task_manager.spawn_handle().spawn("authority-discovery-worker", authority_discovery_worker);
571+
task_manager.spawn_handle().spawn("authority-discovery-worker", authority_discovery_worker.run());
574572
}
575573
}
576574

@@ -598,7 +596,7 @@ fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(TaskManage
598596
set_prometheus_registry(&mut config)?;
599597
use sc_client_api::backend::RemoteBackend;
600598

601-
let (client, backend, keystore, mut task_manager, on_demand) =
599+
let (client, backend, keystore_container, mut task_manager, on_demand) =
602600
service::new_light_parts::<Block, Runtime, Dispatch>(&config)?;
603601

604602
let select_chain = sc_consensus::LongestChain::new(backend.clone());
@@ -686,7 +684,7 @@ fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(TaskManage
686684
task_manager: &mut task_manager,
687685
telemetry_connection_sinks: service::TelemetryConnectionSinks::default(),
688686
config,
689-
keystore,
687+
keystore: keystore_container.sync_keystore(),
690688
backend,
691689
transaction_pool,
692690
client,

‎node/subsystem-util/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ polkadot-node-subsystem = { path = "../subsystem" }
2222
polkadot-primitives = { path = "../../primitives" }
2323
polkadot-statement-table = { path = "../../statement-table" }
2424

25-
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
2625
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
2726
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
27+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "master" }
28+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
2829
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
2930

3031
[dev-dependencies]

‎node/subsystem-util/src/lib.rs

+29-19
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,23 @@ use futures::{
3737
task,
3838
};
3939
use futures_timer::Delay;
40-
use sc_keystore::KeyStorePtr;
4140
use parity_scale_codec::Encode;
4241
use pin_project::{pin_project, pinned_drop};
4342
use polkadot_primitives::v1::{
4443
CandidateEvent, CommittedCandidateReceipt, CoreState, EncodeAs, PersistedValidationData,
4544
GroupRotationInfo, Hash, Id as ParaId, ValidationData, OccupiedCoreAssumption,
4645
SessionIndex, Signed, SigningContext, ValidationCode, ValidatorId, ValidatorIndex,
47-
ValidatorPair,
4846
};
49-
use sp_core::{Pair, traits::SpawnNamed};
47+
use sp_core::{
48+
traits::SpawnNamed,
49+
Public
50+
};
51+
use sp_application_crypto::AppKey;
52+
use sp_keystore::{
53+
CryptoStore,
54+
SyncCryptoStorePtr,
55+
Error as KeystoreError,
56+
};
5057
use std::{
5158
collections::HashMap,
5259
convert::{TryFrom, TryInto},
@@ -281,11 +288,13 @@ specialize_requests_ctx! {
281288
}
282289

283290
/// From the given set of validators, find the first key we can sign with, if any.
284-
pub fn signing_key(validators: &[ValidatorId], keystore: &KeyStorePtr) -> Option<ValidatorPair> {
285-
let keystore = keystore.read();
286-
validators
287-
.iter()
288-
.find_map(|v| keystore.key_pair::<ValidatorPair>(&v).ok())
291+
pub async fn signing_key(validators: &[ValidatorId], keystore: SyncCryptoStorePtr) -> Option<ValidatorId> {
292+
for v in validators.iter() {
293+
if CryptoStore::has_keys(&*keystore, &[(v.to_raw_vec(), ValidatorId::ID)]).await {
294+
return Some(v.clone());
295+
}
296+
}
297+
None
289298
}
290299

291300
/// Local validator information
@@ -294,15 +303,15 @@ pub fn signing_key(validators: &[ValidatorId], keystore: &KeyStorePtr) -> Option
294303
/// relay chain block.
295304
pub struct Validator {
296305
signing_context: SigningContext,
297-
key: ValidatorPair,
306+
key: ValidatorId,
298307
index: ValidatorIndex,
299308
}
300309

301310
impl Validator {
302311
/// Get a struct representing this node's validator if this node is in fact a validator in the context of the given block.
303312
pub async fn new<FromJob>(
304313
parent: Hash,
305-
keystore: KeyStorePtr,
314+
keystore: SyncCryptoStorePtr,
306315
mut sender: mpsc::Sender<FromJob>,
307316
) -> Result<Self, Error>
308317
where
@@ -324,22 +333,22 @@ impl Validator {
324333

325334
let validators = validators?;
326335

327-
Self::construct(&validators, signing_context, keystore)
336+
Self::construct(&validators, signing_context, keystore).await
328337
}
329338

330339
/// Construct a validator instance without performing runtime fetches.
331340
///
332341
/// This can be useful if external code also needs the same data.
333-
pub fn construct(
342+
pub async fn construct(
334343
validators: &[ValidatorId],
335344
signing_context: SigningContext,
336-
keystore: KeyStorePtr,
345+
keystore: SyncCryptoStorePtr,
337346
) -> Result<Self, Error> {
338-
let key = signing_key(validators, &keystore).ok_or(Error::NotAValidator)?;
347+
let key = signing_key(validators, keystore).await.ok_or(Error::NotAValidator)?;
339348
let index = validators
340349
.iter()
341350
.enumerate()
342-
.find(|(_, k)| k == &&key.public())
351+
.find(|(_, k)| k == &&key)
343352
.map(|(idx, _)| idx as ValidatorIndex)
344353
.expect("signing_key would have already returned NotAValidator if the item we're searching for isn't in this list; qed");
345354

@@ -352,7 +361,7 @@ impl Validator {
352361

353362
/// Get this validator's id.
354363
pub fn id(&self) -> ValidatorId {
355-
self.key.public()
364+
self.key.clone()
356365
}
357366

358367
/// Get this validator's local index.
@@ -366,11 +375,12 @@ impl Validator {
366375
}
367376

368377
/// Sign a payload with this validator
369-
pub fn sign<Payload: EncodeAs<RealPayload>, RealPayload: Encode>(
378+
pub async fn sign<Payload: EncodeAs<RealPayload>, RealPayload: Encode>(
370379
&self,
380+
keystore: SyncCryptoStorePtr,
371381
payload: Payload,
372-
) -> Signed<Payload, RealPayload> {
373-
Signed::sign(payload, &self.signing_context, self.index, &self.key)
382+
) -> Result<Signed<Payload, RealPayload>, KeystoreError> {
383+
Signed::sign(&keystore, payload, &self.signing_context, self.index, &self.key).await
374384
}
375385

376386
/// Validate the payload with this validator

‎primitives/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ parity-scale-codec = { version = "1.3.4", default-features = false, features = [
1010
primitives = { package = "sp-core", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
1111
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
1212
application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
13+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
1314
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
1415
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
1516
sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -36,6 +37,8 @@ std = [
3637
"inherents/std",
3738
"trie/std",
3839
"sp-api/std",
40+
"sp-authority-discovery/std",
41+
"sp-keystore",
3942
"sp-std/std",
4043
"sp-version/std",
4144
"sp-staking/std",

‎primitives/src/v0.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,22 @@
1818
//! perspective.
1919
2020
use sp_std::prelude::*;
21+
#[cfg(feature = "std")]
22+
use sp_std::convert::TryInto;
2123
use sp_std::cmp::Ordering;
24+
2225
use parity_scale_codec::{Encode, Decode};
2326
use bitvec::vec::BitVec;
24-
2527
#[cfg(feature = "std")]
2628
use serde::{Serialize, Deserialize};
2729

2830
#[cfg(feature = "std")]
29-
use primitives::crypto::Pair;
31+
use sp_keystore::{CryptoStore, SyncCryptoStorePtr, Error as KeystoreError};
3032
use primitives::RuntimeDebug;
3133
use runtime_primitives::traits::{AppVerify, Block as BlockT};
3234
use inherents::InherentIdentifier;
35+
#[cfg(feature = "std")]
36+
use application_crypto::AppKey;
3337
use application_crypto::KeyTypeId;
3438

3539
pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT, Verify, IdentifyAccount};
@@ -863,20 +867,26 @@ impl<Payload: EncodeAs<RealPayload>, RealPayload: Encode> Signed<Payload, RealPa
863867

864868
/// Sign this payload with the given context and key, storing the validator index.
865869
#[cfg(feature = "std")]
866-
pub fn sign<H: Encode>(
870+
pub async fn sign<H: Encode>(
871+
keystore: &SyncCryptoStorePtr,
867872
payload: Payload,
868873
context: &SigningContext<H>,
869874
validator_index: ValidatorIndex,
870-
key: &ValidatorPair,
871-
) -> Self {
875+
key: &ValidatorId,
876+
) -> Result<Self, KeystoreError> {
872877
let data = Self::payload_data(&payload, context);
873-
let signature = key.sign(&data);
874-
Self {
878+
let signature: ValidatorSignature = CryptoStore::sign_with(
879+
&**keystore,
880+
ValidatorId::ID,
881+
&key.into(),
882+
&data,
883+
).await?.try_into().map_err(|_| KeystoreError::KeyNotSupported(ValidatorId::ID))?;
884+
Ok(Self {
875885
payload,
876886
validator_index,
877887
signature,
878888
real_payload: std::marker::PhantomData,
879-
}
889+
})
880890
}
881891

882892
/// Validate the payload given the context and public key.

‎rpc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jsonrpc-core = "15.0.0"
99
polkadot-primitives = { path = "../primitives" }
1010
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
1111
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
12+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
1213
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
1314
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
1415
sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }

‎rpc/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use sp_block_builder::BlockBuilder;
2727
use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError};
2828
use sp_consensus::SelectChain;
2929
use sp_consensus_babe::BabeApi;
30+
use sp_keystore::SyncCryptoStorePtr;
3031
use sc_client_api::light::{Fetcher, RemoteBlockchain};
3132
use sc_consensus_babe::Epoch;
3233
use sc_finality_grandpa::FinalityProofProvider;
@@ -54,7 +55,7 @@ pub struct BabeDeps {
5455
/// BABE pending epoch changes.
5556
pub shared_epoch_changes: sc_consensus_epochs::SharedEpochChanges<Block, Epoch>,
5657
/// The keystore that manages the keys of the node.
57-
pub keystore: sc_keystore::KeyStorePtr,
58+
pub keystore: SyncCryptoStorePtr,
5859
}
5960

6061
/// Dependencies for GRANDPA

‎runtime/parachains/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master
2020
sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
2121
sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
2222
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
23+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
2324

2425
pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
2526
pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -40,6 +41,7 @@ rand = { version = "0.7", default-features = false }
4041
rand_chacha = { version = "0.2.2", default-features = false }
4142

4243
[dev-dependencies]
44+
futures = "0.3.4"
4345
hex-literal = "0.2.1"
4446
keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" }
4547
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -51,6 +53,7 @@ pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "m
5153
serde_json = "1.0.41"
5254
libsecp256k1 = "0.3.2"
5355
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
56+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master"}
5457

5558

5659
[features]
@@ -67,6 +70,7 @@ std = [
6770
"inherents/std",
6871
"sp-core/std",
6972
"sp-api/std",
73+
"sp-keystore",
7074
"sp-std/std",
7175
"sp-io/std",
7276
"frame-support/std",

‎runtime/parachains/src/inclusion.rs

+111-55
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.