mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-20 23:15:42 +00:00
Make CandidateHash a real type (#1916)
* Make `CandidateHash` a real type This pr adds a new type `CandidateHash` that is used instead of the opaque `Hash` type. This helps to ensure on the type system level that we are passing the correct types. This pr also fixes wrong usage of `relay_parent` as `candidate_hash` when communicating with the av storage. * Update core-primitives/src/lib.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * Wrap the lines Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
This commit is contained in:
@@ -33,7 +33,7 @@ use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
|
||||
use polkadot_primitives::v1::{
|
||||
Hash, AvailableData, BlockNumber, CandidateEvent, ErasureChunk, ValidatorIndex,
|
||||
Hash, AvailableData, BlockNumber, CandidateEvent, ErasureChunk, ValidatorIndex, CandidateHash,
|
||||
};
|
||||
use polkadot_subsystem::{
|
||||
FromOverseer, OverseerSignal, SubsystemError, Subsystem, SubsystemContext, SpawnedSubsystem,
|
||||
@@ -242,7 +242,7 @@ enum CandidateState {
|
||||
|
||||
#[derive(Debug, Decode, Encode, Eq)]
|
||||
struct PoVPruningRecord {
|
||||
candidate_hash: Hash,
|
||||
candidate_hash: CandidateHash,
|
||||
block_number: BlockNumber,
|
||||
candidate_state: CandidateState,
|
||||
prune_at: PruningDelay,
|
||||
@@ -272,7 +272,7 @@ impl PartialOrd for PoVPruningRecord {
|
||||
|
||||
#[derive(Debug, Decode, Encode, Eq)]
|
||||
struct ChunkPruningRecord {
|
||||
candidate_hash: Hash,
|
||||
candidate_hash: CandidateHash,
|
||||
block_number: BlockNumber,
|
||||
candidate_state: CandidateState,
|
||||
chunk_index: u32,
|
||||
@@ -387,11 +387,11 @@ impl AvailabilityStoreSubsystem {
|
||||
}
|
||||
}
|
||||
|
||||
fn available_data_key(candidate_hash: &Hash) -> Vec<u8> {
|
||||
fn available_data_key(candidate_hash: &CandidateHash) -> Vec<u8> {
|
||||
(candidate_hash, 0i8).encode()
|
||||
}
|
||||
|
||||
fn erasure_chunk_key(candidate_hash: &Hash, index: u32) -> Vec<u8> {
|
||||
fn erasure_chunk_key(candidate_hash: &CandidateHash, index: u32) -> Vec<u8> {
|
||||
(candidate_hash, index, 0i8).encode()
|
||||
}
|
||||
|
||||
@@ -564,7 +564,7 @@ where
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Updating pruning record for finalized block {}",
|
||||
record.candidate_hash,
|
||||
record.block_number,
|
||||
);
|
||||
|
||||
record.prune_at = PruningDelay::into_the_future(
|
||||
@@ -583,7 +583,7 @@ where
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Updating chunk pruning record for finalized block {}",
|
||||
record.candidate_hash,
|
||||
record.block_number,
|
||||
);
|
||||
|
||||
record.prune_at = PruningDelay::into_the_future(
|
||||
@@ -620,7 +620,7 @@ where
|
||||
|
||||
for event in events.into_iter() {
|
||||
if let CandidateEvent::CandidateIncluded(receipt, _) = event {
|
||||
log::trace!(target: LOG_TARGET, "Candidate {} was included", receipt.hash());
|
||||
log::trace!(target: LOG_TARGET, "Candidate {:?} was included", receipt.hash());
|
||||
included.insert(receipt.hash());
|
||||
}
|
||||
}
|
||||
@@ -729,7 +729,10 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn available_data(db: &Arc<dyn KeyValueDB>, candidate_hash: &Hash) -> Option<StoredAvailableData> {
|
||||
fn available_data(
|
||||
db: &Arc<dyn KeyValueDB>,
|
||||
candidate_hash: &CandidateHash,
|
||||
) -> Option<StoredAvailableData> {
|
||||
query_inner(db, columns::DATA, &available_data_key(candidate_hash))
|
||||
}
|
||||
|
||||
@@ -835,7 +838,7 @@ where
|
||||
|
||||
fn store_available_data(
|
||||
subsystem: &mut AvailabilityStoreSubsystem,
|
||||
candidate_hash: &Hash,
|
||||
candidate_hash: &CandidateHash,
|
||||
id: Option<ValidatorIndex>,
|
||||
n_validators: u32,
|
||||
available_data: AvailableData,
|
||||
@@ -872,7 +875,7 @@ fn store_available_data(
|
||||
}
|
||||
|
||||
let pruning_record = PoVPruningRecord {
|
||||
candidate_hash: candidate_hash.clone(),
|
||||
candidate_hash: *candidate_hash,
|
||||
block_number,
|
||||
candidate_state: CandidateState::Stored,
|
||||
prune_at,
|
||||
@@ -901,7 +904,7 @@ fn store_available_data(
|
||||
|
||||
fn store_chunk(
|
||||
subsystem: &mut AvailabilityStoreSubsystem,
|
||||
candidate_hash: &Hash,
|
||||
candidate_hash: &CandidateHash,
|
||||
_n_validators: u32,
|
||||
chunk: ErasureChunk,
|
||||
block_number: BlockNumber,
|
||||
@@ -952,7 +955,7 @@ fn store_chunk(
|
||||
|
||||
fn get_chunk(
|
||||
subsystem: &mut AvailabilityStoreSubsystem,
|
||||
candidate_hash: &Hash,
|
||||
candidate_hash: &CandidateHash,
|
||||
index: u32,
|
||||
) -> Result<Option<ErasureChunk>, Error> {
|
||||
if let Some(chunk) = query_inner(
|
||||
@@ -981,7 +984,11 @@ fn get_chunk(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn query_inner<D: Decode>(db: &Arc<dyn KeyValueDB>, column: u32, key: &[u8]) -> Option<D> {
|
||||
fn query_inner<D: Decode>(
|
||||
db: &Arc<dyn KeyValueDB>,
|
||||
column: u32,
|
||||
key: &[u8],
|
||||
) -> Option<D> {
|
||||
match db.get(column, key) {
|
||||
Ok(Some(raw)) => {
|
||||
let res = D::decode(&mut &raw[..]).expect("all stored data serialized correctly; qed");
|
||||
|
||||
@@ -27,7 +27,7 @@ use smallvec::smallvec;
|
||||
|
||||
use polkadot_primitives::v1::{
|
||||
AvailableData, BlockData, CandidateDescriptor, CandidateReceipt, HeadData,
|
||||
PersistedValidationData, PoV, Id as ParaId,
|
||||
PersistedValidationData, PoV, Id as ParaId, CandidateHash,
|
||||
};
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
use polkadot_subsystem::{
|
||||
@@ -199,7 +199,7 @@ fn runtime_api_error_does_not_stop_the_subsystem() {
|
||||
|
||||
// but that's fine, we're still alive
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let candidate_hash = Hash::repeat_byte(33);
|
||||
let candidate_hash = CandidateHash(Hash::repeat_byte(33));
|
||||
let validator_index = 5;
|
||||
let query_chunk = AvailabilityStoreMessage::QueryChunk(
|
||||
candidate_hash,
|
||||
@@ -220,7 +220,7 @@ fn store_chunk_works() {
|
||||
test_harness(PruningConfig::default(), store.clone(), |test_harness| async move {
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
let relay_parent = Hash::repeat_byte(32);
|
||||
let candidate_hash = Hash::repeat_byte(33);
|
||||
let candidate_hash = CandidateHash(Hash::repeat_byte(33));
|
||||
let validator_index = 5;
|
||||
|
||||
let chunk = ErasureChunk {
|
||||
@@ -273,7 +273,7 @@ fn store_block_works() {
|
||||
let test_state = TestState::default();
|
||||
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
let candidate_hash = Hash::from([1; 32]);
|
||||
let candidate_hash = CandidateHash(Hash::from([1; 32]));
|
||||
let validator_index = 5;
|
||||
let n_validators = 10;
|
||||
|
||||
@@ -327,7 +327,7 @@ fn store_pov_and_query_chunk_works() {
|
||||
|
||||
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
let candidate_hash = Hash::from([1; 32]);
|
||||
let candidate_hash = CandidateHash(Hash::from([1; 32]));
|
||||
let n_validators = 10;
|
||||
|
||||
let pov = PoV {
|
||||
@@ -370,7 +370,7 @@ fn stored_but_not_included_chunk_is_pruned() {
|
||||
|
||||
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
let candidate_hash = Hash::repeat_byte(1);
|
||||
let candidate_hash = CandidateHash(Hash::repeat_byte(1));
|
||||
let relay_parent = Hash::repeat_byte(2);
|
||||
let validator_index = 5;
|
||||
|
||||
@@ -425,7 +425,7 @@ fn stored_but_not_included_data_is_pruned() {
|
||||
|
||||
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
let candidate_hash = Hash::repeat_byte(1);
|
||||
let candidate_hash = CandidateHash(Hash::repeat_byte(1));
|
||||
let n_validators = 10;
|
||||
|
||||
let pov = PoV {
|
||||
@@ -852,7 +852,7 @@ fn forkfullness_works() {
|
||||
|
||||
async fn query_available_data(
|
||||
virtual_overseer: &mut test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>,
|
||||
candidate_hash: Hash,
|
||||
candidate_hash: CandidateHash,
|
||||
) -> Option<AvailableData> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
@@ -864,7 +864,7 @@ async fn query_available_data(
|
||||
|
||||
async fn query_chunk(
|
||||
virtual_overseer: &mut test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>,
|
||||
candidate_hash: Hash,
|
||||
candidate_hash: CandidateHash,
|
||||
index: u32,
|
||||
) -> Option<ErasureChunk> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
@@ -32,7 +32,7 @@ use futures::{
|
||||
use sp_keystore::SyncCryptoStorePtr;
|
||||
use polkadot_primitives::v1::{
|
||||
CommittedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorId,
|
||||
ValidatorIndex, SigningContext, PoV,
|
||||
ValidatorIndex, SigningContext, PoV, CandidateHash,
|
||||
CandidateDescriptor, AvailableData, ValidatorSignature, Hash, CandidateReceipt,
|
||||
CandidateCommitments, CoreState, CoreIndex, CollatorId, ValidationOutputs,
|
||||
};
|
||||
@@ -103,12 +103,12 @@ struct CandidateBackingJob {
|
||||
/// The collator required to author the candidate, if any.
|
||||
required_collator: Option<CollatorId>,
|
||||
/// We issued `Valid` or `Invalid` statements on about these candidates.
|
||||
issued_statements: HashSet<Hash>,
|
||||
issued_statements: HashSet<CandidateHash>,
|
||||
/// `Some(h)` if this job has already issues `Seconded` statemt for some candidate with `h` hash.
|
||||
seconded: Option<Hash>,
|
||||
seconded: Option<CandidateHash>,
|
||||
/// The candidates that are includable, by hash. Each entry here indicates
|
||||
/// that we've sent the provisioner the backed candidate.
|
||||
backed: HashSet<Hash>,
|
||||
backed: HashSet<CandidateHash>,
|
||||
/// We have already reported misbehaviors for these validators.
|
||||
reported_misbehavior_for: HashSet<ValidatorIndex>,
|
||||
keystore: SyncCryptoStorePtr,
|
||||
@@ -131,12 +131,12 @@ struct TableContext {
|
||||
|
||||
impl TableContextTrait for TableContext {
|
||||
type AuthorityId = ValidatorIndex;
|
||||
type Digest = Hash;
|
||||
type Digest = CandidateHash;
|
||||
type GroupId = ParaId;
|
||||
type Signature = ValidatorSignature;
|
||||
type Candidate = CommittedCandidateReceipt;
|
||||
|
||||
fn candidate_digest(candidate: &CommittedCandidateReceipt) -> Hash {
|
||||
fn candidate_digest(candidate: &CommittedCandidateReceipt) -> CandidateHash {
|
||||
candidate.hash()
|
||||
}
|
||||
|
||||
@@ -341,6 +341,7 @@ impl CandidateBackingJob {
|
||||
// the collator, do not make available and report the collator.
|
||||
let commitments_check = self.make_pov_available(
|
||||
pov,
|
||||
candidate_hash,
|
||||
validation_data,
|
||||
outputs,
|
||||
|commitments| if commitments.hash() == candidate.commitments_hash {
|
||||
@@ -525,7 +526,7 @@ impl CandidateBackingJob {
|
||||
&mut self,
|
||||
summary: TableSummary,
|
||||
) -> Result<(), Error> {
|
||||
let candidate_hash = summary.candidate.clone();
|
||||
let candidate_hash = summary.candidate;
|
||||
|
||||
if self.issued_statements.contains(&candidate_hash) {
|
||||
return Ok(())
|
||||
@@ -559,6 +560,7 @@ impl CandidateBackingJob {
|
||||
// If validation produces a new set of commitments, we vote the candidate as invalid.
|
||||
let commitments_check = self.make_pov_available(
|
||||
(&*pov).clone(),
|
||||
candidate_hash,
|
||||
validation_data,
|
||||
outputs,
|
||||
|commitments| if commitments == expected_commitments {
|
||||
@@ -667,12 +669,13 @@ impl CandidateBackingJob {
|
||||
&mut self,
|
||||
id: Option<ValidatorIndex>,
|
||||
n_validators: u32,
|
||||
candidate_hash: CandidateHash,
|
||||
available_data: AvailableData,
|
||||
) -> Result<(), Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.tx_from.send(FromJob::AvailabilityStore(
|
||||
AvailabilityStoreMessage::StoreAvailableData(
|
||||
self.parent,
|
||||
candidate_hash,
|
||||
id,
|
||||
n_validators,
|
||||
available_data,
|
||||
@@ -694,6 +697,7 @@ impl CandidateBackingJob {
|
||||
async fn make_pov_available<T, E>(
|
||||
&mut self,
|
||||
pov: PoV,
|
||||
candidate_hash: CandidateHash,
|
||||
validation_data: polkadot_primitives::v1::PersistedValidationData,
|
||||
outputs: ValidationOutputs,
|
||||
with_commitments: impl FnOnce(CandidateCommitments) -> Result<T, E>,
|
||||
@@ -727,6 +731,7 @@ impl CandidateBackingJob {
|
||||
self.store_available_data(
|
||||
self.table_context.validator.as_ref().map(|v| v.index()),
|
||||
self.table_context.validators.len() as u32,
|
||||
candidate_hash,
|
||||
available_data,
|
||||
).await?;
|
||||
|
||||
@@ -1206,8 +1211,8 @@ mod tests {
|
||||
assert_matches!(
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::AvailabilityStore(
|
||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
||||
) if parent_hash == test_state.relay_parent => {
|
||||
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||
) if candidate_hash == candidate.hash() => {
|
||||
tx.send(Ok(())).unwrap();
|
||||
}
|
||||
);
|
||||
@@ -1333,8 +1338,8 @@ mod tests {
|
||||
assert_matches!(
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::AvailabilityStore(
|
||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
||||
) if parent_hash == test_state.relay_parent => {
|
||||
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||
) if candidate_hash == candidate_a.hash() => {
|
||||
tx.send(Ok(())).unwrap();
|
||||
}
|
||||
);
|
||||
@@ -1482,8 +1487,8 @@ mod tests {
|
||||
assert_matches!(
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::AvailabilityStore(
|
||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
||||
) if parent_hash == test_state.relay_parent => {
|
||||
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||
) if candidate_hash == candidate_a.hash() => {
|
||||
tx.send(Ok(())).unwrap();
|
||||
}
|
||||
);
|
||||
@@ -1665,8 +1670,8 @@ mod tests {
|
||||
assert_matches!(
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::AvailabilityStore(
|
||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
||||
) if parent_hash == test_state.relay_parent => {
|
||||
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||
) if candidate_hash == candidate_b.hash() => {
|
||||
tx.send(Ok(())).unwrap();
|
||||
}
|
||||
);
|
||||
|
||||
@@ -174,7 +174,7 @@ async fn get_core_availability(
|
||||
.await
|
||||
.send(
|
||||
AvailabilityStoreMessage::QueryChunkAvailability(
|
||||
committed_candidate_receipt.descriptor.pov_hash,
|
||||
committed_candidate_receipt.hash(),
|
||||
validator_idx,
|
||||
tx,
|
||||
).into(),
|
||||
|
||||
Reference in New Issue
Block a user