Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Don't repeatedly lookup keys in babe_epochAuthorship rpc function #5962

Merged
merged 3 commits into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion client/consensus/babe/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,20 @@ impl<B, C, SC> BabeApi for BabeRPCHandler<B, C, SC>

let mut claims: HashMap<AuthorityId, EpochAuthorship> = HashMap::new();

let key_pairs = {
let keystore = keystore.read();
epoch.authorities.iter().enumerate()
.flat_map(|(i, a)| {
keystore.key_pair::<sp_consensus_babe::AuthorityPair>(&a.0).ok().map(|kp| (kp, i))
})
.collect::<Vec<_>>()
};

for slot_number in epoch_start..epoch_end {
let epoch = epoch_data(&shared_epoch, &client, &babe_config, slot_number, &select_chain)?;
if let Some((claim, key)) = authorship::claim_slot(slot_number, &epoch, &keystore) {
if let Some((claim, key)) =
authorship::claim_slot_using_key_pairs(slot_number, &epoch, &key_pairs)
{
match claim {
PreDigest::Primary { .. } => {
claims.entry(key.public()).or_default().primary.push(slot_number);
Expand Down
58 changes: 32 additions & 26 deletions client/consensus/babe/src/authorship.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub(super) fn secondary_slot_author(
fn claim_secondary_slot(
slot_number: SlotNumber,
epoch: &Epoch,
keystore: &KeyStorePtr,
key_pairs: &Vec<(AuthorityPair, usize)>,
Demi-Marie marked this conversation as resolved.
Show resolved Hide resolved
author_secondary_vrf: bool,
) -> Option<(PreDigest, AuthorityPair)> {
let Epoch { authorities, randomness, epoch_index, .. } = epoch;
Expand All @@ -139,14 +139,7 @@ fn claim_secondary_slot(
*randomness,
)?;

let keystore = keystore.read();

for (pair, authority_index) in authorities.iter()
.enumerate()
.flat_map(|(i, a)| {
keystore.key_pair::<AuthorityPair>(&a.0).ok().map(|kp| (kp, i))
})
{
for (pair, authority_index) in key_pairs {
if pair.public() == *expected_author {
let pre_digest = if author_secondary_vrf {
let transcript = super::authorship::make_transcript(
Expand All @@ -161,16 +154,16 @@ fn claim_secondary_slot(
slot_number,
vrf_output: VRFOutput(s.0.to_output()),
vrf_proof: VRFProof(s.1),
authority_index: authority_index as u32,
authority_index: *authority_index as u32,
})
} else {
PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot_number,
authority_index: authority_index as u32,
authority_index: *authority_index as u32,
})
};

return Some((pre_digest, pair));
return Some((pre_digest, pair.clone()));
}
}

Expand All @@ -186,15 +179,34 @@ pub fn claim_slot(
epoch: &Epoch,
keystore: &KeyStorePtr,
) -> Option<(PreDigest, AuthorityPair)> {
claim_primary_slot(slot_number, epoch, epoch.config.c, keystore)
let key_pairs = {
let keystore = keystore.read();
epoch.authorities.iter()
.enumerate()
.flat_map(|(i, a)| {
keystore.key_pair::<AuthorityPair>(&a.0).ok().map(|kp| (kp, i))
})
.collect::<Vec<_>>()
};
claim_slot_using_key_pairs(slot_number, epoch, &key_pairs)
}

/// Like `claim_slot`, but allows passing an explicit set of key pairs. Useful if we intend
/// to make repeated calls for different slots using the same key pairs.
pub fn claim_slot_using_key_pairs(
slot_number: SlotNumber,
epoch: &Epoch,
key_pairs: &Vec<(AuthorityPair, usize)>,
Demi-Marie marked this conversation as resolved.
Show resolved Hide resolved
) -> Option<(PreDigest, AuthorityPair)> {
claim_primary_slot(slot_number, epoch, epoch.config.c, &key_pairs)
.or_else(|| {
if epoch.config.allowed_slots.is_secondary_plain_slots_allowed() ||
epoch.config.allowed_slots.is_secondary_vrf_slots_allowed()
{
claim_secondary_slot(
slot_number,
&epoch,
keystore,
&key_pairs,
epoch.config.allowed_slots.is_secondary_vrf_slots_allowed(),
)
} else {
Expand All @@ -216,39 +228,33 @@ fn claim_primary_slot(
slot_number: SlotNumber,
epoch: &Epoch,
c: (u64, u64),
keystore: &KeyStorePtr,
key_pairs: &Vec<(AuthorityPair, usize)>,
Demi-Marie marked this conversation as resolved.
Show resolved Hide resolved
) -> Option<(PreDigest, AuthorityPair)> {
let Epoch { authorities, randomness, epoch_index, .. } = epoch;
let keystore = keystore.read();

for (pair, authority_index) in authorities.iter()
.enumerate()
.flat_map(|(i, a)| {
keystore.key_pair::<AuthorityPair>(&a.0).ok().map(|kp| (kp, i))
})
{
for (pair, authority_index) in key_pairs {
let transcript = super::authorship::make_transcript(randomness, slot_number, *epoch_index);

// Compute the threshold we will use.
//
// We already checked that authorities contains `key.public()`, so it can't
// be empty. Therefore, this division in `calculate_threshold` is safe.
let threshold = super::authorship::calculate_primary_threshold(c, authorities, authority_index);
let threshold = super::authorship::calculate_primary_threshold(c, authorities, *authority_index);

let pre_digest = get_keypair(&pair)
let pre_digest = get_keypair(pair)
.vrf_sign_after_check(transcript, |inout| super::authorship::check_primary_threshold(inout, threshold))
.map(|s| {
PreDigest::Primary(PrimaryPreDigest {
slot_number,
vrf_output: VRFOutput(s.0.to_output()),
vrf_proof: VRFProof(s.1),
authority_index: authority_index as u32,
authority_index: *authority_index as u32,
})
});

// early exit on first successful claim
if let Some(pre_digest) = pre_digest {
return Some((pre_digest, pair));
return Some((pre_digest, pair.clone()));
}
}

Expand Down