mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-24 08:55:47 +00:00
Add candidate info to OccupiedCore (#2134)
* guide: add candidate information to OccupiedCore * add descriptor and hash to occupied core type * guide: add candidate hash to inclusion * runtime: return candidate info in core state * bitfield signing: stop querying runtime as much * minimize going to runtime in availability distribution * fix availability distribution tests * guide: remove para ID from Occupied core * get all crates compiling
This commit is contained in:
committed by
GitHub
parent
eab86d6f4b
commit
38276b08a4
@@ -78,37 +78,7 @@ async fn get_core_availability(
|
|||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let span = jaeger::hash_span(&relay_parent, "core-availability");
|
let span = jaeger::hash_span(&relay_parent, "core-availability");
|
||||||
if let CoreState::Occupied(core) = core {
|
if let CoreState::Occupied(core) = core {
|
||||||
tracing::trace!(target: LOG_TARGET, para_id = %core.para_id, "Getting core availability");
|
|
||||||
|
|
||||||
let _span = span.child("occupied");
|
|
||||||
let (tx, rx) = oneshot::channel();
|
|
||||||
sender
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.send(
|
|
||||||
AllMessages::from(RuntimeApiMessage::Request(
|
|
||||||
relay_parent,
|
|
||||||
RuntimeApiRequest::CandidatePendingAvailability(core.para_id, tx),
|
|
||||||
)).into(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let committed_candidate_receipt = match rx.await? {
|
|
||||||
Ok(Some(ccr)) => ccr,
|
|
||||||
Ok(None) => {
|
|
||||||
tracing::trace!(target: LOG_TARGET, para_id = %core.para_id, "No committed candidate");
|
|
||||||
return Ok(false)
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
// Don't take down the node on runtime API errors.
|
|
||||||
tracing::warn!(target: LOG_TARGET, err = ?e, "Encountered a runtime API error");
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
drop(_span);
|
|
||||||
let _span = span.child("query chunk");
|
let _span = span.child("query chunk");
|
||||||
let candidate_hash = committed_candidate_receipt.hash();
|
|
||||||
|
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
sender
|
sender
|
||||||
@@ -116,7 +86,7 @@ async fn get_core_availability(
|
|||||||
.await
|
.await
|
||||||
.send(
|
.send(
|
||||||
AllMessages::from(AvailabilityStoreMessage::QueryChunkAvailability(
|
AllMessages::from(AvailabilityStoreMessage::QueryChunkAvailability(
|
||||||
candidate_hash,
|
core.candidate_hash,
|
||||||
validator_idx,
|
validator_idx,
|
||||||
tx,
|
tx,
|
||||||
)).into(),
|
)).into(),
|
||||||
@@ -127,9 +97,9 @@ async fn get_core_availability(
|
|||||||
|
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
para_id = %core.para_id,
|
para_id = %core.para_id(),
|
||||||
availability = ?res,
|
availability = ?res,
|
||||||
?candidate_hash,
|
?core.candidate_hash,
|
||||||
"Candidate availability",
|
"Candidate availability",
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -325,17 +295,18 @@ pub type BitfieldSigningSubsystem<Spawner, Context> = JobManager<Spawner, Contex
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use futures::{pin_mut, executor::block_on};
|
use futures::{pin_mut, executor::block_on};
|
||||||
use polkadot_primitives::v1::OccupiedCore;
|
use polkadot_primitives::v1::{CandidateHash, OccupiedCore};
|
||||||
|
|
||||||
fn occupied_core(para_id: u32) -> CoreState {
|
fn occupied_core(para_id: u32, candidate_hash: CandidateHash) -> CoreState {
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: para_id.into(),
|
|
||||||
group_responsible: para_id.into(),
|
group_responsible: para_id.into(),
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 100_u32,
|
occupied_since: 100_u32,
|
||||||
time_out_at: 200_u32,
|
time_out_at: 200_u32,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: Default::default(),
|
availability: Default::default(),
|
||||||
|
candidate_hash,
|
||||||
|
candidate_descriptor: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,6 +325,9 @@ mod tests {
|
|||||||
).fuse();
|
).fuse();
|
||||||
pin_mut!(future);
|
pin_mut!(future);
|
||||||
|
|
||||||
|
let hash_a = CandidateHash(Hash::repeat_byte(1));
|
||||||
|
let hash_b = CandidateHash(Hash::repeat_byte(2));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
futures::select! {
|
futures::select! {
|
||||||
m = receiver.next() => match m.unwrap() {
|
m = receiver.next() => match m.unwrap() {
|
||||||
@@ -363,29 +337,16 @@ mod tests {
|
|||||||
),
|
),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(relay_parent, rp);
|
assert_eq!(relay_parent, rp);
|
||||||
tx.send(Ok(vec![CoreState::Free, occupied_core(1), occupied_core(2)])).unwrap();
|
tx.send(Ok(vec![CoreState::Free, occupied_core(1, hash_a), occupied_core(2, hash_b)])).unwrap();
|
||||||
},
|
|
||||||
FromJobCommand::SendMessage(
|
|
||||||
AllMessages::RuntimeApi(
|
|
||||||
RuntimeApiMessage::Request(rp, RuntimeApiRequest::CandidatePendingAvailability(para_id, tx)),
|
|
||||||
),
|
|
||||||
) => {
|
|
||||||
assert_eq!(relay_parent, rp);
|
|
||||||
|
|
||||||
if para_id == 1.into() {
|
|
||||||
tx.send(Ok(Some(Default::default()))).unwrap();
|
|
||||||
} else {
|
|
||||||
tx.send(Ok(None)).unwrap();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
FromJobCommand::SendMessage(
|
FromJobCommand::SendMessage(
|
||||||
AllMessages::AvailabilityStore(
|
AllMessages::AvailabilityStore(
|
||||||
AvailabilityStoreMessage::QueryChunkAvailability(_, vidx, tx),
|
AvailabilityStoreMessage::QueryChunkAvailability(c_hash, vidx, tx),
|
||||||
),
|
),
|
||||||
) => {
|
) => {
|
||||||
assert_eq!(validator_index, vidx);
|
assert_eq!(validator_index, vidx);
|
||||||
|
|
||||||
tx.send(true).unwrap();
|
tx.send(c_hash == hash_a).unwrap();
|
||||||
},
|
},
|
||||||
o => panic!("Unknown message: {:?}", o),
|
o => panic!("Unknown message: {:?}", o),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ use polkadot_primitives::v1::{OccupiedCore, ScheduledCore};
|
|||||||
|
|
||||||
pub fn occupied_core(para_id: u32) -> CoreState {
|
pub fn occupied_core(para_id: u32) -> CoreState {
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: para_id.into(),
|
|
||||||
group_responsible: para_id.into(),
|
group_responsible: para_id.into(),
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 100_u32,
|
occupied_since: 100_u32,
|
||||||
time_out_at: 200_u32,
|
time_out_at: 200_u32,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: bitvec![bitvec::order::Lsb0, u8; 0; 32],
|
availability: bitvec![bitvec::order::Lsb0, u8; 0; 32],
|
||||||
|
candidate_descriptor: Default::default(),
|
||||||
|
candidate_hash: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,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, CoreState, ErasureChunk, Hash, HashT,
|
||||||
SessionIndex, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, CandidateHash,
|
SessionIndex, ValidatorId, ValidatorIndex, PARACHAIN_KEY_TYPE_ID, CandidateHash,
|
||||||
CandidateDescriptor,
|
CandidateDescriptor,
|
||||||
};
|
};
|
||||||
@@ -62,11 +62,6 @@ const LOG_TARGET: &'static str = "availability_distribution";
|
|||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
enum Error {
|
enum Error {
|
||||||
#[error("Response channel to obtain PendingAvailability failed")]
|
|
||||||
QueryPendingAvailabilityResponseChannel(#[source] oneshot::Canceled),
|
|
||||||
#[error("RuntimeAPI to obtain PendingAvailability failed")]
|
|
||||||
QueryPendingAvailability(#[source] RuntimeApiError),
|
|
||||||
|
|
||||||
#[error("Response channel to obtain StoreChunk failed")]
|
#[error("Response channel to obtain StoreChunk failed")]
|
||||||
StoreChunkResponseChannel(#[source] oneshot::Canceled),
|
StoreChunkResponseChannel(#[source] oneshot::Canceled),
|
||||||
|
|
||||||
@@ -795,19 +790,12 @@ where
|
|||||||
e => e.or_default(),
|
e => e.or_default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for para in query_para_ids(ctx, relay_parent).await? {
|
for (receipt_hash, descriptor) in query_pending_availability(ctx, relay_parent).await? {
|
||||||
if let Some(ccr) = query_pending_availability(ctx, relay_parent, para).await? {
|
// unfortunately we have no good way of telling the candidate was
|
||||||
let receipt_hash = ccr.hash();
|
// cached until now. But we don't clobber a `Cached` entry if there
|
||||||
let descriptor = ccr.descriptor().clone();
|
// is one already.
|
||||||
|
live_candidates.entry(receipt_hash).or_insert(FetchedLiveCandidate::Fresh(descriptor));
|
||||||
// unfortunately we have no good way of telling the candidate was
|
receipts_for.insert(receipt_hash);
|
||||||
// cached until now. But we don't clobber a `Cached` entry if there
|
|
||||||
// is one already.
|
|
||||||
live_candidates.entry(receipt_hash)
|
|
||||||
.or_insert(FetchedLiveCandidate::Fresh(descriptor));
|
|
||||||
|
|
||||||
receipts_for.insert(receipt_hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,9 +838,10 @@ where
|
|||||||
Ok((live_candidates, ancestors))
|
Ok((live_candidates, ancestors))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query all para IDs that are occupied under a given relay-parent.
|
/// Query all hashes and descriptors of candidates pending availability at a particular block.
|
||||||
#[tracing::instrument(level = "trace", skip(ctx), fields(subsystem = LOG_TARGET))]
|
#[tracing::instrument(level = "trace", skip(ctx), fields(subsystem = LOG_TARGET))]
|
||||||
async fn query_para_ids<Context>(ctx: &mut Context, relay_parent: Hash) -> Result<Vec<ParaId>>
|
async fn query_pending_availability<Context>(ctx: &mut Context, relay_parent: Hash)
|
||||||
|
-> Result<Vec<(CandidateHash, CandidateDescriptor)>>
|
||||||
where
|
where
|
||||||
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
||||||
{
|
{
|
||||||
@@ -863,22 +852,18 @@ where
|
|||||||
)))
|
)))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let all_para_ids = rx
|
let cores: Vec<_> = rx
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::AvailabilityCoresResponseChannel(e))?
|
.map_err(|e| Error::AvailabilityCoresResponseChannel(e))?
|
||||||
.map_err(|e| Error::AvailabilityCores(e))?;
|
.map_err(|e| Error::AvailabilityCores(e))?;
|
||||||
|
|
||||||
let occupied_para_ids = all_para_ids
|
Ok(cores.into_iter()
|
||||||
.into_iter()
|
.filter_map(|core_state| if let CoreState::Occupied(occupied) = core_state {
|
||||||
.filter_map(|core_state| {
|
Some((occupied.candidate_hash, occupied.candidate_descriptor))
|
||||||
if let CoreState::Occupied(occupied) = core_state {
|
} else {
|
||||||
Some(occupied.para_id)
|
None
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect())
|
||||||
Ok(occupied_para_ids)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modify the reputation of a peer based on its behavior.
|
/// Modify the reputation of a peer based on its behavior.
|
||||||
@@ -954,27 +939,6 @@ where
|
|||||||
rx.await.map_err(|e| Error::StoreChunkResponseChannel(e))
|
rx.await.map_err(|e| Error::StoreChunkResponseChannel(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request the head data for a particular para.
|
|
||||||
#[tracing::instrument(level = "trace", skip(ctx), fields(subsystem = LOG_TARGET))]
|
|
||||||
async fn query_pending_availability<Context>(
|
|
||||||
ctx: &mut Context,
|
|
||||||
relay_parent: Hash,
|
|
||||||
para: ParaId,
|
|
||||||
) -> Result<Option<CommittedCandidateReceipt>>
|
|
||||||
where
|
|
||||||
Context: SubsystemContext<Message = AvailabilityDistributionMessage>,
|
|
||||||
{
|
|
||||||
let (tx, rx) = oneshot::channel();
|
|
||||||
ctx.send_message(AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
|
||||||
relay_parent,
|
|
||||||
RuntimeApiRequest::CandidatePendingAvailability(para, tx),
|
|
||||||
))).await;
|
|
||||||
|
|
||||||
rx.await
|
|
||||||
.map_err(|e| Error::QueryPendingAvailabilityResponseChannel(e))?
|
|
||||||
.map_err(|e| Error::QueryPendingAvailability(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Query the validator set.
|
/// Query the validator set.
|
||||||
#[tracing::instrument(level = "trace", skip(ctx), fields(subsystem = LOG_TARGET))]
|
#[tracing::instrument(level = "trace", skip(ctx), fields(subsystem = LOG_TARGET))]
|
||||||
async fn query_validators<Context>(
|
async fn query_validators<Context>(
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ use polkadot_node_network_protocol::{view, ObservedRole};
|
|||||||
use polkadot_node_subsystem_util::TimeoutExt;
|
use polkadot_node_subsystem_util::TimeoutExt;
|
||||||
use polkadot_primitives::v1::{
|
use polkadot_primitives::v1::{
|
||||||
AvailableData, BlockData, CandidateCommitments, CandidateDescriptor, GroupIndex,
|
AvailableData, BlockData, CandidateCommitments, CandidateDescriptor, GroupIndex,
|
||||||
GroupRotationInfo, HeadData, OccupiedCore, PersistedValidationData, PoV, ScheduledCore,
|
GroupRotationInfo, HeadData, OccupiedCore, PersistedValidationData, PoV, ScheduledCore, Id as ParaId,
|
||||||
|
CommittedCandidateReceipt,
|
||||||
};
|
};
|
||||||
use polkadot_subsystem_testhelpers as test_helpers;
|
use polkadot_subsystem_testhelpers as test_helpers;
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ use futures::{executor, future, Future};
|
|||||||
use sc_keystore::LocalKeystore;
|
use sc_keystore::LocalKeystore;
|
||||||
use sp_application_crypto::AppKey;
|
use sp_application_crypto::AppKey;
|
||||||
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
|
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
|
||||||
|
use sp_keyring::Sr25519Keyring;
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use maplit::hashmap;
|
use maplit::hashmap;
|
||||||
|
|
||||||
@@ -95,20 +97,19 @@ async fn overseer_recv(
|
|||||||
msg
|
msg
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dummy_occupied_core(para: ParaId) -> CoreState {
|
fn occupied_core_from_candidate(receipt: &CommittedCandidateReceipt) -> CoreState {
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: para,
|
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 0,
|
occupied_since: 0,
|
||||||
time_out_at: 5,
|
time_out_at: 5,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: Default::default(),
|
availability: Default::default(),
|
||||||
group_responsible: GroupIndex::from(0),
|
group_responsible: GroupIndex::from(0),
|
||||||
|
candidate_hash: receipt.hash(),
|
||||||
|
candidate_descriptor: receipt.descriptor().clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
use sp_keyring::Sr25519Keyring;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct TestState {
|
struct TestState {
|
||||||
chain_ids: Vec<ParaId>,
|
chain_ids: Vec<ParaId>,
|
||||||
@@ -388,7 +389,6 @@ async fn change_our_view(
|
|||||||
ancestors: Vec<Hash>,
|
ancestors: Vec<Hash>,
|
||||||
session_per_relay_parent: HashMap<Hash, SessionIndex>,
|
session_per_relay_parent: HashMap<Hash, SessionIndex>,
|
||||||
availability_cores_per_relay_parent: HashMap<Hash, Vec<CoreState>>,
|
availability_cores_per_relay_parent: HashMap<Hash, Vec<CoreState>>,
|
||||||
candidate_pending_availabilities_per_relay_parent: HashMap<Hash, Vec<CommittedCandidateReceipt>>,
|
|
||||||
data_availability: HashMap<CandidateHash, bool>,
|
data_availability: HashMap<CandidateHash, bool>,
|
||||||
chunk_data_per_candidate: HashMap<CandidateHash, (PoV, PersistedValidationData)>,
|
chunk_data_per_candidate: HashMap<CandidateHash, (PoV, PersistedValidationData)>,
|
||||||
send_chunks_to: HashMap<CandidateHash, Vec<PeerId>>,
|
send_chunks_to: HashMap<CandidateHash, Vec<PeerId>>,
|
||||||
@@ -436,7 +436,7 @@ async fn change_our_view(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0..availability_cores_per_relay_parent.len() {
|
for _ in 0..availability_cores_per_relay_parent.len() {
|
||||||
let relay_parent = assert_matches!(
|
assert_matches!(
|
||||||
overseer_recv(virtual_overseer).await,
|
overseer_recv(virtual_overseer).await,
|
||||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||||
relay_parent,
|
relay_parent,
|
||||||
@@ -446,30 +446,8 @@ async fn change_our_view(
|
|||||||
.expect(&format!("Availability core for relay parent {:?} does not exist", relay_parent));
|
.expect(&format!("Availability core for relay parent {:?} does not exist", relay_parent));
|
||||||
|
|
||||||
tx.send(Ok(cores.clone())).unwrap();
|
tx.send(Ok(cores.clone())).unwrap();
|
||||||
relay_parent
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let pending_availability = candidate_pending_availabilities_per_relay_parent.get(&relay_parent)
|
|
||||||
.expect(&format!("Candidate pending availability for relay parent {:?} does not exist", relay_parent));
|
|
||||||
|
|
||||||
for _ in 0..pending_availability.len() {
|
|
||||||
assert_matches!(
|
|
||||||
overseer_recv(virtual_overseer).await,
|
|
||||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
|
||||||
hash,
|
|
||||||
RuntimeApiRequest::CandidatePendingAvailability(para, tx)
|
|
||||||
)) => {
|
|
||||||
assert_eq!(relay_parent, hash);
|
|
||||||
|
|
||||||
let candidate = pending_availability.iter()
|
|
||||||
.find(|c| c.descriptor.para_id == para)
|
|
||||||
.expect(&format!("Pending candidate for para {} does not exist", para));
|
|
||||||
|
|
||||||
tx.send(Ok(Some(candidate.clone()))).unwrap();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0..data_availability.len() {
|
for _ in 0..data_availability.len() {
|
||||||
@@ -571,7 +549,6 @@ fn check_views() {
|
|||||||
let mut virtual_overseer = test_harness.virtual_overseer;
|
let mut virtual_overseer = test_harness.virtual_overseer;
|
||||||
|
|
||||||
let TestState {
|
let TestState {
|
||||||
chain_ids,
|
|
||||||
validator_public,
|
validator_public,
|
||||||
relay_parent: current,
|
relay_parent: current,
|
||||||
ancestors,
|
ancestors,
|
||||||
@@ -588,36 +565,37 @@ fn check_views() {
|
|||||||
vec![ancestors[0], genesis],
|
vec![ancestors[0], genesis],
|
||||||
hashmap! { current => 1, genesis => 1 },
|
hashmap! { current => 1, genesis => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
ancestors[0] => vec![dummy_occupied_core(chain_ids[0]), dummy_occupied_core(chain_ids[1])],
|
ancestors[0] => vec![
|
||||||
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
|
occupied_core_from_candidate(&candidates[1]),
|
||||||
|
],
|
||||||
current => vec![
|
current => vec![
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: chain_ids[0].clone(),
|
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 0,
|
occupied_since: 0,
|
||||||
time_out_at: 10,
|
time_out_at: 10,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: Default::default(),
|
availability: Default::default(),
|
||||||
group_responsible: GroupIndex::from(0),
|
group_responsible: GroupIndex::from(0),
|
||||||
|
candidate_hash: candidates[0].hash(),
|
||||||
|
candidate_descriptor: candidates[0].descriptor().clone(),
|
||||||
}),
|
}),
|
||||||
CoreState::Free,
|
CoreState::Free,
|
||||||
CoreState::Free,
|
CoreState::Free,
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: chain_ids[1].clone(),
|
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 1,
|
occupied_since: 1,
|
||||||
time_out_at: 7,
|
time_out_at: 7,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: Default::default(),
|
availability: Default::default(),
|
||||||
group_responsible: GroupIndex::from(0),
|
group_responsible: GroupIndex::from(0),
|
||||||
|
candidate_hash: candidates[1].hash(),
|
||||||
|
candidate_descriptor: candidates[1].descriptor().clone(),
|
||||||
}),
|
}),
|
||||||
CoreState::Free,
|
CoreState::Free,
|
||||||
CoreState::Free,
|
CoreState::Free,
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
hashmap! {
|
|
||||||
ancestors[0] => vec![candidates[0].clone(), candidates[1].clone()],
|
|
||||||
current => vec![candidates[0].clone(), candidates[1].clone()],
|
|
||||||
},
|
|
||||||
hashmap! {
|
hashmap! {
|
||||||
candidates[0].hash() => true,
|
candidates[0].hash() => true,
|
||||||
candidates[1].hash() => false,
|
candidates[1].hash() => false,
|
||||||
@@ -690,11 +668,10 @@ fn reputation_verification() {
|
|||||||
hashmap! { current => 1 },
|
hashmap! { current => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
current => vec![
|
current => vec![
|
||||||
dummy_occupied_core(candidates[0].descriptor.para_id),
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
dummy_occupied_core(candidates[1].descriptor.para_id)
|
occupied_core_from_candidate(&candidates[1]),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
hashmap! { current => vec![candidates[0].clone(), candidates[1].clone()] },
|
|
||||||
hashmap! { candidates[0].hash() => true, candidates[1].hash() => false },
|
hashmap! { candidates[0].hash() => true, candidates[1].hash() => false },
|
||||||
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
||||||
hashmap! {},
|
hashmap! {},
|
||||||
@@ -783,10 +760,9 @@ fn not_a_live_candidate_is_detected() {
|
|||||||
hashmap! { current => 1 },
|
hashmap! { current => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
current => vec![
|
current => vec![
|
||||||
dummy_occupied_core(candidates[0].descriptor.para_id),
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
hashmap! { current => vec![candidates[0].clone()] },
|
|
||||||
hashmap! { candidates[0].hash() => true },
|
hashmap! { candidates[0].hash() => true },
|
||||||
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
||||||
hashmap! {},
|
hashmap! {},
|
||||||
@@ -832,10 +808,9 @@ fn peer_change_view_before_us() {
|
|||||||
hashmap! { current => 1 },
|
hashmap! { current => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
current => vec![
|
current => vec![
|
||||||
dummy_occupied_core(candidates[0].descriptor.para_id),
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
hashmap! { current => vec![candidates[0].clone()] },
|
|
||||||
hashmap! { candidates[0].hash() => true },
|
hashmap! { candidates[0].hash() => true },
|
||||||
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
||||||
hashmap! { candidates[0].hash() => vec![peer_a.clone()] },
|
hashmap! { candidates[0].hash() => vec![peer_a.clone()] },
|
||||||
@@ -880,10 +855,9 @@ fn candidate_chunks_are_put_into_message_vault_when_candidate_is_first_seen() {
|
|||||||
hashmap! { ancestors[0] => 1 },
|
hashmap! { ancestors[0] => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
ancestors[0] => vec![
|
ancestors[0] => vec![
|
||||||
dummy_occupied_core(candidates[0].descriptor.para_id),
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
hashmap! { ancestors[0] => vec![candidates[0].clone()] },
|
|
||||||
hashmap! { candidates[0].hash() => true },
|
hashmap! { candidates[0].hash() => true },
|
||||||
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
||||||
hashmap! {},
|
hashmap! {},
|
||||||
@@ -897,10 +871,9 @@ fn candidate_chunks_are_put_into_message_vault_when_candidate_is_first_seen() {
|
|||||||
hashmap! { current => 1 },
|
hashmap! { current => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
current => vec![
|
current => vec![
|
||||||
dummy_occupied_core(candidates[0].descriptor.para_id),
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
hashmap! { current => vec![candidates[0].clone()] },
|
|
||||||
hashmap! { candidates[0].hash() => true },
|
hashmap! { candidates[0].hash() => true },
|
||||||
hashmap! {},
|
hashmap! {},
|
||||||
hashmap! {},
|
hashmap! {},
|
||||||
@@ -1168,50 +1141,28 @@ fn query_pending_availability_at_pulls_from_and_updates_receipts() {
|
|||||||
) if r == hash_b => {
|
) if r == hash_b => {
|
||||||
let _ = tx.send(Ok(vec![
|
let _ = tx.send(Ok(vec![
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: para_b,
|
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 0,
|
occupied_since: 0,
|
||||||
time_out_at: 0,
|
time_out_at: 0,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: Default::default(),
|
availability: Default::default(),
|
||||||
group_responsible: GroupIndex::from(0),
|
group_responsible: GroupIndex::from(0),
|
||||||
|
candidate_hash: candidate_hash_b,
|
||||||
|
candidate_descriptor: candidate_b.descriptor.clone(),
|
||||||
}),
|
}),
|
||||||
CoreState::Occupied(OccupiedCore {
|
CoreState::Occupied(OccupiedCore {
|
||||||
para_id: para_c,
|
|
||||||
next_up_on_available: None,
|
next_up_on_available: None,
|
||||||
occupied_since: 0,
|
occupied_since: 0,
|
||||||
time_out_at: 0,
|
time_out_at: 0,
|
||||||
next_up_on_time_out: None,
|
next_up_on_time_out: None,
|
||||||
availability: Default::default(),
|
availability: Default::default(),
|
||||||
group_responsible: GroupIndex::from(0),
|
group_responsible: GroupIndex::from(0),
|
||||||
|
candidate_hash: candidate_hash_c,
|
||||||
|
candidate_descriptor: candidate_c.descriptor.clone(),
|
||||||
}),
|
}),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
overseer_recv(&mut virtual_overseer).await,
|
|
||||||
AllMessages::RuntimeApi(
|
|
||||||
RuntimeApiMessage::Request(
|
|
||||||
r,
|
|
||||||
RuntimeApiRequest::CandidatePendingAvailability(p, tx),
|
|
||||||
)
|
|
||||||
) if r == hash_b && p == para_b => {
|
|
||||||
let _ = tx.send(Ok(Some(candidate_b)));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
overseer_recv(&mut virtual_overseer).await,
|
|
||||||
AllMessages::RuntimeApi(
|
|
||||||
RuntimeApiMessage::Request(
|
|
||||||
r,
|
|
||||||
RuntimeApiRequest::CandidatePendingAvailability(p, tx),
|
|
||||||
)
|
|
||||||
) if r == hash_b && p == para_c => {
|
|
||||||
let _ = tx.send(Ok(Some(candidate_c)));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
futures::pin_mut!(test_fut);
|
futures::pin_mut!(test_fut);
|
||||||
@@ -1256,11 +1207,10 @@ fn new_peer_gets_all_chunks_send() {
|
|||||||
hashmap! { current => 1 },
|
hashmap! { current => 1 },
|
||||||
hashmap! {
|
hashmap! {
|
||||||
current => vec![
|
current => vec![
|
||||||
dummy_occupied_core(candidates[0].descriptor.para_id),
|
occupied_core_from_candidate(&candidates[0]),
|
||||||
dummy_occupied_core(candidates[1].descriptor.para_id)
|
occupied_core_from_candidate(&candidates[1])
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
hashmap! { current => vec![candidates[0].clone(), candidates[1].clone()] },
|
|
||||||
hashmap! { candidates[0].hash() => true, candidates[1].hash() => false },
|
hashmap! { candidates[0].hash() => true, candidates[1].hash() => false },
|
||||||
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
hashmap! { candidates[0].hash() => (pov_blocks[0].clone(), test_state.persisted_validation_data.clone())},
|
||||||
hashmap! {},
|
hashmap! {},
|
||||||
|
|||||||
@@ -576,11 +576,11 @@ impl<N: Saturating + BaseArithmetic + Copy> GroupRotationInfo<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Information about a core which is currently occupied.
|
/// Information about a core which is currently occupied.
|
||||||
#[derive(Clone, Encode, Decode, Debug)]
|
#[derive(Clone, Encode, Decode)]
|
||||||
#[cfg_attr(feature = "std", derive(PartialEq))]
|
#[cfg_attr(feature = "std", derive(Debug, PartialEq))]
|
||||||
pub struct OccupiedCore<N = BlockNumber> {
|
pub struct OccupiedCore<H = Hash, N = BlockNumber> {
|
||||||
/// The ID of the para occupying the core.
|
// NOTE: this has no ParaId as it can be deduced from the candidate descriptor.
|
||||||
pub para_id: Id,
|
|
||||||
/// If this core is freed by availability, this is the assignment that is next up on this
|
/// If this core is freed by availability, this is the assignment that is next up on this
|
||||||
/// core, if any. None if there is nothing queued for this core.
|
/// core, if any. None if there is nothing queued for this core.
|
||||||
pub next_up_on_available: Option<ScheduledCore>,
|
pub next_up_on_available: Option<ScheduledCore>,
|
||||||
@@ -598,11 +598,22 @@ pub struct OccupiedCore<N = BlockNumber> {
|
|||||||
pub availability: BitVec<bitvec::order::Lsb0, u8>,
|
pub availability: BitVec<bitvec::order::Lsb0, u8>,
|
||||||
/// The group assigned to distribute availability pieces of this candidate.
|
/// The group assigned to distribute availability pieces of this candidate.
|
||||||
pub group_responsible: GroupIndex,
|
pub group_responsible: GroupIndex,
|
||||||
|
/// The hash of the candidate occupying the core.
|
||||||
|
pub candidate_hash: CandidateHash,
|
||||||
|
/// The descriptor of the candidate occupying the core.
|
||||||
|
pub candidate_descriptor: CandidateDescriptor<H>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<H, N> OccupiedCore<H, N> {
|
||||||
|
/// Get the Para currently occupying this core.
|
||||||
|
pub fn para_id(&self) -> Id {
|
||||||
|
self.candidate_descriptor.para_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about a core which is currently occupied.
|
/// Information about a core which is currently occupied.
|
||||||
#[derive(Clone, Encode, Decode, Debug)]
|
#[derive(Clone, Encode, Decode)]
|
||||||
#[cfg_attr(feature = "std", derive(PartialEq, Default))]
|
#[cfg_attr(feature = "std", derive(Debug, PartialEq, Default))]
|
||||||
pub struct ScheduledCore {
|
pub struct ScheduledCore {
|
||||||
/// The ID of a para scheduled.
|
/// The ID of a para scheduled.
|
||||||
pub para_id: Id,
|
pub para_id: Id,
|
||||||
@@ -611,12 +622,12 @@ pub struct ScheduledCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The state of a particular availability core.
|
/// The state of a particular availability core.
|
||||||
#[derive(Clone, Encode, Decode, Debug)]
|
#[derive(Clone, Encode, Decode)]
|
||||||
#[cfg_attr(feature = "std", derive(PartialEq))]
|
#[cfg_attr(feature = "std", derive(Debug, PartialEq))]
|
||||||
pub enum CoreState<N = BlockNumber> {
|
pub enum CoreState<H = Hash, N = BlockNumber> {
|
||||||
/// The core is currently occupied.
|
/// The core is currently occupied.
|
||||||
#[codec(index = "0")]
|
#[codec(index = "0")]
|
||||||
Occupied(OccupiedCore<N>),
|
Occupied(OccupiedCore<H, N>),
|
||||||
/// The core is currently free, with a para scheduled and given the opportunity
|
/// The core is currently free, with a para scheduled and given the opportunity
|
||||||
/// to occupy.
|
/// to occupy.
|
||||||
///
|
///
|
||||||
@@ -634,7 +645,7 @@ impl<N> CoreState<N> {
|
|||||||
/// If this core state has a `para_id`, return it.
|
/// If this core state has a `para_id`, return it.
|
||||||
pub fn para_id(&self) -> Option<Id> {
|
pub fn para_id(&self) -> Option<Id> {
|
||||||
match self {
|
match self {
|
||||||
Self::Occupied(OccupiedCore { para_id, ..}) => Some(*para_id),
|
Self::Occupied(ref core) => Some(core.para_id()),
|
||||||
Self::Scheduled(ScheduledCore { para_id, .. }) => Some(*para_id),
|
Self::Scheduled(ScheduledCore { para_id, .. }) => Some(*para_id),
|
||||||
Self::Free => None,
|
Self::Free => None,
|
||||||
}
|
}
|
||||||
@@ -718,7 +729,7 @@ sp_api::decl_runtime_apis! {
|
|||||||
|
|
||||||
/// Yields information on all availability cores. Cores are either free or occupied. Free
|
/// Yields information on all availability cores. Cores are either free or occupied. Free
|
||||||
/// cores can have paras assigned to them.
|
/// cores can have paras assigned to them.
|
||||||
fn availability_cores() -> Vec<CoreState<N>>;
|
fn availability_cores() -> Vec<CoreState<H, N>>;
|
||||||
|
|
||||||
/// Yields the full validation data for the given ParaId along with an assumption that
|
/// Yields the full validation data for the given ParaId along with an assumption that
|
||||||
/// should be used if the para currently occupieds a core.
|
/// should be used if the para currently occupieds a core.
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ If not running as a validator, do nothing.
|
|||||||
|
|
||||||
- Begin by waiting a fixed period of time so availability distribution has the chance to make candidates available.
|
- Begin by waiting a fixed period of time so availability distribution has the chance to make candidates available.
|
||||||
- Determine our validator index `i`, the set of backed candidates pending availability in `r`, and which bit of the bitfield each corresponds to.
|
- Determine our validator index `i`, the set of backed candidates pending availability in `r`, and which bit of the bitfield each corresponds to.
|
||||||
- Start with an empty bitfield. For each bit in the bitfield, if there is a candidate pending availability, query the [Availability Store](../utility/availability-store.md) for whether we have the availability chunk for our validator index.
|
- Start with an empty bitfield. For each bit in the bitfield, if there is a candidate pending availability, query the [Availability Store](../utility/availability-store.md) for whether we have the availability chunk for our validator index. The `OccupiedCore` struct contains the candidate hash so the full candidate does not need to be fetched from runtime.
|
||||||
- For all chunks we have, set the corresponding bit in the bitfield.
|
- For all chunks we have, set the corresponding bit in the bitfield.
|
||||||
- Sign the bitfield and dispatch a `BitfieldDistribution::DistributeBitfield` message.
|
- Sign the bitfield and dispatch a `BitfieldDistribution::DistributeBitfield` message.
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ This is all the information that a validator needs about scheduling for the curr
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
struct OccupiedCore {
|
struct OccupiedCore {
|
||||||
/// The ID of the para occupying the core.
|
// NOTE: this has no ParaId as it can be deduced from the candidate descriptor.
|
||||||
para_id: ParaId,
|
|
||||||
/// If this core is freed by availability, this is the assignment that is next up on this
|
/// If this core is freed by availability, this is the assignment that is next up on this
|
||||||
/// core, if any. None if there is nothing queued for this core.
|
/// core, if any. None if there is nothing queued for this core.
|
||||||
next_up_on_available: Option<ScheduledCore>,
|
next_up_on_available: Option<ScheduledCore>,
|
||||||
@@ -31,6 +30,10 @@ struct OccupiedCore {
|
|||||||
availability: Bitfield,
|
availability: Bitfield,
|
||||||
/// The group assigned to distribute availability pieces of this candidate.
|
/// The group assigned to distribute availability pieces of this candidate.
|
||||||
group_responsible: GroupIndex,
|
group_responsible: GroupIndex,
|
||||||
|
/// The hash of the candidate occupying the core.
|
||||||
|
candidate_hash: CandidateHash,
|
||||||
|
/// The descriptor of the candidate occupying the core.
|
||||||
|
candidate_descriptor: CandidateDescriptor,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ScheduledCore {
|
struct ScheduledCore {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct AvailabilityBitfield {
|
|||||||
|
|
||||||
struct CandidatePendingAvailability {
|
struct CandidatePendingAvailability {
|
||||||
core: CoreIndex, // availability core
|
core: CoreIndex, // availability core
|
||||||
|
hash: CandidateHash,
|
||||||
descriptor: CandidateDescriptor,
|
descriptor: CandidateDescriptor,
|
||||||
availability_votes: Bitfield, // one bit per validator.
|
availability_votes: Bitfield, // one bit per validator.
|
||||||
relay_parent_number: BlockNumber, // number of the relay-parent.
|
relay_parent_number: BlockNumber, // number of the relay-parent.
|
||||||
|
|||||||
@@ -1347,7 +1347,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
(Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 })
|
(Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
|
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use primitives::v1::{
|
|||||||
ValidatorId, CandidateCommitments, CandidateDescriptor, ValidatorIndex, Id as ParaId,
|
ValidatorId, CandidateCommitments, CandidateDescriptor, ValidatorIndex, Id as ParaId,
|
||||||
AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext,
|
AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext,
|
||||||
BackedCandidate, CoreIndex, GroupIndex, CommittedCandidateReceipt,
|
BackedCandidate, CoreIndex, GroupIndex, CommittedCandidateReceipt,
|
||||||
CandidateReceipt, HeadData,
|
CandidateReceipt, HeadData, CandidateHash,
|
||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
decl_storage, decl_module, decl_error, decl_event, ensure, debug,
|
decl_storage, decl_module, decl_error, decl_event, ensure, debug,
|
||||||
@@ -58,6 +58,8 @@ pub struct AvailabilityBitfieldRecord<N> {
|
|||||||
pub struct CandidatePendingAvailability<H, N> {
|
pub struct CandidatePendingAvailability<H, N> {
|
||||||
/// The availability core this is assigned to.
|
/// The availability core this is assigned to.
|
||||||
core: CoreIndex,
|
core: CoreIndex,
|
||||||
|
/// The candidate hash.
|
||||||
|
hash: CandidateHash,
|
||||||
/// The candidate descriptor.
|
/// The candidate descriptor.
|
||||||
descriptor: CandidateDescriptor<H>,
|
descriptor: CandidateDescriptor<H>,
|
||||||
/// The received availability votes. One bit per validator.
|
/// The received availability votes. One bit per validator.
|
||||||
@@ -85,6 +87,16 @@ impl<H, N> CandidatePendingAvailability<H, N> {
|
|||||||
pub(crate) fn core_occupied(&self)-> CoreIndex {
|
pub(crate) fn core_occupied(&self)-> CoreIndex {
|
||||||
self.core.clone()
|
self.core.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the candidate hash.
|
||||||
|
pub(crate) fn candidate_hash(&self) -> CandidateHash {
|
||||||
|
self.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the canddiate descriptor.
|
||||||
|
pub(crate) fn candidate_descriptor(&self) -> &CandidateDescriptor<H> {
|
||||||
|
&self.descriptor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A hook for applying validator rewards
|
/// A hook for applying validator rewards
|
||||||
@@ -568,6 +580,8 @@ impl<T: Config> Module<T> {
|
|||||||
candidate.candidate.commitments.head_data.clone(),
|
candidate.candidate.commitments.head_data.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let candidate_hash = candidate.candidate.hash();
|
||||||
|
|
||||||
let (descriptor, commitments) = (
|
let (descriptor, commitments) = (
|
||||||
candidate.candidate.descriptor,
|
candidate.candidate.descriptor,
|
||||||
candidate.candidate.commitments,
|
candidate.candidate.commitments,
|
||||||
@@ -575,6 +589,7 @@ impl<T: Config> Module<T> {
|
|||||||
|
|
||||||
<PendingAvailability<T>>::insert(¶_id, CandidatePendingAvailability {
|
<PendingAvailability<T>>::insert(¶_id, CandidatePendingAvailability {
|
||||||
core,
|
core,
|
||||||
|
hash: candidate_hash,
|
||||||
descriptor,
|
descriptor,
|
||||||
availability_votes,
|
availability_votes,
|
||||||
relay_parent_number: check_cx.relay_parent_number,
|
relay_parent_number: check_cx.relay_parent_number,
|
||||||
@@ -1112,6 +1127,7 @@ mod tests {
|
|||||||
let default_candidate = TestCandidateBuilder::default().build();
|
let default_candidate = TestCandidateBuilder::default().build();
|
||||||
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: default_candidate.hash(),
|
||||||
descriptor: default_candidate.descriptor.clone(),
|
descriptor: default_candidate.descriptor.clone(),
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 0,
|
relay_parent_number: 0,
|
||||||
@@ -1122,6 +1138,7 @@ mod tests {
|
|||||||
|
|
||||||
<PendingAvailability<Test>>::insert(&chain_b, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(&chain_b, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(1),
|
core: CoreIndex::from(1),
|
||||||
|
hash: default_candidate.hash(),
|
||||||
descriptor: default_candidate.descriptor,
|
descriptor: default_candidate.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 0,
|
relay_parent_number: 0,
|
||||||
@@ -1286,6 +1303,7 @@ mod tests {
|
|||||||
let default_candidate = TestCandidateBuilder::default().build();
|
let default_candidate = TestCandidateBuilder::default().build();
|
||||||
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: default_candidate.hash(),
|
||||||
descriptor: default_candidate.descriptor,
|
descriptor: default_candidate.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 0,
|
relay_parent_number: 0,
|
||||||
@@ -1321,6 +1339,7 @@ mod tests {
|
|||||||
let default_candidate = TestCandidateBuilder::default().build();
|
let default_candidate = TestCandidateBuilder::default().build();
|
||||||
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: default_candidate.hash(),
|
||||||
descriptor: default_candidate.descriptor,
|
descriptor: default_candidate.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 0,
|
relay_parent_number: 0,
|
||||||
@@ -1393,6 +1412,7 @@ mod tests {
|
|||||||
|
|
||||||
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(chain_a, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: candidate_a.hash(),
|
||||||
descriptor: candidate_a.descriptor,
|
descriptor: candidate_a.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 0,
|
relay_parent_number: 0,
|
||||||
@@ -1409,6 +1429,7 @@ mod tests {
|
|||||||
|
|
||||||
<PendingAvailability<Test>>::insert(chain_b, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(chain_b, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(1),
|
core: CoreIndex::from(1),
|
||||||
|
hash: candidate_b.hash(),
|
||||||
descriptor: candidate_b.descriptor,
|
descriptor: candidate_b.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 0,
|
relay_parent_number: 0,
|
||||||
@@ -1839,6 +1860,7 @@ mod tests {
|
|||||||
let candidate = TestCandidateBuilder::default().build();
|
let candidate = TestCandidateBuilder::default().build();
|
||||||
<PendingAvailability<Test>>::insert(&chain_a, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(&chain_a, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: candidate.hash(),
|
||||||
descriptor: candidate.descriptor,
|
descriptor: candidate.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 3,
|
relay_parent_number: 3,
|
||||||
@@ -2127,6 +2149,7 @@ mod tests {
|
|||||||
<PendingAvailability<Test>>::get(&chain_a),
|
<PendingAvailability<Test>>::get(&chain_a),
|
||||||
Some(CandidatePendingAvailability {
|
Some(CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: candidate_a.hash(),
|
||||||
descriptor: candidate_a.descriptor,
|
descriptor: candidate_a.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: System::block_number() - 1,
|
relay_parent_number: System::block_number() - 1,
|
||||||
@@ -2143,6 +2166,7 @@ mod tests {
|
|||||||
<PendingAvailability<Test>>::get(&chain_b),
|
<PendingAvailability<Test>>::get(&chain_b),
|
||||||
Some(CandidatePendingAvailability {
|
Some(CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(1),
|
core: CoreIndex::from(1),
|
||||||
|
hash: candidate_b.hash(),
|
||||||
descriptor: candidate_b.descriptor,
|
descriptor: candidate_b.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: System::block_number() - 1,
|
relay_parent_number: System::block_number() - 1,
|
||||||
@@ -2159,6 +2183,7 @@ mod tests {
|
|||||||
<PendingAvailability<Test>>::get(&thread_a),
|
<PendingAvailability<Test>>::get(&thread_a),
|
||||||
Some(CandidatePendingAvailability {
|
Some(CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(2),
|
core: CoreIndex::from(2),
|
||||||
|
hash: candidate_c.hash(),
|
||||||
descriptor: candidate_c.descriptor,
|
descriptor: candidate_c.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: System::block_number() - 1,
|
relay_parent_number: System::block_number() - 1,
|
||||||
@@ -2254,6 +2279,7 @@ mod tests {
|
|||||||
<PendingAvailability<Test>>::get(&chain_a),
|
<PendingAvailability<Test>>::get(&chain_a),
|
||||||
Some(CandidatePendingAvailability {
|
Some(CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: candidate_a.hash(),
|
||||||
descriptor: candidate_a.descriptor,
|
descriptor: candidate_a.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: System::block_number() - 1,
|
relay_parent_number: System::block_number() - 1,
|
||||||
@@ -2329,6 +2355,7 @@ mod tests {
|
|||||||
let candidate = TestCandidateBuilder::default().build();
|
let candidate = TestCandidateBuilder::default().build();
|
||||||
<PendingAvailability<Test>>::insert(&chain_a, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(&chain_a, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(0),
|
core: CoreIndex::from(0),
|
||||||
|
hash: candidate.hash(),
|
||||||
descriptor: candidate.descriptor.clone(),
|
descriptor: candidate.descriptor.clone(),
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 5,
|
relay_parent_number: 5,
|
||||||
@@ -2339,6 +2366,7 @@ mod tests {
|
|||||||
|
|
||||||
<PendingAvailability<Test>>::insert(&chain_b, CandidatePendingAvailability {
|
<PendingAvailability<Test>>::insert(&chain_b, CandidatePendingAvailability {
|
||||||
core: CoreIndex::from(1),
|
core: CoreIndex::from(1),
|
||||||
|
hash: candidate.hash(),
|
||||||
descriptor: candidate.descriptor,
|
descriptor: candidate.descriptor,
|
||||||
availability_votes: default_availability_votes(),
|
availability_votes: default_availability_votes(),
|
||||||
relay_parent_number: 6,
|
relay_parent_number: 6,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub fn validator_groups<T: initializer::Config>() -> (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation for the `availability_cores` function of the runtime API.
|
/// Implementation for the `availability_cores` function of the runtime API.
|
||||||
pub fn availability_cores<T: initializer::Config>() -> Vec<CoreState<T::BlockNumber>> {
|
pub fn availability_cores<T: initializer::Config>() -> Vec<CoreState<T::Hash, T::BlockNumber>> {
|
||||||
let cores = <scheduler::Module<T>>::availability_cores();
|
let cores = <scheduler::Module<T>>::availability_cores();
|
||||||
let parachains = <paras::Module<T>>::parachains();
|
let parachains = <paras::Module<T>>::parachains();
|
||||||
let config = <configuration::Module<T>>::config();
|
let config = <configuration::Module<T>>::config();
|
||||||
@@ -96,7 +96,6 @@ pub fn availability_cores<T: initializer::Config>() -> Vec<CoreState<T::BlockNum
|
|||||||
|
|
||||||
let backed_in_number = pending_availability.backed_in_number().clone();
|
let backed_in_number = pending_availability.backed_in_number().clone();
|
||||||
OccupiedCore {
|
OccupiedCore {
|
||||||
para_id,
|
|
||||||
next_up_on_available: <scheduler::Module<T>>::next_up_on_available(
|
next_up_on_available: <scheduler::Module<T>>::next_up_on_available(
|
||||||
CoreIndex(i as u32)
|
CoreIndex(i as u32)
|
||||||
),
|
),
|
||||||
@@ -113,6 +112,8 @@ pub fn availability_cores<T: initializer::Config>() -> Vec<CoreState<T::BlockNum
|
|||||||
backed_in_number,
|
backed_in_number,
|
||||||
pending_availability.core_occupied(),
|
pending_availability.core_occupied(),
|
||||||
),
|
),
|
||||||
|
candidate_hash: pending_availability.candidate_hash(),
|
||||||
|
candidate_descriptor: pending_availability.candidate_descriptor().clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CoreOccupied::Parathread(p) => {
|
CoreOccupied::Parathread(p) => {
|
||||||
@@ -123,7 +124,6 @@ pub fn availability_cores<T: initializer::Config>() -> Vec<CoreState<T::BlockNum
|
|||||||
|
|
||||||
let backed_in_number = pending_availability.backed_in_number().clone();
|
let backed_in_number = pending_availability.backed_in_number().clone();
|
||||||
OccupiedCore {
|
OccupiedCore {
|
||||||
para_id,
|
|
||||||
next_up_on_available: <scheduler::Module<T>>::next_up_on_available(
|
next_up_on_available: <scheduler::Module<T>>::next_up_on_available(
|
||||||
CoreIndex(i as u32)
|
CoreIndex(i as u32)
|
||||||
),
|
),
|
||||||
@@ -140,6 +140,8 @@ pub fn availability_cores<T: initializer::Config>() -> Vec<CoreState<T::BlockNum
|
|||||||
backed_in_number,
|
backed_in_number,
|
||||||
pending_availability.core_occupied(),
|
pending_availability.core_occupied(),
|
||||||
),
|
),
|
||||||
|
candidate_hash: pending_availability.candidate_hash(),
|
||||||
|
candidate_descriptor: pending_availability.candidate_descriptor().clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1122,7 +1122,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
(Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 })
|
(Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
|
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
runtime_api_impl::validator_groups::<Runtime>()
|
runtime_api_impl::validator_groups::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
|
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
|
||||||
runtime_api_impl::availability_cores::<Runtime>()
|
runtime_api_impl::availability_cores::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -631,7 +631,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
runtime_impl::validator_groups::<Runtime>()
|
runtime_impl::validator_groups::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
|
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
|
||||||
runtime_impl::availability_cores::<Runtime>()
|
runtime_impl::availability_cores::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -844,7 +844,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
(Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 })
|
(Vec::new(), GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 0, now: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
|
fn availability_cores() -> Vec<CoreState<Hash, BlockNumber>> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user