mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 22:11:06 +00:00
Don't pass validators' public keys with attestations (#186)
* Don't pass validators' public keys with attestations * Update statement-table's Misbehaviour typedef * Update network/router * Expand MessageValidationData * Try to fix tests * Extend ApiContext * Remove 'index_mapping' from the SessionParams * Construct index_mapping from authorities * Move index_mapping to TableContext * Add test for index_mapping order
This commit is contained in:
committed by
Robert Habermeier
parent
36dd42523d
commit
e8fcb43fcf
@@ -187,9 +187,9 @@ pub trait Network {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct GroupInfo {
|
||||
/// Authorities meant to check validity of candidates.
|
||||
pub validity_guarantors: HashSet<SessionKey>,
|
||||
validity_guarantors: HashSet<SessionKey>,
|
||||
/// Number of votes needed for validity.
|
||||
pub needed_validity: usize,
|
||||
needed_validity: usize,
|
||||
}
|
||||
|
||||
/// Sign a table statement against a parent hash.
|
||||
@@ -347,7 +347,7 @@ impl<C, N, P> ParachainValidation<C, N, P> where
|
||||
|
||||
debug!(target: "validation", "Active parachains: {:?}", active_parachains);
|
||||
|
||||
let table = Arc::new(SharedTable::new(group_info, sign_with.clone(), parent_hash, self.extrinsic_store.clone()));
|
||||
let table = Arc::new(SharedTable::new(authorities, group_info, sign_with.clone(), parent_hash, self.extrinsic_store.clone()));
|
||||
let router = self.network.communication_for(
|
||||
table.clone(),
|
||||
outgoing,
|
||||
|
||||
@@ -23,9 +23,8 @@ use std::sync::Arc;
|
||||
use extrinsic_store::{Data, Store as ExtrinsicStore};
|
||||
use table::{self, Table, Context as TableContextTrait};
|
||||
use polkadot_primitives::{Block, BlockId, Hash, SessionKey};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Collation, Extrinsic, CandidateReceipt,
|
||||
AttestedCandidate, ParachainHost, PoVBlock
|
||||
use polkadot_primitives::parachain::{Id as ParaId, Collation, Extrinsic, CandidateReceipt,
|
||||
AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex,
|
||||
};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
@@ -46,11 +45,17 @@ struct TableContext {
|
||||
parent_hash: Hash,
|
||||
key: Arc<ed25519::Pair>,
|
||||
groups: HashMap<ParaId, GroupInfo>,
|
||||
index_mapping: HashMap<ValidatorIndex, SessionKey>,
|
||||
}
|
||||
|
||||
impl table::Context for TableContext {
|
||||
fn is_member_of(&self, authority: &SessionKey, group: &ParaId) -> bool {
|
||||
self.groups.get(group).map_or(false, |g| g.validity_guarantors.contains(authority))
|
||||
fn is_member_of(&self, authority: ValidatorIndex, group: &ParaId) -> bool {
|
||||
let key = match self.index_mapping.get(&authority) {
|
||||
Some(val) => val,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
self.groups.get(group).map_or(false, |g| g.validity_guarantors.get(&key).is_some())
|
||||
}
|
||||
|
||||
fn requisite_votes(&self, group: &ParaId) -> usize {
|
||||
@@ -63,13 +68,23 @@ impl TableContext {
|
||||
self.key.public().into()
|
||||
}
|
||||
|
||||
fn local_index(&self) -> ValidatorIndex {
|
||||
let id = self.local_id();
|
||||
self
|
||||
.index_mapping
|
||||
.iter()
|
||||
.find(|(_, k)| k == &&id)
|
||||
.map(|(i, _)| *i)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn sign_statement(&self, statement: table::Statement) -> table::SignedStatement {
|
||||
let signature = ::sign_table_statement(&statement, &self.key, &self.parent_hash).into();
|
||||
|
||||
table::SignedStatement {
|
||||
statement,
|
||||
signature,
|
||||
sender: self.local_id(),
|
||||
sender: self.local_index(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,9 +146,9 @@ impl SharedTableInner {
|
||||
|
||||
self.update_trackers(&summary.candidate, context);
|
||||
|
||||
let local_id = context.local_id();
|
||||
let local_index = context.local_index();
|
||||
|
||||
let para_member = context.is_member_of(&local_id, &summary.group_id);
|
||||
let para_member = context.is_member_of(local_index, &summary.group_id);
|
||||
|
||||
let digest = &summary.candidate;
|
||||
|
||||
@@ -375,13 +390,15 @@ impl SharedTable {
|
||||
/// Provide the key to sign with, and the parent hash of the relay chain
|
||||
/// block being built.
|
||||
pub fn new(
|
||||
authorities: &[ed25519::Public],
|
||||
groups: HashMap<ParaId, GroupInfo>,
|
||||
key: Arc<ed25519::Pair>,
|
||||
parent_hash: Hash,
|
||||
extrinsic_store: ExtrinsicStore,
|
||||
) -> Self {
|
||||
SharedTable {
|
||||
context: Arc::new(TableContext { groups, key, parent_hash }),
|
||||
let index_mapping = authorities.iter().enumerate().map(|(i, k)| (i as ValidatorIndex, k.clone())).collect();
|
||||
Self {
|
||||
context: Arc::new(TableContext { groups, key, parent_hash, index_mapping, }),
|
||||
inner: Arc::new(Mutex::new(SharedTableInner {
|
||||
table: Table::default(),
|
||||
validated: HashMap::new(),
|
||||
@@ -513,7 +530,7 @@ impl SharedTable {
|
||||
}
|
||||
|
||||
/// Get all witnessed misbehavior.
|
||||
pub fn get_misbehavior(&self) -> HashMap<SessionKey, table::Misbehavior> {
|
||||
pub fn get_misbehavior(&self) -> HashMap<ValidatorIndex, table::Misbehavior> {
|
||||
self.inner.lock().table.get_misbehavior().clone()
|
||||
}
|
||||
|
||||
@@ -534,6 +551,11 @@ impl SharedTable {
|
||||
|
||||
rx
|
||||
}
|
||||
|
||||
/// Returns id of the validator corresponding to the given index.
|
||||
pub fn index_to_id(&self, index: ValidatorIndex) -> Option<SessionKey> {
|
||||
self.context.index_mapping.get(&index).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -577,13 +599,15 @@ mod tests {
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_index = 1;
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
validity_guarantors: [local_id, validity_other.clone()].iter().cloned().collect(),
|
||||
validity_guarantors: [local_id.clone(), validity_other.clone()].iter().cloned().collect(),
|
||||
needed_validity: 2,
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
groups,
|
||||
local_key.clone(),
|
||||
parent_hash,
|
||||
@@ -607,7 +631,7 @@ mod tests {
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
sender: validity_other,
|
||||
sender: validity_other_index,
|
||||
};
|
||||
|
||||
shared_table.import_remote_statement(
|
||||
@@ -628,13 +652,15 @@ mod tests {
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_index = 1;
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
validity_guarantors: [local_id, validity_other.clone()].iter().cloned().collect(),
|
||||
validity_guarantors: [local_id.clone(), validity_other.clone()].iter().cloned().collect(),
|
||||
needed_validity: 1,
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
groups,
|
||||
local_key.clone(),
|
||||
parent_hash,
|
||||
@@ -658,7 +684,7 @@ mod tests {
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
sender: validity_other,
|
||||
sender: validity_other_index,
|
||||
};
|
||||
|
||||
shared_table.import_remote_statement(
|
||||
@@ -758,13 +784,15 @@ mod tests {
|
||||
|
||||
let validity_other_key = AuthorityKeyring::Bob.pair();
|
||||
let validity_other = validity_other_key.public();
|
||||
let validity_other_index = 1;
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
validity_guarantors: [local_id, validity_other.clone()].iter().cloned().collect(),
|
||||
validity_guarantors: [local_id.clone(), validity_other.clone()].iter().cloned().collect(),
|
||||
needed_validity: 1,
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
groups,
|
||||
local_key.clone(),
|
||||
parent_hash,
|
||||
@@ -789,7 +817,7 @@ mod tests {
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
sender: validity_other,
|
||||
sender: validity_other_index,
|
||||
};
|
||||
|
||||
let _a = shared_table.import_remote_statement(
|
||||
@@ -823,11 +851,12 @@ mod tests {
|
||||
let validity_other = validity_other_key.public();
|
||||
|
||||
groups.insert(para_id, GroupInfo {
|
||||
validity_guarantors: [local_id, validity_other].iter().cloned().collect(),
|
||||
validity_guarantors: [local_id.clone(), validity_other.clone()].iter().cloned().collect(),
|
||||
needed_validity: 1,
|
||||
});
|
||||
|
||||
let shared_table = SharedTable::new(
|
||||
&[local_id, validity_other],
|
||||
groups,
|
||||
local_key.clone(),
|
||||
parent_hash,
|
||||
@@ -861,4 +890,28 @@ mod tests {
|
||||
|
||||
assert!(a.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn index_mapping_from_authorities() {
|
||||
let authorities_set: &[&[_]] = &[
|
||||
&[],
|
||||
&[AuthorityKeyring::Alice.pair().public()],
|
||||
&[AuthorityKeyring::Alice.pair().public(), AuthorityKeyring::Bob.pair().public()],
|
||||
&[AuthorityKeyring::Bob.pair().public(), AuthorityKeyring::Alice.pair().public()],
|
||||
&[AuthorityKeyring::Alice.pair().public(), AuthorityKeyring::Bob.pair().public(), AuthorityKeyring::Charlie.pair().public()],
|
||||
&[AuthorityKeyring::Charlie.pair().public(), AuthorityKeyring::Bob.pair().public(), AuthorityKeyring::Alice.pair().public()],
|
||||
];
|
||||
|
||||
for authorities in authorities_set {
|
||||
let shared_table = SharedTable::new(
|
||||
authorities,
|
||||
HashMap::new(),
|
||||
Arc::new(AuthorityKeyring::Alice.pair()),
|
||||
Default::default(),
|
||||
ExtrinsicStore::new_in_memory(),
|
||||
);
|
||||
let expected_mapping = authorities.iter().enumerate().map(|(i, k)| (i as ValidatorIndex, k.clone())).collect();
|
||||
assert_eq!(shared_table.context.index_mapping, expected_mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user