mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 14:01:02 +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:
@@ -50,6 +50,14 @@ pub type ChainId = u32;
|
|||||||
/// A hash of some data used by the relay chain.
|
/// A hash of some data used by the relay chain.
|
||||||
pub type Hash = sp_core::H256;
|
pub type Hash = sp_core::H256;
|
||||||
|
|
||||||
|
/// Unit type wrapper around [`Hash`] that represents a candidate hash.
|
||||||
|
///
|
||||||
|
/// This type is produced by [`CandidateReceipt::hash`].
|
||||||
|
///
|
||||||
|
/// This type makes it easy to enforce that a hash is a candidate hash on the type level.
|
||||||
|
#[derive(Clone, Copy, codec::Encode, codec::Decode, Hash, Eq, PartialEq, Debug, Default)]
|
||||||
|
pub struct CandidateHash(pub Hash);
|
||||||
|
|
||||||
/// Index of a transaction in the relay chain. 32-bit should be plenty.
|
/// Index of a transaction in the relay chain. 32-bit should be plenty.
|
||||||
pub type Nonce = u32;
|
pub type Nonce = u32;
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ use kvdb_rocksdb::{Database, DatabaseConfig};
|
|||||||
use kvdb::{KeyValueDB, DBTransaction};
|
use kvdb::{KeyValueDB, DBTransaction};
|
||||||
|
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
Hash, AvailableData, BlockNumber, CandidateEvent, ErasureChunk, ValidatorIndex,
|
Hash, AvailableData, BlockNumber, CandidateEvent, ErasureChunk, ValidatorIndex, CandidateHash,
|
||||||
};
|
};
|
||||||
use polkadot_subsystem::{
|
use polkadot_subsystem::{
|
||||||
FromOverseer, OverseerSignal, SubsystemError, Subsystem, SubsystemContext, SpawnedSubsystem,
|
FromOverseer, OverseerSignal, SubsystemError, Subsystem, SubsystemContext, SpawnedSubsystem,
|
||||||
@@ -242,7 +242,7 @@ enum CandidateState {
|
|||||||
|
|
||||||
#[derive(Debug, Decode, Encode, Eq)]
|
#[derive(Debug, Decode, Encode, Eq)]
|
||||||
struct PoVPruningRecord {
|
struct PoVPruningRecord {
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
candidate_state: CandidateState,
|
candidate_state: CandidateState,
|
||||||
prune_at: PruningDelay,
|
prune_at: PruningDelay,
|
||||||
@@ -272,7 +272,7 @@ impl PartialOrd for PoVPruningRecord {
|
|||||||
|
|
||||||
#[derive(Debug, Decode, Encode, Eq)]
|
#[derive(Debug, Decode, Encode, Eq)]
|
||||||
struct ChunkPruningRecord {
|
struct ChunkPruningRecord {
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
candidate_state: CandidateState,
|
candidate_state: CandidateState,
|
||||||
chunk_index: u32,
|
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()
|
(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()
|
(candidate_hash, index, 0i8).encode()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ where
|
|||||||
log::trace!(
|
log::trace!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Updating pruning record for finalized block {}",
|
"Updating pruning record for finalized block {}",
|
||||||
record.candidate_hash,
|
record.block_number,
|
||||||
);
|
);
|
||||||
|
|
||||||
record.prune_at = PruningDelay::into_the_future(
|
record.prune_at = PruningDelay::into_the_future(
|
||||||
@@ -583,7 +583,7 @@ where
|
|||||||
log::trace!(
|
log::trace!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Updating chunk pruning record for finalized block {}",
|
"Updating chunk pruning record for finalized block {}",
|
||||||
record.candidate_hash,
|
record.block_number,
|
||||||
);
|
);
|
||||||
|
|
||||||
record.prune_at = PruningDelay::into_the_future(
|
record.prune_at = PruningDelay::into_the_future(
|
||||||
@@ -620,7 +620,7 @@ where
|
|||||||
|
|
||||||
for event in events.into_iter() {
|
for event in events.into_iter() {
|
||||||
if let CandidateEvent::CandidateIncluded(receipt, _) = event {
|
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());
|
included.insert(receipt.hash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -729,7 +729,10 @@ where
|
|||||||
Ok(())
|
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))
|
query_inner(db, columns::DATA, &available_data_key(candidate_hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,7 +838,7 @@ where
|
|||||||
|
|
||||||
fn store_available_data(
|
fn store_available_data(
|
||||||
subsystem: &mut AvailabilityStoreSubsystem,
|
subsystem: &mut AvailabilityStoreSubsystem,
|
||||||
candidate_hash: &Hash,
|
candidate_hash: &CandidateHash,
|
||||||
id: Option<ValidatorIndex>,
|
id: Option<ValidatorIndex>,
|
||||||
n_validators: u32,
|
n_validators: u32,
|
||||||
available_data: AvailableData,
|
available_data: AvailableData,
|
||||||
@@ -872,7 +875,7 @@ fn store_available_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pruning_record = PoVPruningRecord {
|
let pruning_record = PoVPruningRecord {
|
||||||
candidate_hash: candidate_hash.clone(),
|
candidate_hash: *candidate_hash,
|
||||||
block_number,
|
block_number,
|
||||||
candidate_state: CandidateState::Stored,
|
candidate_state: CandidateState::Stored,
|
||||||
prune_at,
|
prune_at,
|
||||||
@@ -901,7 +904,7 @@ fn store_available_data(
|
|||||||
|
|
||||||
fn store_chunk(
|
fn store_chunk(
|
||||||
subsystem: &mut AvailabilityStoreSubsystem,
|
subsystem: &mut AvailabilityStoreSubsystem,
|
||||||
candidate_hash: &Hash,
|
candidate_hash: &CandidateHash,
|
||||||
_n_validators: u32,
|
_n_validators: u32,
|
||||||
chunk: ErasureChunk,
|
chunk: ErasureChunk,
|
||||||
block_number: BlockNumber,
|
block_number: BlockNumber,
|
||||||
@@ -952,7 +955,7 @@ fn store_chunk(
|
|||||||
|
|
||||||
fn get_chunk(
|
fn get_chunk(
|
||||||
subsystem: &mut AvailabilityStoreSubsystem,
|
subsystem: &mut AvailabilityStoreSubsystem,
|
||||||
candidate_hash: &Hash,
|
candidate_hash: &CandidateHash,
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> Result<Option<ErasureChunk>, Error> {
|
) -> Result<Option<ErasureChunk>, Error> {
|
||||||
if let Some(chunk) = query_inner(
|
if let Some(chunk) = query_inner(
|
||||||
@@ -981,7 +984,11 @@ fn get_chunk(
|
|||||||
Ok(None)
|
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) {
|
match db.get(column, key) {
|
||||||
Ok(Some(raw)) => {
|
Ok(Some(raw)) => {
|
||||||
let res = D::decode(&mut &raw[..]).expect("all stored data serialized correctly; qed");
|
let res = D::decode(&mut &raw[..]).expect("all stored data serialized correctly; qed");
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use smallvec::smallvec;
|
|||||||
|
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
AvailableData, BlockData, CandidateDescriptor, CandidateReceipt, HeadData,
|
AvailableData, BlockData, CandidateDescriptor, CandidateReceipt, HeadData,
|
||||||
PersistedValidationData, PoV, Id as ParaId,
|
PersistedValidationData, PoV, Id as ParaId, CandidateHash,
|
||||||
};
|
};
|
||||||
use polkadot_node_subsystem_util::TimeoutExt;
|
use polkadot_node_subsystem_util::TimeoutExt;
|
||||||
use polkadot_subsystem::{
|
use polkadot_subsystem::{
|
||||||
@@ -199,7 +199,7 @@ fn runtime_api_error_does_not_stop_the_subsystem() {
|
|||||||
|
|
||||||
// but that's fine, we're still alive
|
// but that's fine, we're still alive
|
||||||
let (tx, rx) = oneshot::channel();
|
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 validator_index = 5;
|
||||||
let query_chunk = AvailabilityStoreMessage::QueryChunk(
|
let query_chunk = AvailabilityStoreMessage::QueryChunk(
|
||||||
candidate_hash,
|
candidate_hash,
|
||||||
@@ -220,7 +220,7 @@ fn store_chunk_works() {
|
|||||||
test_harness(PruningConfig::default(), store.clone(), |test_harness| async move {
|
test_harness(PruningConfig::default(), store.clone(), |test_harness| async move {
|
||||||
let TestHarness { mut virtual_overseer } = test_harness;
|
let TestHarness { mut virtual_overseer } = test_harness;
|
||||||
let relay_parent = Hash::repeat_byte(32);
|
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 validator_index = 5;
|
||||||
|
|
||||||
let chunk = ErasureChunk {
|
let chunk = ErasureChunk {
|
||||||
@@ -273,7 +273,7 @@ fn store_block_works() {
|
|||||||
let test_state = TestState::default();
|
let test_state = TestState::default();
|
||||||
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||||
let TestHarness { mut virtual_overseer } = test_harness;
|
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 validator_index = 5;
|
||||||
let n_validators = 10;
|
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 {
|
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||||
let TestHarness { mut virtual_overseer } = test_harness;
|
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 n_validators = 10;
|
||||||
|
|
||||||
let pov = PoV {
|
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 {
|
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||||
let TestHarness { mut virtual_overseer } = test_harness;
|
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 relay_parent = Hash::repeat_byte(2);
|
||||||
let validator_index = 5;
|
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 {
|
test_harness(test_state.pruning_config.clone(), store.clone(), |test_harness| async move {
|
||||||
let TestHarness { mut virtual_overseer } = test_harness;
|
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 n_validators = 10;
|
||||||
|
|
||||||
let pov = PoV {
|
let pov = PoV {
|
||||||
@@ -852,7 +852,7 @@ fn forkfullness_works() {
|
|||||||
|
|
||||||
async fn query_available_data(
|
async fn query_available_data(
|
||||||
virtual_overseer: &mut test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>,
|
virtual_overseer: &mut test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
) -> Option<AvailableData> {
|
) -> Option<AvailableData> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|
||||||
@@ -864,7 +864,7 @@ async fn query_available_data(
|
|||||||
|
|
||||||
async fn query_chunk(
|
async fn query_chunk(
|
||||||
virtual_overseer: &mut test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>,
|
virtual_overseer: &mut test_helpers::TestSubsystemContextHandle<AvailabilityStoreMessage>,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> Option<ErasureChunk> {
|
) -> Option<ErasureChunk> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use futures::{
|
|||||||
use sp_keystore::SyncCryptoStorePtr;
|
use sp_keystore::SyncCryptoStorePtr;
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
CommittedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorId,
|
CommittedCandidateReceipt, BackedCandidate, Id as ParaId, ValidatorId,
|
||||||
ValidatorIndex, SigningContext, PoV,
|
ValidatorIndex, SigningContext, PoV, CandidateHash,
|
||||||
CandidateDescriptor, AvailableData, ValidatorSignature, Hash, CandidateReceipt,
|
CandidateDescriptor, AvailableData, ValidatorSignature, Hash, CandidateReceipt,
|
||||||
CandidateCommitments, CoreState, CoreIndex, CollatorId, ValidationOutputs,
|
CandidateCommitments, CoreState, CoreIndex, CollatorId, ValidationOutputs,
|
||||||
};
|
};
|
||||||
@@ -103,12 +103,12 @@ struct CandidateBackingJob {
|
|||||||
/// The collator required to author the candidate, if any.
|
/// The collator required to author the candidate, if any.
|
||||||
required_collator: Option<CollatorId>,
|
required_collator: Option<CollatorId>,
|
||||||
/// We issued `Valid` or `Invalid` statements on about these candidates.
|
/// 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.
|
/// `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
|
/// The candidates that are includable, by hash. Each entry here indicates
|
||||||
/// that we've sent the provisioner the backed candidate.
|
/// that we've sent the provisioner the backed candidate.
|
||||||
backed: HashSet<Hash>,
|
backed: HashSet<CandidateHash>,
|
||||||
/// We have already reported misbehaviors for these validators.
|
/// We have already reported misbehaviors for these validators.
|
||||||
reported_misbehavior_for: HashSet<ValidatorIndex>,
|
reported_misbehavior_for: HashSet<ValidatorIndex>,
|
||||||
keystore: SyncCryptoStorePtr,
|
keystore: SyncCryptoStorePtr,
|
||||||
@@ -131,12 +131,12 @@ struct TableContext {
|
|||||||
|
|
||||||
impl TableContextTrait for TableContext {
|
impl TableContextTrait for TableContext {
|
||||||
type AuthorityId = ValidatorIndex;
|
type AuthorityId = ValidatorIndex;
|
||||||
type Digest = Hash;
|
type Digest = CandidateHash;
|
||||||
type GroupId = ParaId;
|
type GroupId = ParaId;
|
||||||
type Signature = ValidatorSignature;
|
type Signature = ValidatorSignature;
|
||||||
type Candidate = CommittedCandidateReceipt;
|
type Candidate = CommittedCandidateReceipt;
|
||||||
|
|
||||||
fn candidate_digest(candidate: &CommittedCandidateReceipt) -> Hash {
|
fn candidate_digest(candidate: &CommittedCandidateReceipt) -> CandidateHash {
|
||||||
candidate.hash()
|
candidate.hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,6 +341,7 @@ impl CandidateBackingJob {
|
|||||||
// the collator, do not make available and report the collator.
|
// the collator, do not make available and report the collator.
|
||||||
let commitments_check = self.make_pov_available(
|
let commitments_check = self.make_pov_available(
|
||||||
pov,
|
pov,
|
||||||
|
candidate_hash,
|
||||||
validation_data,
|
validation_data,
|
||||||
outputs,
|
outputs,
|
||||||
|commitments| if commitments.hash() == candidate.commitments_hash {
|
|commitments| if commitments.hash() == candidate.commitments_hash {
|
||||||
@@ -525,7 +526,7 @@ impl CandidateBackingJob {
|
|||||||
&mut self,
|
&mut self,
|
||||||
summary: TableSummary,
|
summary: TableSummary,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let candidate_hash = summary.candidate.clone();
|
let candidate_hash = summary.candidate;
|
||||||
|
|
||||||
if self.issued_statements.contains(&candidate_hash) {
|
if self.issued_statements.contains(&candidate_hash) {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
@@ -559,6 +560,7 @@ impl CandidateBackingJob {
|
|||||||
// If validation produces a new set of commitments, we vote the candidate as invalid.
|
// If validation produces a new set of commitments, we vote the candidate as invalid.
|
||||||
let commitments_check = self.make_pov_available(
|
let commitments_check = self.make_pov_available(
|
||||||
(&*pov).clone(),
|
(&*pov).clone(),
|
||||||
|
candidate_hash,
|
||||||
validation_data,
|
validation_data,
|
||||||
outputs,
|
outputs,
|
||||||
|commitments| if commitments == expected_commitments {
|
|commitments| if commitments == expected_commitments {
|
||||||
@@ -667,12 +669,13 @@ impl CandidateBackingJob {
|
|||||||
&mut self,
|
&mut self,
|
||||||
id: Option<ValidatorIndex>,
|
id: Option<ValidatorIndex>,
|
||||||
n_validators: u32,
|
n_validators: u32,
|
||||||
|
candidate_hash: CandidateHash,
|
||||||
available_data: AvailableData,
|
available_data: AvailableData,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
self.tx_from.send(FromJob::AvailabilityStore(
|
self.tx_from.send(FromJob::AvailabilityStore(
|
||||||
AvailabilityStoreMessage::StoreAvailableData(
|
AvailabilityStoreMessage::StoreAvailableData(
|
||||||
self.parent,
|
candidate_hash,
|
||||||
id,
|
id,
|
||||||
n_validators,
|
n_validators,
|
||||||
available_data,
|
available_data,
|
||||||
@@ -694,6 +697,7 @@ impl CandidateBackingJob {
|
|||||||
async fn make_pov_available<T, E>(
|
async fn make_pov_available<T, E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pov: PoV,
|
pov: PoV,
|
||||||
|
candidate_hash: CandidateHash,
|
||||||
validation_data: polkadot_primitives::v1::PersistedValidationData,
|
validation_data: polkadot_primitives::v1::PersistedValidationData,
|
||||||
outputs: ValidationOutputs,
|
outputs: ValidationOutputs,
|
||||||
with_commitments: impl FnOnce(CandidateCommitments) -> Result<T, E>,
|
with_commitments: impl FnOnce(CandidateCommitments) -> Result<T, E>,
|
||||||
@@ -727,6 +731,7 @@ impl CandidateBackingJob {
|
|||||||
self.store_available_data(
|
self.store_available_data(
|
||||||
self.table_context.validator.as_ref().map(|v| v.index()),
|
self.table_context.validator.as_ref().map(|v| v.index()),
|
||||||
self.table_context.validators.len() as u32,
|
self.table_context.validators.len() as u32,
|
||||||
|
candidate_hash,
|
||||||
available_data,
|
available_data,
|
||||||
).await?;
|
).await?;
|
||||||
|
|
||||||
@@ -1206,8 +1211,8 @@ mod tests {
|
|||||||
assert_matches!(
|
assert_matches!(
|
||||||
virtual_overseer.recv().await,
|
virtual_overseer.recv().await,
|
||||||
AllMessages::AvailabilityStore(
|
AllMessages::AvailabilityStore(
|
||||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||||
) if parent_hash == test_state.relay_parent => {
|
) if candidate_hash == candidate.hash() => {
|
||||||
tx.send(Ok(())).unwrap();
|
tx.send(Ok(())).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1333,8 +1338,8 @@ mod tests {
|
|||||||
assert_matches!(
|
assert_matches!(
|
||||||
virtual_overseer.recv().await,
|
virtual_overseer.recv().await,
|
||||||
AllMessages::AvailabilityStore(
|
AllMessages::AvailabilityStore(
|
||||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||||
) if parent_hash == test_state.relay_parent => {
|
) if candidate_hash == candidate_a.hash() => {
|
||||||
tx.send(Ok(())).unwrap();
|
tx.send(Ok(())).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1482,8 +1487,8 @@ mod tests {
|
|||||||
assert_matches!(
|
assert_matches!(
|
||||||
virtual_overseer.recv().await,
|
virtual_overseer.recv().await,
|
||||||
AllMessages::AvailabilityStore(
|
AllMessages::AvailabilityStore(
|
||||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||||
) if parent_hash == test_state.relay_parent => {
|
) if candidate_hash == candidate_a.hash() => {
|
||||||
tx.send(Ok(())).unwrap();
|
tx.send(Ok(())).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1665,8 +1670,8 @@ mod tests {
|
|||||||
assert_matches!(
|
assert_matches!(
|
||||||
virtual_overseer.recv().await,
|
virtual_overseer.recv().await,
|
||||||
AllMessages::AvailabilityStore(
|
AllMessages::AvailabilityStore(
|
||||||
AvailabilityStoreMessage::StoreAvailableData(parent_hash, _, _, _, tx)
|
AvailabilityStoreMessage::StoreAvailableData(candidate_hash, _, _, _, tx)
|
||||||
) if parent_hash == test_state.relay_parent => {
|
) if candidate_hash == candidate_b.hash() => {
|
||||||
tx.send(Ok(())).unwrap();
|
tx.send(Ok(())).unwrap();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ async fn get_core_availability(
|
|||||||
.await
|
.await
|
||||||
.send(
|
.send(
|
||||||
AvailabilityStoreMessage::QueryChunkAvailability(
|
AvailabilityStoreMessage::QueryChunkAvailability(
|
||||||
committed_candidate_receipt.descriptor.pov_hash,
|
committed_candidate_receipt.hash(),
|
||||||
validator_idx,
|
validator_idx,
|
||||||
tx,
|
tx,
|
||||||
).into(),
|
).into(),
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ use polkadot_node_network_protocol::{
|
|||||||
use polkadot_node_subsystem_util::metrics::{self, prometheus};
|
use polkadot_node_subsystem_util::metrics::{self, prometheus};
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
BlakeTwo256, CommittedCandidateReceipt, CoreState, ErasureChunk, Hash, HashT, Id as ParaId,
|
BlakeTwo256, CommittedCandidateReceipt, CoreState, ErasureChunk, Hash, HashT, Id as ParaId,
|
||||||
SessionIndex, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID,
|
SessionIndex, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, CandidateHash,
|
||||||
};
|
};
|
||||||
use polkadot_subsystem::messages::{
|
use polkadot_subsystem::messages::{
|
||||||
AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, ChainApiMessage,
|
AllMessages, AvailabilityDistributionMessage, AvailabilityStoreMessage, ChainApiMessage,
|
||||||
@@ -130,7 +130,7 @@ const BENEFIT_VALID_MESSAGE: Rep = Rep::new(10, "Valid message");
|
|||||||
#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct AvailabilityGossipMessage {
|
pub struct AvailabilityGossipMessage {
|
||||||
/// Anchor hash of the candidate the `ErasureChunk` is associated to.
|
/// Anchor hash of the candidate the `ErasureChunk` is associated to.
|
||||||
pub candidate_hash: Hash,
|
pub candidate_hash: CandidateHash,
|
||||||
/// The erasure chunk, a encoded information part of `AvailabilityData`.
|
/// The erasure chunk, a encoded information part of `AvailabilityData`.
|
||||||
pub erasure_chunk: ErasureChunk,
|
pub erasure_chunk: ErasureChunk,
|
||||||
}
|
}
|
||||||
@@ -149,13 +149,13 @@ struct ProtocolState {
|
|||||||
/// Caches a mapping of relay parents or ancestor to live candidate receipts.
|
/// Caches a mapping of relay parents or ancestor to live candidate receipts.
|
||||||
/// Allows fast intersection of live candidates with views and consecutive unioning.
|
/// Allows fast intersection of live candidates with views and consecutive unioning.
|
||||||
/// Maps relay parent / ancestor -> live candidate receipts + its hash.
|
/// Maps relay parent / ancestor -> live candidate receipts + its hash.
|
||||||
receipts: HashMap<Hash, HashSet<(Hash, CommittedCandidateReceipt)>>,
|
receipts: HashMap<Hash, HashSet<(CandidateHash, CommittedCandidateReceipt)>>,
|
||||||
|
|
||||||
/// Allow reverse caching of view checks.
|
/// Allow reverse caching of view checks.
|
||||||
/// Maps candidate hash -> relay parent for extracting meta information from `PerRelayParent`.
|
/// Maps candidate hash -> relay parent for extracting meta information from `PerRelayParent`.
|
||||||
/// Note that the presence of this is not sufficient to determine if deletion is OK, i.e.
|
/// Note that the presence of this is not sufficient to determine if deletion is OK, i.e.
|
||||||
/// two histories could cover this.
|
/// two histories could cover this.
|
||||||
reverse: HashMap<Hash, Hash>,
|
reverse: HashMap<CandidateHash, Hash>,
|
||||||
|
|
||||||
/// Keeps track of which candidate receipts are required due to ancestors of which relay parents
|
/// Keeps track of which candidate receipts are required due to ancestors of which relay parents
|
||||||
/// of our view.
|
/// of our view.
|
||||||
@@ -166,7 +166,7 @@ struct ProtocolState {
|
|||||||
per_relay_parent: HashMap<Hash, PerRelayParent>,
|
per_relay_parent: HashMap<Hash, PerRelayParent>,
|
||||||
|
|
||||||
/// Track data that is specific to a candidate.
|
/// Track data that is specific to a candidate.
|
||||||
per_candidate: HashMap<Hash, PerCandidate>,
|
per_candidate: HashMap<CandidateHash, PerCandidate>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
@@ -176,11 +176,11 @@ struct PerCandidate {
|
|||||||
/// candidate hash + erasure chunk index -> gossip message
|
/// candidate hash + erasure chunk index -> gossip message
|
||||||
message_vault: HashMap<u32, AvailabilityGossipMessage>,
|
message_vault: HashMap<u32, AvailabilityGossipMessage>,
|
||||||
|
|
||||||
/// Track received candidate hashes and chunk indices from peers.
|
/// Track received candidate hashes and validator indices from peers.
|
||||||
received_messages: HashMap<PeerId, HashSet<(Hash, ValidatorIndex)>>,
|
received_messages: HashMap<PeerId, HashSet<(CandidateHash, ValidatorIndex)>>,
|
||||||
|
|
||||||
/// Track already sent candidate hashes and the erasure chunk index to the peers.
|
/// Track already sent candidate hashes and the erasure chunk index to the peers.
|
||||||
sent_messages: HashMap<PeerId, HashSet<(Hash, ValidatorIndex)>>,
|
sent_messages: HashMap<PeerId, HashSet<(CandidateHash, ValidatorIndex)>>,
|
||||||
|
|
||||||
/// The set of validators.
|
/// The set of validators.
|
||||||
validators: Vec<ValidatorId>,
|
validators: Vec<ValidatorId>,
|
||||||
@@ -221,7 +221,7 @@ impl ProtocolState {
|
|||||||
fn cached_live_candidates_unioned<'a>(
|
fn cached_live_candidates_unioned<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
relay_parents: impl IntoIterator<Item = &'a Hash> + 'a,
|
relay_parents: impl IntoIterator<Item = &'a Hash> + 'a,
|
||||||
) -> HashMap<Hash, CommittedCandidateReceipt> {
|
) -> HashMap<CandidateHash, CommittedCandidateReceipt> {
|
||||||
let relay_parents_and_ancestors = self.extend_with_ancestors(relay_parents);
|
let relay_parents_and_ancestors = self.extend_with_ancestors(relay_parents);
|
||||||
relay_parents_and_ancestors
|
relay_parents_and_ancestors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -229,7 +229,7 @@ impl ProtocolState {
|
|||||||
.map(|receipt_set| receipt_set.into_iter())
|
.map(|receipt_set| receipt_set.into_iter())
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|(receipt_hash, receipt)| (receipt_hash.clone(), receipt.clone()))
|
.map(|(receipt_hash, receipt)| (receipt_hash.clone(), receipt.clone()))
|
||||||
.collect::<HashMap<Hash, CommittedCandidateReceipt>>()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_relay_parent<Context>(
|
async fn add_relay_parent<Context>(
|
||||||
@@ -296,8 +296,9 @@ impl ProtocolState {
|
|||||||
// remove from the ancestry index
|
// remove from the ancestry index
|
||||||
self.ancestry.remove(relay_parent);
|
self.ancestry.remove(relay_parent);
|
||||||
// and also remove the actual receipt
|
// and also remove the actual receipt
|
||||||
self.receipts.remove(relay_parent);
|
if let Some(candidates) = self.receipts.remove(relay_parent) {
|
||||||
self.per_candidate.remove(relay_parent);
|
candidates.into_iter().for_each(|c| { self.per_candidate.remove(&c.0); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(per_relay_parent) = self.per_relay_parent.remove(relay_parent) {
|
if let Some(per_relay_parent) = self.per_relay_parent.remove(relay_parent) {
|
||||||
@@ -313,8 +314,9 @@ impl ProtocolState {
|
|||||||
// remove from the ancestry index
|
// remove from the ancestry index
|
||||||
self.ancestry.remove(&ancestor);
|
self.ancestry.remove(&ancestor);
|
||||||
// and also remove the actual receipt
|
// and also remove the actual receipt
|
||||||
self.receipts.remove(&ancestor);
|
if let Some(candidates) = self.receipts.remove(&ancestor) {
|
||||||
self.per_candidate.remove(&ancestor);
|
candidates.into_iter().for_each(|c| { self.per_candidate.remove(&c.0); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -645,8 +647,7 @@ where
|
|||||||
let live_candidates = state.cached_live_candidates_unioned(state.view.0.iter());
|
let live_candidates = state.cached_live_candidates_unioned(state.view.0.iter());
|
||||||
|
|
||||||
// check if the candidate is of interest
|
// check if the candidate is of interest
|
||||||
let live_candidate = if let Some(live_candidate) = live_candidates.get(&message.candidate_hash)
|
let live_candidate = if let Some(live_candidate) = live_candidates.get(&message.candidate_hash) {
|
||||||
{
|
|
||||||
live_candidate
|
live_candidate
|
||||||
} else {
|
} else {
|
||||||
return modify_reputation(ctx, origin, COST_NOT_A_LIVE_CANDIDATE).await;
|
return modify_reputation(ctx, origin, COST_NOT_A_LIVE_CANDIDATE).await;
|
||||||
@@ -862,7 +863,7 @@ async fn query_live_candidates<Context>(
|
|||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
state: &mut ProtocolState,
|
state: &mut ProtocolState,
|
||||||
relay_parents: impl IntoIterator<Item = Hash>,
|
relay_parents: impl IntoIterator<Item = Hash>,
|
||||||
) -> Result<HashMap<Hash, (Hash, CommittedCandidateReceipt)>>
|
) -> Result<HashMap<Hash, (CandidateHash, CommittedCandidateReceipt)>>
|
||||||
where
|
where
|
||||||
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
||||||
{
|
{
|
||||||
@@ -871,7 +872,7 @@ where
|
|||||||
|
|
||||||
let capacity = hint.1.unwrap_or(hint.0) * (1 + AvailabilityDistributionSubsystem::K);
|
let capacity = hint.1.unwrap_or(hint.0) * (1 + AvailabilityDistributionSubsystem::K);
|
||||||
let mut live_candidates =
|
let mut live_candidates =
|
||||||
HashMap::<Hash, (Hash, CommittedCandidateReceipt)>::with_capacity(capacity);
|
HashMap::<Hash, (CandidateHash, CommittedCandidateReceipt)>::with_capacity(capacity);
|
||||||
|
|
||||||
for relay_parent in iter {
|
for relay_parent in iter {
|
||||||
// register one of relay parents (not the ancestors)
|
// register one of relay parents (not the ancestors)
|
||||||
@@ -969,7 +970,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Query the proof of validity for a particular candidate hash.
|
/// Query the proof of validity for a particular candidate hash.
|
||||||
async fn query_data_availability<Context>(ctx: &mut Context, candidate_hash: Hash) -> Result<bool>
|
async fn query_data_availability<Context>(ctx: &mut Context, candidate_hash: CandidateHash) -> Result<bool>
|
||||||
where
|
where
|
||||||
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
||||||
{
|
{
|
||||||
@@ -985,7 +986,7 @@ where
|
|||||||
|
|
||||||
async fn query_chunk<Context>(
|
async fn query_chunk<Context>(
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
validator_index: ValidatorIndex,
|
validator_index: ValidatorIndex,
|
||||||
) -> Result<Option<ErasureChunk>>
|
) -> Result<Option<ErasureChunk>>
|
||||||
where
|
where
|
||||||
@@ -1002,7 +1003,7 @@ where
|
|||||||
|
|
||||||
async fn store_chunk<Context>(
|
async fn store_chunk<Context>(
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
relay_parent: Hash,
|
relay_parent: Hash,
|
||||||
validator_index: ValidatorIndex,
|
validator_index: ValidatorIndex,
|
||||||
erasure_chunk: ErasureChunk,
|
erasure_chunk: ErasureChunk,
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ fn make_erasure_root(test: &TestState, pov: PoV) -> Hash {
|
|||||||
|
|
||||||
fn make_valid_availability_gossip(
|
fn make_valid_availability_gossip(
|
||||||
test: &TestState,
|
test: &TestState,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
erasure_chunk_index: u32,
|
erasure_chunk_index: u32,
|
||||||
pov: PoV,
|
pov: PoV,
|
||||||
) -> AvailabilityGossipMessage {
|
) -> AvailabilityGossipMessage {
|
||||||
@@ -320,7 +320,7 @@ fn helper_integrity() {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
let message =
|
let message =
|
||||||
make_valid_availability_gossip(&test_state, dbg!(candidate.hash()), 2, pov_block.clone());
|
make_valid_availability_gossip(&test_state, candidate.hash(), 2, pov_block.clone());
|
||||||
|
|
||||||
let root = dbg!(&candidate.commitments.erasure_root);
|
let root = dbg!(&candidate.commitments.erasure_root);
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ impl View {
|
|||||||
pub mod v1 {
|
pub mod v1 {
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
Hash, CollatorId, Id as ParaId, ErasureChunk, CandidateReceipt,
|
Hash, CollatorId, Id as ParaId, ErasureChunk, CandidateReceipt,
|
||||||
SignedAvailabilityBitfield, PoV,
|
SignedAvailabilityBitfield, PoV, CandidateHash,
|
||||||
};
|
};
|
||||||
use polkadot_node_primitives::SignedFullStatement;
|
use polkadot_node_primitives::SignedFullStatement;
|
||||||
use parity_scale_codec::{Encode, Decode};
|
use parity_scale_codec::{Encode, Decode};
|
||||||
@@ -198,7 +198,7 @@ pub mod v1 {
|
|||||||
pub enum AvailabilityDistributionMessage {
|
pub enum AvailabilityDistributionMessage {
|
||||||
/// An erasure chunk for a given candidate hash.
|
/// An erasure chunk for a given candidate hash.
|
||||||
#[codec(index = "0")]
|
#[codec(index = "0")]
|
||||||
Chunk(Hash, ErasureChunk),
|
Chunk(CandidateHash, ErasureChunk),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Network messages used by the bitfield distribution subsystem.
|
/// Network messages used by the bitfield distribution subsystem.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ use polkadot_node_subsystem_util::{
|
|||||||
};
|
};
|
||||||
use node_primitives::SignedFullStatement;
|
use node_primitives::SignedFullStatement;
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
Hash, CompactStatement, ValidatorIndex, ValidatorId, SigningContext, ValidatorSignature,
|
Hash, CompactStatement, ValidatorIndex, ValidatorId, SigningContext, ValidatorSignature, CandidateHash,
|
||||||
};
|
};
|
||||||
use polkadot_node_network_protocol::{
|
use polkadot_node_network_protocol::{
|
||||||
v1 as protocol_v1, View, PeerId, ReputationChange as Rep, NetworkBridgeEvent,
|
v1 as protocol_v1, View, PeerId, ReputationChange as Rep, NetworkBridgeEvent,
|
||||||
@@ -102,32 +102,32 @@ impl StatementDistribution {
|
|||||||
/// via other means.
|
/// via other means.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct VcPerPeerTracker {
|
struct VcPerPeerTracker {
|
||||||
local_observed: arrayvec::ArrayVec<[Hash; VC_THRESHOLD]>,
|
local_observed: arrayvec::ArrayVec<[CandidateHash; VC_THRESHOLD]>,
|
||||||
remote_observed: arrayvec::ArrayVec<[Hash; VC_THRESHOLD]>,
|
remote_observed: arrayvec::ArrayVec<[CandidateHash; VC_THRESHOLD]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VcPerPeerTracker {
|
impl VcPerPeerTracker {
|
||||||
// Note that the remote should now be aware that a validator has seconded a given candidate (by hash)
|
/// Note that the remote should now be aware that a validator has seconded a given candidate (by hash)
|
||||||
// based on a message that we have sent it from our local pool.
|
/// based on a message that we have sent it from our local pool.
|
||||||
fn note_local(&mut self, h: Hash) {
|
fn note_local(&mut self, h: CandidateHash) {
|
||||||
if !note_hash(&mut self.local_observed, h) {
|
if !note_hash(&mut self.local_observed, h) {
|
||||||
log::warn!("Statement distribution is erroneously attempting to distribute more \
|
log::warn!("Statement distribution is erroneously attempting to distribute more \
|
||||||
than {} candidate(s) per validator index. Ignoring", VC_THRESHOLD);
|
than {} candidate(s) per validator index. Ignoring", VC_THRESHOLD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that the remote should now be aware that a validator has seconded a given candidate (by hash)
|
/// Note that the remote should now be aware that a validator has seconded a given candidate (by hash)
|
||||||
// based on a message that it has sent us.
|
/// based on a message that it has sent us.
|
||||||
//
|
///
|
||||||
// Returns `true` if the peer was allowed to send us such a message, `false` otherwise.
|
/// Returns `true` if the peer was allowed to send us such a message, `false` otherwise.
|
||||||
fn note_remote(&mut self, h: Hash) -> bool {
|
fn note_remote(&mut self, h: CandidateHash) -> bool {
|
||||||
note_hash(&mut self.remote_observed, h)
|
note_hash(&mut self.remote_observed, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_hash(
|
fn note_hash(
|
||||||
observed: &mut arrayvec::ArrayVec<[Hash; VC_THRESHOLD]>,
|
observed: &mut arrayvec::ArrayVec<[CandidateHash; VC_THRESHOLD]>,
|
||||||
h: Hash,
|
h: CandidateHash,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if observed.contains(&h) { return true; }
|
if observed.contains(&h) { return true; }
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ fn note_hash(
|
|||||||
struct PeerRelayParentKnowledge {
|
struct PeerRelayParentKnowledge {
|
||||||
/// candidates that the peer is aware of. This indicates that we can
|
/// candidates that the peer is aware of. This indicates that we can
|
||||||
/// send other statements pertaining to that candidate.
|
/// send other statements pertaining to that candidate.
|
||||||
known_candidates: HashSet<Hash>,
|
known_candidates: HashSet<CandidateHash>,
|
||||||
/// fingerprints of all statements a peer should be aware of: those that
|
/// fingerprints of all statements a peer should be aware of: those that
|
||||||
/// were sent to the peer by us.
|
/// were sent to the peer by us.
|
||||||
sent_statements: HashSet<(CompactStatement, ValidatorIndex)>,
|
sent_statements: HashSet<(CompactStatement, ValidatorIndex)>,
|
||||||
@@ -149,7 +149,7 @@ struct PeerRelayParentKnowledge {
|
|||||||
/// How many candidates this peer is aware of for each given validator index.
|
/// How many candidates this peer is aware of for each given validator index.
|
||||||
seconded_counts: HashMap<ValidatorIndex, VcPerPeerTracker>,
|
seconded_counts: HashMap<ValidatorIndex, VcPerPeerTracker>,
|
||||||
/// How many statements we've received for each candidate that we're aware of.
|
/// How many statements we've received for each candidate that we're aware of.
|
||||||
received_message_count: HashMap<Hash, usize>,
|
received_message_count: HashMap<CandidateHash, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PeerRelayParentKnowledge {
|
impl PeerRelayParentKnowledge {
|
||||||
@@ -246,7 +246,7 @@ impl PeerRelayParentKnowledge {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let received_per_candidate = self.received_message_count
|
let received_per_candidate = self.received_message_count
|
||||||
.entry(candidate_hash.clone())
|
.entry(*candidate_hash)
|
||||||
.or_insert(0);
|
.or_insert(0);
|
||||||
|
|
||||||
if *received_per_candidate >= max_message_count {
|
if *received_per_candidate >= max_message_count {
|
||||||
@@ -372,7 +372,7 @@ enum NotedStatement<'a> {
|
|||||||
|
|
||||||
struct ActiveHeadData {
|
struct ActiveHeadData {
|
||||||
/// All candidates we are aware of for this head, keyed by hash.
|
/// All candidates we are aware of for this head, keyed by hash.
|
||||||
candidates: HashSet<Hash>,
|
candidates: HashSet<CandidateHash>,
|
||||||
/// Stored statements for circulation to peers.
|
/// Stored statements for circulation to peers.
|
||||||
///
|
///
|
||||||
/// These are iterable in insertion order, and `Seconded` statements are always
|
/// These are iterable in insertion order, and `Seconded` statements are always
|
||||||
@@ -464,7 +464,7 @@ impl ActiveHeadData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator over all statements for the active head that are for a particular candidate.
|
/// Get an iterator over all statements for the active head that are for a particular candidate.
|
||||||
fn statements_about(&self, candidate_hash: Hash)
|
fn statements_about(&self, candidate_hash: CandidateHash)
|
||||||
-> impl Iterator<Item = &'_ StoredStatement> + '_
|
-> impl Iterator<Item = &'_ StoredStatement> + '_
|
||||||
{
|
{
|
||||||
self.statements().filter(move |s| s.compact().candidate_hash() == &candidate_hash)
|
self.statements().filter(move |s| s.compact().candidate_hash() == &candidate_hash)
|
||||||
@@ -521,10 +521,10 @@ async fn circulate_statement_and_dependents(
|
|||||||
|
|
||||||
// First circulate the statement directly to all peers needing it.
|
// First circulate the statement directly to all peers needing it.
|
||||||
// The borrow of `active_head` needs to encompass only this (Rust) statement.
|
// The borrow of `active_head` needs to encompass only this (Rust) statement.
|
||||||
let outputs: Option<(Hash, Vec<PeerId>)> = {
|
let outputs: Option<(CandidateHash, Vec<PeerId>)> = {
|
||||||
match active_head.note_statement(statement) {
|
match active_head.note_statement(statement) {
|
||||||
NotedStatement::Fresh(stored) => Some((
|
NotedStatement::Fresh(stored) => Some((
|
||||||
stored.compact().candidate_hash().clone(),
|
*stored.compact().candidate_hash(),
|
||||||
circulate_statement(peers, ctx, relay_parent, stored).await?,
|
circulate_statement(peers, ctx, relay_parent, stored).await?,
|
||||||
)),
|
)),
|
||||||
_ => None,
|
_ => None,
|
||||||
@@ -602,7 +602,7 @@ async fn send_statements_about(
|
|||||||
peer_data: &mut PeerData,
|
peer_data: &mut PeerData,
|
||||||
ctx: &mut impl SubsystemContext<Message = StatementDistributionMessage>,
|
ctx: &mut impl SubsystemContext<Message = StatementDistributionMessage>,
|
||||||
relay_parent: Hash,
|
relay_parent: Hash,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
active_head: &ActiveHeadData,
|
active_head: &ActiveHeadData,
|
||||||
metrics: &Metrics,
|
metrics: &Metrics,
|
||||||
) -> SubsystemResult<()> {
|
) -> SubsystemResult<()> {
|
||||||
@@ -1110,8 +1110,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn note_local_works() {
|
fn note_local_works() {
|
||||||
let hash_a: Hash = [1; 32].into();
|
let hash_a = CandidateHash([1; 32].into());
|
||||||
let hash_b: Hash = [2; 32].into();
|
let hash_b = CandidateHash([2; 32].into());
|
||||||
|
|
||||||
let mut per_peer_tracker = VcPerPeerTracker::default();
|
let mut per_peer_tracker = VcPerPeerTracker::default();
|
||||||
per_peer_tracker.note_local(hash_a.clone());
|
per_peer_tracker.note_local(hash_a.clone());
|
||||||
@@ -1126,9 +1126,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn note_remote_works() {
|
fn note_remote_works() {
|
||||||
let hash_a: Hash = [1; 32].into();
|
let hash_a = CandidateHash([1; 32].into());
|
||||||
let hash_b: Hash = [2; 32].into();
|
let hash_b = CandidateHash([2; 32].into());
|
||||||
let hash_c: Hash = [3; 32].into();
|
let hash_c = CandidateHash([3; 32].into());
|
||||||
|
|
||||||
let mut per_peer_tracker = VcPerPeerTracker::default();
|
let mut per_peer_tracker = VcPerPeerTracker::default();
|
||||||
assert!(per_peer_tracker.note_remote(hash_a.clone()));
|
assert!(per_peer_tracker.note_remote(hash_a.clone()));
|
||||||
@@ -1148,7 +1148,7 @@ mod tests {
|
|||||||
fn per_peer_relay_parent_knowledge_send() {
|
fn per_peer_relay_parent_knowledge_send() {
|
||||||
let mut knowledge = PeerRelayParentKnowledge::default();
|
let mut knowledge = PeerRelayParentKnowledge::default();
|
||||||
|
|
||||||
let hash_a: Hash = [1; 32].into();
|
let hash_a = CandidateHash([1; 32].into());
|
||||||
|
|
||||||
// Sending an un-pinned statement should not work and should have no effect.
|
// Sending an un-pinned statement should not work and should have no effect.
|
||||||
assert!(knowledge.send(&(CompactStatement::Valid(hash_a), 0)).is_none());
|
assert!(knowledge.send(&(CompactStatement::Valid(hash_a), 0)).is_none());
|
||||||
@@ -1180,7 +1180,7 @@ mod tests {
|
|||||||
fn cant_send_after_receiving() {
|
fn cant_send_after_receiving() {
|
||||||
let mut knowledge = PeerRelayParentKnowledge::default();
|
let mut knowledge = PeerRelayParentKnowledge::default();
|
||||||
|
|
||||||
let hash_a: Hash = [1; 32].into();
|
let hash_a = CandidateHash([1; 32].into());
|
||||||
assert!(knowledge.receive(&(CompactStatement::Candidate(hash_a), 0), 3).unwrap());
|
assert!(knowledge.receive(&(CompactStatement::Candidate(hash_a), 0), 3).unwrap());
|
||||||
assert!(knowledge.send(&(CompactStatement::Candidate(hash_a), 0)).is_none());
|
assert!(knowledge.send(&(CompactStatement::Candidate(hash_a), 0)).is_none());
|
||||||
}
|
}
|
||||||
@@ -1189,7 +1189,7 @@ mod tests {
|
|||||||
fn per_peer_relay_parent_knowledge_receive() {
|
fn per_peer_relay_parent_knowledge_receive() {
|
||||||
let mut knowledge = PeerRelayParentKnowledge::default();
|
let mut knowledge = PeerRelayParentKnowledge::default();
|
||||||
|
|
||||||
let hash_a: Hash = [1; 32].into();
|
let hash_a = CandidateHash([1; 32].into());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
knowledge.receive(&(CompactStatement::Valid(hash_a), 0), 3),
|
knowledge.receive(&(CompactStatement::Valid(hash_a), 0), 3),
|
||||||
@@ -1226,8 +1226,8 @@ mod tests {
|
|||||||
assert_eq!(knowledge.received_statements.len(), 3); // number of prior `Ok`s.
|
assert_eq!(knowledge.received_statements.len(), 3); // number of prior `Ok`s.
|
||||||
|
|
||||||
// Now make sure that the seconding limit is respected.
|
// Now make sure that the seconding limit is respected.
|
||||||
let hash_b: Hash = [2; 32].into();
|
let hash_b = CandidateHash([2; 32].into());
|
||||||
let hash_c: Hash = [3; 32].into();
|
let hash_c = CandidateHash([3; 32].into());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
knowledge.receive(&(CompactStatement::Candidate(hash_b), 0), 3),
|
knowledge.receive(&(CompactStatement::Candidate(hash_b), 0), 3),
|
||||||
|
|||||||
@@ -1635,7 +1635,7 @@ mod tests {
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use futures::{executor, pin_mut, select, channel::mpsc, FutureExt};
|
use futures::{executor, pin_mut, select, channel::mpsc, FutureExt};
|
||||||
|
|
||||||
use polkadot_primitives::v1::{BlockData, CollatorPair, PoV};
|
use polkadot_primitives::v1::{BlockData, CollatorPair, PoV, CandidateHash};
|
||||||
use polkadot_subsystem::messages::RuntimeApiRequest;
|
use polkadot_subsystem::messages::RuntimeApiRequest;
|
||||||
use polkadot_node_primitives::{Collation, CollationGenerationConfig};
|
use polkadot_node_primitives::{Collation, CollationGenerationConfig};
|
||||||
use polkadot_node_network_protocol::{PeerId, ReputationChange, NetworkBridgeEvent};
|
use polkadot_node_network_protocol::{PeerId, ReputationChange, NetworkBridgeEvent};
|
||||||
@@ -2273,7 +2273,7 @@ mod tests {
|
|||||||
|
|
||||||
fn test_availability_store_msg() -> AvailabilityStoreMessage {
|
fn test_availability_store_msg() -> AvailabilityStoreMessage {
|
||||||
let (sender, _) = oneshot::channel();
|
let (sender, _) = oneshot::channel();
|
||||||
AvailabilityStoreMessage::QueryAvailableData(Default::default(), sender)
|
AvailabilityStoreMessage::QueryAvailableData(CandidateHash(Default::default()), sender)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_network_bridge_msg() -> NetworkBridgeMessage {
|
fn test_network_bridge_msg() -> NetworkBridgeMessage {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ use polkadot_primitives::v1::{
|
|||||||
Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement,
|
Hash, CommittedCandidateReceipt, CandidateReceipt, CompactStatement,
|
||||||
EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId,
|
EncodeAs, Signed, SigningContext, ValidatorIndex, ValidatorId,
|
||||||
UpwardMessage, ValidationCode, PersistedValidationData, ValidationData,
|
UpwardMessage, ValidationCode, PersistedValidationData, ValidationData,
|
||||||
HeadData, PoV, CollatorPair, Id as ParaId, ValidationOutputs,
|
HeadData, PoV, CollatorPair, Id as ParaId, ValidationOutputs, CandidateHash,
|
||||||
};
|
};
|
||||||
use polkadot_statement_table::{
|
use polkadot_statement_table::{
|
||||||
generic::{
|
generic::{
|
||||||
@@ -54,10 +54,10 @@ pub enum Statement {
|
|||||||
Seconded(CommittedCandidateReceipt),
|
Seconded(CommittedCandidateReceipt),
|
||||||
/// A statement that a validator has deemed a candidate valid.
|
/// A statement that a validator has deemed a candidate valid.
|
||||||
#[codec(index = "2")]
|
#[codec(index = "2")]
|
||||||
Valid(Hash),
|
Valid(CandidateHash),
|
||||||
/// A statement that a validator has deemed a candidate invalid.
|
/// A statement that a validator has deemed a candidate invalid.
|
||||||
#[codec(index = "3")]
|
#[codec(index = "3")]
|
||||||
Invalid(Hash),
|
Invalid(CandidateHash),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl Statement {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ use polkadot_primitives::v1::{
|
|||||||
CollatorId, CommittedCandidateReceipt, CoreState, ErasureChunk,
|
CollatorId, CommittedCandidateReceipt, CoreState, ErasureChunk,
|
||||||
GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption,
|
GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption,
|
||||||
PersistedValidationData, PoV, SessionIndex, SignedAvailabilityBitfield,
|
PersistedValidationData, PoV, SessionIndex, SignedAvailabilityBitfield,
|
||||||
ValidationCode, ValidatorId, ValidationData,
|
ValidationCode, ValidatorId, ValidationData, CandidateHash,
|
||||||
ValidatorIndex, ValidatorSignature, InboundDownwardMessage,
|
ValidatorIndex, ValidatorSignature, InboundDownwardMessage,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -289,31 +289,31 @@ impl BitfieldSigningMessage {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AvailabilityStoreMessage {
|
pub enum AvailabilityStoreMessage {
|
||||||
/// Query a `AvailableData` from the AV store.
|
/// Query a `AvailableData` from the AV store.
|
||||||
QueryAvailableData(Hash, oneshot::Sender<Option<AvailableData>>),
|
QueryAvailableData(CandidateHash, oneshot::Sender<Option<AvailableData>>),
|
||||||
|
|
||||||
/// Query whether a `AvailableData` exists within the AV Store.
|
/// Query whether a `AvailableData` exists within the AV Store.
|
||||||
///
|
///
|
||||||
/// This is useful in cases when existence
|
/// This is useful in cases when existence
|
||||||
/// matters, but we don't want to necessarily pass around multiple
|
/// matters, but we don't want to necessarily pass around multiple
|
||||||
/// megabytes of data to get a single bit of information.
|
/// megabytes of data to get a single bit of information.
|
||||||
QueryDataAvailability(Hash, oneshot::Sender<bool>),
|
QueryDataAvailability(CandidateHash, oneshot::Sender<bool>),
|
||||||
|
|
||||||
/// Query an `ErasureChunk` from the AV store by the candidate hash and validator index.
|
/// Query an `ErasureChunk` from the AV store by the candidate hash and validator index.
|
||||||
QueryChunk(Hash, ValidatorIndex, oneshot::Sender<Option<ErasureChunk>>),
|
QueryChunk(CandidateHash, ValidatorIndex, oneshot::Sender<Option<ErasureChunk>>),
|
||||||
|
|
||||||
/// Query whether an `ErasureChunk` exists within the AV Store.
|
/// Query whether an `ErasureChunk` exists within the AV Store.
|
||||||
///
|
///
|
||||||
/// This is useful in cases like bitfield signing, when existence
|
/// This is useful in cases like bitfield signing, when existence
|
||||||
/// matters, but we don't want to necessarily pass around large
|
/// matters, but we don't want to necessarily pass around large
|
||||||
/// quantities of data to get a single bit of information.
|
/// quantities of data to get a single bit of information.
|
||||||
QueryChunkAvailability(Hash, ValidatorIndex, oneshot::Sender<bool>),
|
QueryChunkAvailability(CandidateHash, ValidatorIndex, oneshot::Sender<bool>),
|
||||||
|
|
||||||
/// Store an `ErasureChunk` in the AV store.
|
/// Store an `ErasureChunk` in the AV store.
|
||||||
///
|
///
|
||||||
/// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed.
|
/// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed.
|
||||||
StoreChunk {
|
StoreChunk {
|
||||||
/// A hash of the candidate this chunk belongs to.
|
/// A hash of the candidate this chunk belongs to.
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
/// A relevant relay parent.
|
/// A relevant relay parent.
|
||||||
relay_parent: Hash,
|
relay_parent: Hash,
|
||||||
/// The index of the validator this chunk belongs to.
|
/// The index of the validator this chunk belongs to.
|
||||||
@@ -328,7 +328,7 @@ pub enum AvailabilityStoreMessage {
|
|||||||
/// If `ValidatorIndex` is present store corresponding chunk also.
|
/// If `ValidatorIndex` is present store corresponding chunk also.
|
||||||
///
|
///
|
||||||
/// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed.
|
/// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed.
|
||||||
StoreAvailableData(Hash, Option<ValidatorIndex>, u32, AvailableData, oneshot::Sender<Result<(), ()>>),
|
StoreAvailableData(CandidateHash, Option<ValidatorIndex>, u32, AvailableData, oneshot::Sender<Result<(), ()>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AvailabilityStoreMessage {
|
impl AvailabilityStoreMessage {
|
||||||
|
|||||||
@@ -633,18 +633,18 @@ pub struct ErasureChunk {
|
|||||||
pub enum CompactStatement {
|
pub enum CompactStatement {
|
||||||
/// Proposal of a parachain candidate.
|
/// Proposal of a parachain candidate.
|
||||||
#[codec(index = "1")]
|
#[codec(index = "1")]
|
||||||
Candidate(Hash),
|
Candidate(CandidateHash),
|
||||||
/// State that a parachain candidate is valid.
|
/// State that a parachain candidate is valid.
|
||||||
#[codec(index = "2")]
|
#[codec(index = "2")]
|
||||||
Valid(Hash),
|
Valid(CandidateHash),
|
||||||
/// State that a parachain candidate is invalid.
|
/// State that a parachain candidate is invalid.
|
||||||
#[codec(index = "3")]
|
#[codec(index = "3")]
|
||||||
Invalid(Hash),
|
Invalid(CandidateHash),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompactStatement {
|
impl CompactStatement {
|
||||||
/// Get the underlying candidate hash this references.
|
/// Get the underlying candidate hash this references.
|
||||||
pub fn candidate_hash(&self) -> &Hash {
|
pub fn candidate_hash(&self) -> &CandidateHash {
|
||||||
match *self {
|
match *self {
|
||||||
CompactStatement::Candidate(ref h)
|
CompactStatement::Candidate(ref h)
|
||||||
| CompactStatement::Valid(ref h)
|
| CompactStatement::Valid(ref h)
|
||||||
@@ -684,7 +684,7 @@ impl ValidityAttestation {
|
|||||||
/// which should be known in context.
|
/// which should be known in context.
|
||||||
pub fn signed_payload<H: Encode>(
|
pub fn signed_payload<H: Encode>(
|
||||||
&self,
|
&self,
|
||||||
candidate_hash: Hash,
|
candidate_hash: CandidateHash,
|
||||||
signing_context: &SigningContext<H>,
|
signing_context: &SigningContext<H>,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
match *self {
|
match *self {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub use runtime_primitives::traits::{BlakeTwo256, Hash as HashT};
|
|||||||
pub use polkadot_core_primitives::v1::{
|
pub use polkadot_core_primitives::v1::{
|
||||||
BlockNumber, Moment, Signature, AccountPublic, AccountId, AccountIndex,
|
BlockNumber, Moment, Signature, AccountPublic, AccountId, AccountIndex,
|
||||||
ChainId, Hash, Nonce, Balance, Header, Block, BlockId, UncheckedExtrinsic,
|
ChainId, Hash, Nonce, Balance, Header, Block, BlockId, UncheckedExtrinsic,
|
||||||
Remark, DownwardMessage, InboundDownwardMessage,
|
Remark, DownwardMessage, InboundDownwardMessage, CandidateHash,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Export some polkadot-parachain primitives
|
// Export some polkadot-parachain primitives
|
||||||
@@ -148,8 +148,8 @@ impl<H> CandidateReceipt<H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the blake2-256 hash of the receipt.
|
/// Computes the blake2-256 hash of the receipt.
|
||||||
pub fn hash(&self) -> Hash where H: Encode {
|
pub fn hash(&self) -> CandidateHash where H: Encode {
|
||||||
BlakeTwo256::hash_of(self)
|
CandidateHash(BlakeTwo256::hash_of(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ impl<H: Clone> CommittedCandidateReceipt<H> {
|
|||||||
///
|
///
|
||||||
/// This computes the canonical hash, not the hash of the directly encoded data.
|
/// This computes the canonical hash, not the hash of the directly encoded data.
|
||||||
/// Thus this is a shortcut for `candidate.to_plain().hash()`.
|
/// Thus this is a shortcut for `candidate.to_plain().hash()`.
|
||||||
pub fn hash(&self) -> Hash where H: Encode {
|
pub fn hash(&self) -> CandidateHash where H: Encode {
|
||||||
self.to_plain().hash()
|
self.to_plain().hash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,7 +421,7 @@ pub fn check_candidate_backing<H: AsRef<[u8]> + Clone + Encode>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this is known, even in runtime, to be blake2-256.
|
// this is known, even in runtime, to be blake2-256.
|
||||||
let hash: Hash = backed.candidate.hash();
|
let hash = backed.candidate.hash();
|
||||||
|
|
||||||
let mut signed = 0;
|
let mut signed = 0;
|
||||||
for ((val_in_group_idx, _), attestation) in backed.validator_indices.iter().enumerate()
|
for ((val_in_group_idx, _), attestation) in backed.validator_indices.iter().enumerate()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ enum ObservedRole {
|
|||||||
```rust
|
```rust
|
||||||
enum AvailabilityDistributionV1Message {
|
enum AvailabilityDistributionV1Message {
|
||||||
/// An erasure chunk for a given candidate hash.
|
/// An erasure chunk for a given candidate hash.
|
||||||
Chunk(Hash, ErasureChunk),
|
Chunk(CandidateHash, ErasureChunk),
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -136,18 +136,18 @@ Messages to and from the availability store.
|
|||||||
```rust
|
```rust
|
||||||
enum AvailabilityStoreMessage {
|
enum AvailabilityStoreMessage {
|
||||||
/// Query the `AvailableData` of a candidate by hash.
|
/// Query the `AvailableData` of a candidate by hash.
|
||||||
QueryAvailableData(Hash, ResponseChannel<Option<AvailableData>>),
|
QueryAvailableData(CandidateHash, ResponseChannel<Option<AvailableData>>),
|
||||||
/// Query whether an `AvailableData` exists within the AV Store.
|
/// Query whether an `AvailableData` exists within the AV Store.
|
||||||
QueryDataAvailability(Hash, ResponseChannel<bool>),
|
QueryDataAvailability(CandidateHash, ResponseChannel<bool>),
|
||||||
/// Query a specific availability chunk of the candidate's erasure-coding by validator index.
|
/// Query a specific availability chunk of the candidate's erasure-coding by validator index.
|
||||||
/// Returns the chunk and its inclusion proof against the candidate's erasure-root.
|
/// Returns the chunk and its inclusion proof against the candidate's erasure-root.
|
||||||
QueryChunk(Hash, ValidatorIndex, ResponseChannel<Option<AvailabilityChunkAndProof>>),
|
QueryChunk(CandidateHash, ValidatorIndex, ResponseChannel<Option<AvailabilityChunkAndProof>>),
|
||||||
/// Store a specific chunk of the candidate's erasure-coding by validator index, with an
|
/// Store a specific chunk of the candidate's erasure-coding by validator index, with an
|
||||||
/// accompanying proof.
|
/// accompanying proof.
|
||||||
StoreChunk(Hash, ValidatorIndex, AvailabilityChunkAndProof, ResponseChannel<Result<()>>),
|
StoreChunk(CandidateHash, ValidatorIndex, AvailabilityChunkAndProof, ResponseChannel<Result<()>>),
|
||||||
/// Store `AvailableData`. If `ValidatorIndex` is provided, also store this validator's
|
/// Store `AvailableData`. If `ValidatorIndex` is provided, also store this validator's
|
||||||
/// `AvailabilityChunkAndProof`.
|
/// `AvailabilityChunkAndProof`.
|
||||||
StoreAvailableData(Hash, Option<ValidatorIndex>, u32, AvailableData, ResponseChannel<Result<()>>),
|
StoreAvailableData(CandidateHash, Option<ValidatorIndex>, u32, AvailableData, ResponseChannel<Result<()>>),
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -18,63 +18,21 @@ pub mod generic;
|
|||||||
|
|
||||||
pub use generic::{Table, Context};
|
pub use generic::{Table, Context};
|
||||||
|
|
||||||
/// Concrete instantiations suitable for v0 primitives.
|
|
||||||
pub mod v0 {
|
|
||||||
use crate::generic;
|
|
||||||
use primitives::v0::{
|
|
||||||
Hash,
|
|
||||||
Id, AbridgedCandidateReceipt, CompactStatement as PrimitiveStatement, ValidatorSignature, ValidatorIndex,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Statements about candidates on the network.
|
|
||||||
pub type Statement = generic::Statement<AbridgedCandidateReceipt, Hash>;
|
|
||||||
|
|
||||||
/// Signed statements about candidates.
|
|
||||||
pub type SignedStatement = generic::SignedStatement<
|
|
||||||
AbridgedCandidateReceipt,
|
|
||||||
Hash,
|
|
||||||
ValidatorIndex,
|
|
||||||
ValidatorSignature,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// Kinds of misbehavior, along with proof.
|
|
||||||
pub type Misbehavior = generic::Misbehavior<
|
|
||||||
AbridgedCandidateReceipt,
|
|
||||||
Hash,
|
|
||||||
ValidatorIndex,
|
|
||||||
ValidatorSignature,
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// A summary of import of a statement.
|
|
||||||
pub type Summary = generic::Summary<Hash, Id>;
|
|
||||||
|
|
||||||
impl<'a> From<&'a Statement> for PrimitiveStatement {
|
|
||||||
fn from(s: &'a Statement) -> PrimitiveStatement {
|
|
||||||
match *s {
|
|
||||||
generic::Statement::Valid(s) => PrimitiveStatement::Valid(s),
|
|
||||||
generic::Statement::Invalid(s) => PrimitiveStatement::Invalid(s),
|
|
||||||
generic::Statement::Candidate(ref s) => PrimitiveStatement::Candidate(s.hash()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Concrete instantiations suitable for v1 primitives.
|
/// Concrete instantiations suitable for v1 primitives.
|
||||||
pub mod v1 {
|
pub mod v1 {
|
||||||
use crate::generic;
|
use crate::generic;
|
||||||
use primitives::v1::{
|
use primitives::v1::{
|
||||||
Hash,
|
CandidateHash, Id, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement,
|
||||||
Id, CommittedCandidateReceipt, CompactStatement as PrimitiveStatement,
|
|
||||||
ValidatorSignature, ValidatorIndex,
|
ValidatorSignature, ValidatorIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Statements about candidates on the network.
|
/// Statements about candidates on the network.
|
||||||
pub type Statement = generic::Statement<CommittedCandidateReceipt, Hash>;
|
pub type Statement = generic::Statement<CommittedCandidateReceipt, CandidateHash>;
|
||||||
|
|
||||||
/// Signed statements about candidates.
|
/// Signed statements about candidates.
|
||||||
pub type SignedStatement = generic::SignedStatement<
|
pub type SignedStatement = generic::SignedStatement<
|
||||||
CommittedCandidateReceipt,
|
CommittedCandidateReceipt,
|
||||||
Hash,
|
CandidateHash,
|
||||||
ValidatorIndex,
|
ValidatorIndex,
|
||||||
ValidatorSignature,
|
ValidatorSignature,
|
||||||
>;
|
>;
|
||||||
@@ -82,13 +40,13 @@ pub mod v1 {
|
|||||||
/// Kinds of misbehavior, along with proof.
|
/// Kinds of misbehavior, along with proof.
|
||||||
pub type Misbehavior = generic::Misbehavior<
|
pub type Misbehavior = generic::Misbehavior<
|
||||||
CommittedCandidateReceipt,
|
CommittedCandidateReceipt,
|
||||||
Hash,
|
CandidateHash,
|
||||||
ValidatorIndex,
|
ValidatorIndex,
|
||||||
ValidatorSignature,
|
ValidatorSignature,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// A summary of import of a statement.
|
/// A summary of import of a statement.
|
||||||
pub type Summary = generic::Summary<Hash, Id>;
|
pub type Summary = generic::Summary<CandidateHash, Id>;
|
||||||
|
|
||||||
impl<'a> From<&'a Statement> for PrimitiveStatement {
|
impl<'a> From<&'a Statement> for PrimitiveStatement {
|
||||||
fn from(s: &'a Statement) -> PrimitiveStatement {
|
fn from(s: &'a Statement) -> PrimitiveStatement {
|
||||||
|
|||||||
Reference in New Issue
Block a user