mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 21:27:57 +00:00
Remove Parent Hash to Session mapping (#928)
* Adds a SigningContext type * Bump spec versions * Fixes requested changes * Bump ParachainHost api_version and guard signing_context call * Improve error message * If there is no signing_context api use default value Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
@@ -34,12 +34,11 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
use codec::Encode;
|
||||
use polkadot_primitives::Hash;
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, Chain, DutyRoster, AbridgedCandidateReceipt,
|
||||
Statement as PrimitiveStatement,
|
||||
PoVBlock, ErasureChunk, ValidatorSignature, ValidatorIndex,
|
||||
ValidatorPair, ValidatorId,
|
||||
ValidatorPair, ValidatorId, SigningContext,
|
||||
};
|
||||
use primitives::Pair;
|
||||
|
||||
@@ -135,9 +134,13 @@ pub struct GroupInfo {
|
||||
/// Sign a table statement against a parent hash.
|
||||
/// The actual message signed is the encoded statement concatenated with the
|
||||
/// parent hash.
|
||||
pub fn sign_table_statement(statement: &Statement, key: &ValidatorPair, parent_hash: &Hash) -> ValidatorSignature {
|
||||
pub fn sign_table_statement(
|
||||
statement: &Statement,
|
||||
key: &ValidatorPair,
|
||||
signing_context: &SigningContext,
|
||||
) -> ValidatorSignature {
|
||||
let mut encoded = PrimitiveStatement::from(statement).encode();
|
||||
encoded.extend(parent_hash.as_ref());
|
||||
encoded.extend(signing_context.encode());
|
||||
|
||||
key.sign(&encoded)
|
||||
}
|
||||
@@ -147,12 +150,12 @@ pub fn check_statement(
|
||||
statement: &Statement,
|
||||
signature: &ValidatorSignature,
|
||||
signer: ValidatorId,
|
||||
parent_hash: &Hash,
|
||||
signing_context: &SigningContext,
|
||||
) -> bool {
|
||||
use runtime_primitives::traits::AppVerify;
|
||||
|
||||
let mut encoded = PrimitiveStatement::from(statement).encode();
|
||||
encoded.extend(parent_hash.as_ref());
|
||||
encoded.extend(signing_context.encode());
|
||||
|
||||
signature.verify(&encoded[..], &signer)
|
||||
}
|
||||
@@ -214,11 +217,19 @@ mod tests {
|
||||
fn sign_and_check_statement() {
|
||||
let statement: Statement = GenericStatement::Valid([1; 32].into());
|
||||
let parent_hash = [2; 32].into();
|
||||
let signing_context = SigningContext {
|
||||
session_index: Default::default(),
|
||||
parent_hash,
|
||||
};
|
||||
|
||||
let sig = sign_table_statement(&statement, &Sr25519Keyring::Alice.pair().into(), &parent_hash);
|
||||
let sig = sign_table_statement(&statement, &Sr25519Keyring::Alice.pair().into(), &signing_context);
|
||||
|
||||
assert!(check_statement(&statement, &sig, Sr25519Keyring::Alice.public().into(), &parent_hash));
|
||||
assert!(!check_statement(&statement, &sig, Sr25519Keyring::Alice.public().into(), &[0xff; 32].into()));
|
||||
assert!(!check_statement(&statement, &sig, Sr25519Keyring::Bob.public().into(), &parent_hash));
|
||||
let wrong_signing_context = SigningContext {
|
||||
session_index: Default::default(),
|
||||
parent_hash: [0xff; 32].into(),
|
||||
};
|
||||
assert!(check_statement(&statement, &sig, Sr25519Keyring::Alice.public().into(), &signing_context));
|
||||
assert!(!check_statement(&statement, &sig, Sr25519Keyring::Alice.public().into(), &wrong_signing_context));
|
||||
assert!(!check_statement(&statement, &sig, Sr25519Keyring::Bob.public().into(), &signing_context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ use table::{self, Table, Context as TableContextTrait};
|
||||
use polkadot_primitives::{Block, Hash};
|
||||
use polkadot_primitives::parachain::{
|
||||
Id as ParaId, AbridgedCandidateReceipt, ValidatorPair, ValidatorId,
|
||||
AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex,
|
||||
AttestedCandidate, ParachainHost, PoVBlock, ValidatorIndex, SigningContext,
|
||||
};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
@@ -48,7 +48,7 @@ pub use table::{SignedStatement, Statement};
|
||||
pub use table::generic::Statement as GenericStatement;
|
||||
|
||||
struct TableContext {
|
||||
parent_hash: Hash,
|
||||
signing_context: SigningContext,
|
||||
key: Option<Arc<ValidatorPair>>,
|
||||
groups: HashMap<ParaId, GroupInfo>,
|
||||
validators: Vec<ValidatorId>,
|
||||
@@ -87,7 +87,12 @@ impl TableContext {
|
||||
fn sign_statement(&self, statement: table::Statement) -> Option<table::SignedStatement> {
|
||||
self.local_index().and_then(move |sender|
|
||||
self.key.as_ref()
|
||||
.map(|key| crate::sign_table_statement(&statement, key, &self.parent_hash).into())
|
||||
.map(|key| crate::sign_table_statement(
|
||||
&statement,
|
||||
key,
|
||||
&self.signing_context,
|
||||
).into()
|
||||
)
|
||||
.map(move |signature| table::SignedStatement { statement, signature, sender })
|
||||
)
|
||||
}
|
||||
@@ -189,7 +194,7 @@ impl SharedTableInner {
|
||||
|
||||
work.map(|work| ParachainWork {
|
||||
availability_store: self.availability_store.clone(),
|
||||
relay_parent: context.parent_hash.clone(),
|
||||
relay_parent: context.signing_context.parent_hash.clone(),
|
||||
work,
|
||||
max_block_data_size,
|
||||
n_validators: context.validators.len(),
|
||||
@@ -408,12 +413,12 @@ impl SharedTable {
|
||||
validators: Vec<ValidatorId>,
|
||||
groups: HashMap<ParaId, GroupInfo>,
|
||||
key: Option<Arc<ValidatorPair>>,
|
||||
parent_hash: Hash,
|
||||
signing_context: SigningContext,
|
||||
availability_store: AvailabilityStore,
|
||||
max_block_data_size: Option<u64>,
|
||||
) -> Self {
|
||||
SharedTable {
|
||||
context: Arc::new(TableContext { groups, key, parent_hash, validators: validators.clone(), }),
|
||||
context: Arc::new(TableContext { groups, key, signing_context, validators: validators.clone(), }),
|
||||
max_block_data_size,
|
||||
inner: Arc::new(Mutex::new(SharedTableInner {
|
||||
table: Table::default(),
|
||||
@@ -425,8 +430,8 @@ impl SharedTable {
|
||||
}
|
||||
|
||||
/// Get the parent hash this table should hold statements localized to.
|
||||
pub fn consensus_parent_hash(&self) -> &Hash {
|
||||
&self.context.parent_hash
|
||||
pub fn signing_context(&self) -> &SigningContext {
|
||||
&self.context.signing_context
|
||||
}
|
||||
|
||||
/// Get the local validator session key.
|
||||
@@ -654,7 +659,11 @@ mod tests {
|
||||
let mut groups = HashMap::new();
|
||||
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
let parent_hash = Hash::default();
|
||||
let signing_context = SigningContext {
|
||||
session_index: Default::default(),
|
||||
parent_hash: parent_hash.clone(),
|
||||
};
|
||||
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
@@ -673,7 +682,7 @@ mod tests {
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
signing_context.clone(),
|
||||
AvailabilityStore::new_in_memory(DummyErasureNetworking),
|
||||
None,
|
||||
);
|
||||
@@ -684,7 +693,11 @@ mod tests {
|
||||
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key.into(), &parent_hash);
|
||||
let signature = crate::sign_table_statement(
|
||||
&candidate_statement,
|
||||
&validity_other_key.into(),
|
||||
&signing_context,
|
||||
);
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
@@ -702,7 +715,11 @@ mod tests {
|
||||
let mut groups = HashMap::new();
|
||||
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
let parent_hash = Hash::default();
|
||||
let signing_context = SigningContext {
|
||||
session_index: Default::default(),
|
||||
parent_hash: parent_hash.clone(),
|
||||
};
|
||||
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
@@ -721,7 +738,7 @@ mod tests {
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
signing_context.clone(),
|
||||
AvailabilityStore::new_in_memory(DummyErasureNetworking),
|
||||
None,
|
||||
);
|
||||
@@ -732,7 +749,11 @@ mod tests {
|
||||
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key.into(), &parent_hash);
|
||||
let signature = crate::sign_table_statement(
|
||||
&candidate_statement,
|
||||
&validity_other_key.into(),
|
||||
&signing_context,
|
||||
);
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
@@ -874,7 +895,11 @@ mod tests {
|
||||
let mut groups = HashMap::new();
|
||||
|
||||
let para_id = ParaId::from(1);
|
||||
let parent_hash = Default::default();
|
||||
let parent_hash = Hash::default();
|
||||
let signing_context = SigningContext {
|
||||
session_index: Default::default(),
|
||||
parent_hash: parent_hash.clone(),
|
||||
};
|
||||
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
@@ -893,7 +918,7 @@ mod tests {
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
signing_context.clone(),
|
||||
AvailabilityStore::new_in_memory(DummyErasureNetworking),
|
||||
None,
|
||||
);
|
||||
@@ -905,7 +930,11 @@ mod tests {
|
||||
let candidate_hash = candidate.hash();
|
||||
let candidate_statement = GenericStatement::Candidate(candidate);
|
||||
|
||||
let signature = crate::sign_table_statement(&candidate_statement, &validity_other_key.into(), &parent_hash);
|
||||
let signature = crate::sign_table_statement(
|
||||
&candidate_statement,
|
||||
&validity_other_key.into(),
|
||||
&signing_context,
|
||||
);
|
||||
let signed_statement = ::table::generic::SignedStatement {
|
||||
statement: candidate_statement,
|
||||
signature: signature.into(),
|
||||
@@ -934,7 +963,11 @@ mod tests {
|
||||
|
||||
let para_id = ParaId::from(1);
|
||||
let pov_block = pov_block_with_data(vec![1, 2, 3]);
|
||||
let parent_hash = Default::default();
|
||||
let parent_hash = Hash::default();
|
||||
let signing_context = SigningContext {
|
||||
session_index: Default::default(),
|
||||
parent_hash: parent_hash.clone(),
|
||||
};
|
||||
|
||||
let local_key = Sr25519Keyring::Alice.pair();
|
||||
let local_id: ValidatorId = local_key.public().into();
|
||||
@@ -952,7 +985,7 @@ mod tests {
|
||||
[local_id, validity_other].to_vec(),
|
||||
groups,
|
||||
Some(local_key.clone()),
|
||||
parent_hash,
|
||||
signing_context.clone(),
|
||||
AvailabilityStore::new_in_memory(DummyErasureNetworking),
|
||||
None,
|
||||
);
|
||||
|
||||
@@ -36,7 +36,7 @@ use consensus::SelectChain;
|
||||
use futures::{future::ready, prelude::*, task::{Spawn, SpawnExt}};
|
||||
use polkadot_primitives::{Block, Hash, BlockId};
|
||||
use polkadot_primitives::parachain::{
|
||||
Chain, ParachainHost, Id as ParaId, ValidatorIndex, ValidatorId, ValidatorPair,
|
||||
Chain, ParachainHost, Id as ParaId, ValidatorIndex, ValidatorId, ValidatorPair, SigningContext,
|
||||
};
|
||||
use babe_primitives::BabeApi;
|
||||
use keystore::KeyStorePtr;
|
||||
@@ -44,7 +44,7 @@ use sp_api::{ApiExt, ProvideRuntimeApi};
|
||||
use runtime_primitives::traits::HashFor;
|
||||
use availability_store::Store as AvailabilityStore;
|
||||
|
||||
use log::{warn, error, info, debug};
|
||||
use log::{warn, error, info, debug, trace};
|
||||
|
||||
use super::{Network, Collators, SharedTable, TableRouter};
|
||||
use crate::Error;
|
||||
@@ -334,11 +334,29 @@ impl<C, N, P, SP> ParachainValidationInstances<C, N, P, SP> where
|
||||
}
|
||||
}
|
||||
|
||||
let api = self.client.runtime_api();
|
||||
|
||||
let signing_context = if api.has_api_with::<dyn ParachainHost<Block, Error = ()>, _>(
|
||||
&BlockId::hash(parent_hash),
|
||||
|version| version >= 3,
|
||||
)? {
|
||||
api.signing_context(&id)?
|
||||
} else {
|
||||
trace!(
|
||||
target: "validation",
|
||||
"Expected runtime with ParachainHost version >= 3",
|
||||
);
|
||||
SigningContext {
|
||||
session_index: 0,
|
||||
parent_hash,
|
||||
}
|
||||
};
|
||||
|
||||
let table = Arc::new(SharedTable::new(
|
||||
validators.clone(),
|
||||
group_info,
|
||||
sign_with,
|
||||
parent_hash,
|
||||
signing_context,
|
||||
self.availability_store.clone(),
|
||||
max_block_data_size,
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user