mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 12:17:58 +00:00
cargo +nightly fmt (#3540)
* cargo +nightly fmt * add cargo-fmt check to ci * update ci * fmt * fmt * skip macro * ignore bridges
This commit is contained in:
@@ -14,44 +14,49 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::{collections::{HashMap, HashSet, VecDeque}, pin::Pin, time::Duration};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet, VecDeque},
|
||||
pin::Pin,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use futures::{FutureExt, StreamExt, channel::oneshot, stream::FuturesUnordered, select, Future};
|
||||
use futures::{channel::oneshot, select, stream::FuturesUnordered, Future, FutureExt, StreamExt};
|
||||
use sp_core::Pair;
|
||||
|
||||
use polkadot_node_network_protocol::{
|
||||
peer_set::PeerSet,
|
||||
request_response::{
|
||||
request::OutgoingResponse,
|
||||
v1::{CollationFetchingRequest, CollationFetchingResponse},
|
||||
IncomingRequest,
|
||||
},
|
||||
v1 as protocol_v1, OurView, PeerId, UnifiedReputationChange as Rep, View,
|
||||
};
|
||||
use polkadot_node_primitives::{PoV, SignedFullStatement, Statement};
|
||||
use polkadot_node_subsystem_util::{
|
||||
metrics::{self, prometheus},
|
||||
runtime::{get_availability_cores, get_group_rotation_info, RuntimeInfo},
|
||||
TimeoutExt,
|
||||
};
|
||||
use polkadot_primitives::v1::{
|
||||
AuthorityDiscoveryId, CandidateHash, CandidateReceipt, CollatorPair, CoreIndex, CoreState, GroupIndex, Hash,
|
||||
Id as ParaId,
|
||||
AuthorityDiscoveryId, CandidateHash, CandidateReceipt, CollatorPair, CoreIndex, CoreState,
|
||||
GroupIndex, Hash, Id as ParaId,
|
||||
};
|
||||
use polkadot_subsystem::{
|
||||
overseer,
|
||||
FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, jaeger,
|
||||
messages::{
|
||||
CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage,
|
||||
},
|
||||
jaeger,
|
||||
messages::{CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage},
|
||||
overseer, FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext,
|
||||
};
|
||||
use polkadot_node_network_protocol::{
|
||||
OurView, PeerId, UnifiedReputationChange as Rep, View, peer_set::PeerSet,
|
||||
request_response::{
|
||||
IncomingRequest, request::OutgoingResponse, v1::{CollationFetchingRequest, CollationFetchingResponse}
|
||||
},
|
||||
v1 as protocol_v1,
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
TimeoutExt,
|
||||
metrics::{self, prometheus},
|
||||
runtime::{RuntimeInfo, get_availability_cores, get_group_rotation_info}
|
||||
};
|
||||
use polkadot_node_primitives::{SignedFullStatement, Statement, PoV};
|
||||
|
||||
use crate::error::{Fatal, NonFatal, log_error};
|
||||
use super::{LOG_TARGET, Result};
|
||||
use super::{Result, LOG_TARGET};
|
||||
use crate::error::{log_error, Fatal, NonFatal};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
const COST_UNEXPECTED_MESSAGE: Rep = Rep::CostMinor("An unexpected message");
|
||||
const COST_APPARENT_FLOOD: Rep = Rep::CostMinor("Message received when previous one was still being processed");
|
||||
const COST_APPARENT_FLOOD: Rep =
|
||||
Rep::CostMinor("Message received when previous one was still being processed");
|
||||
|
||||
/// Time after starting an upload to a validator we will start another one to the next validator,
|
||||
/// even if the upload was not finished yet.
|
||||
@@ -102,9 +107,9 @@ struct MetricsInner {
|
||||
}
|
||||
|
||||
impl metrics::Metrics for Metrics {
|
||||
fn try_register(registry: &prometheus::Registry)
|
||||
-> std::result::Result<Self, prometheus::PrometheusError>
|
||||
{
|
||||
fn try_register(
|
||||
registry: &prometheus::Registry,
|
||||
) -> std::result::Result<Self, prometheus::PrometheusError> {
|
||||
let metrics = MetricsInner {
|
||||
advertisements_made: prometheus::register(
|
||||
prometheus::Counter::new(
|
||||
@@ -128,12 +133,10 @@ impl metrics::Metrics for Metrics {
|
||||
registry,
|
||||
)?,
|
||||
process_msg: prometheus::register(
|
||||
prometheus::Histogram::with_opts(
|
||||
prometheus::HistogramOpts::new(
|
||||
"parachain_collator_protocol_collator_process_msg",
|
||||
"Time spent within `collator_protocol_collator::process_msg`",
|
||||
)
|
||||
)?,
|
||||
prometheus::Histogram::with_opts(prometheus::HistogramOpts::new(
|
||||
"parachain_collator_protocol_collator_process_msg",
|
||||
"Time spent within `collator_protocol_collator::process_msg`",
|
||||
))?,
|
||||
registry,
|
||||
)?,
|
||||
};
|
||||
@@ -157,8 +160,11 @@ struct ValidatorGroup {
|
||||
|
||||
impl ValidatorGroup {
|
||||
/// Returns `true` if we should advertise our collation to the given peer.
|
||||
fn should_advertise_to(&self, peer_ids: &HashMap<PeerId, AuthorityDiscoveryId>, peer: &PeerId)
|
||||
-> bool {
|
||||
fn should_advertise_to(
|
||||
&self,
|
||||
peer_ids: &HashMap<PeerId, AuthorityDiscoveryId>,
|
||||
peer: &PeerId,
|
||||
) -> bool {
|
||||
match peer_ids.get(peer) {
|
||||
Some(discovery_id) => !self.advertised_to.contains(discovery_id),
|
||||
None => false,
|
||||
@@ -166,7 +172,11 @@ impl ValidatorGroup {
|
||||
}
|
||||
|
||||
/// Should be called after we advertised our collation to the given `peer` to keep track of it.
|
||||
fn advertised_to_peer(&mut self, peer_ids: &HashMap<PeerId, AuthorityDiscoveryId>, peer: &PeerId) {
|
||||
fn advertised_to_peer(
|
||||
&mut self,
|
||||
peer_ids: &HashMap<PeerId, AuthorityDiscoveryId>,
|
||||
peer: &PeerId,
|
||||
) {
|
||||
if let Some(validator_id) = peer_ids.get(peer) {
|
||||
self.advertised_to.insert(validator_id.clone());
|
||||
}
|
||||
@@ -175,10 +185,7 @@ impl ValidatorGroup {
|
||||
|
||||
impl From<HashSet<AuthorityDiscoveryId>> for ValidatorGroup {
|
||||
fn from(discovery_ids: HashSet<AuthorityDiscoveryId>) -> Self {
|
||||
Self {
|
||||
discovery_ids,
|
||||
advertised_to: HashSet::new(),
|
||||
}
|
||||
Self { discovery_ids, advertised_to: HashSet::new() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +236,8 @@ struct WaitingCollationFetches {
|
||||
waiting_peers: HashSet<PeerId>,
|
||||
}
|
||||
|
||||
type ActiveCollationFetches = FuturesUnordered<Pin<Box<dyn Future<Output = (Hash, PeerId)> + Send + 'static>>>;
|
||||
type ActiveCollationFetches =
|
||||
FuturesUnordered<Pin<Box<dyn Future<Output = (Hash, PeerId)> + Send + 'static>>>;
|
||||
|
||||
struct State {
|
||||
/// Our network peer id.
|
||||
@@ -344,12 +352,12 @@ where
|
||||
"distribute collation message parent is outside of our view",
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
// We have already seen collation for this relay parent.
|
||||
if state.collations.contains_key(&relay_parent) {
|
||||
return Ok(());
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
// Determine which core the para collated-on is assigned to.
|
||||
@@ -365,12 +373,12 @@ where
|
||||
);
|
||||
|
||||
return Ok(())
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Determine the group on that core and the next group on that core.
|
||||
let (current_validators, next_validators) =
|
||||
determine_our_validators(ctx, runtime, our_core, num_cores, relay_parent,).await?;
|
||||
determine_our_validators(ctx, runtime, our_core, num_cores, relay_parent).await?;
|
||||
|
||||
if current_validators.validators.is_empty() && next_validators.validators.is_empty() {
|
||||
tracing::warn!(
|
||||
@@ -379,7 +387,7 @@ where
|
||||
"there are no validators assigned to core",
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
tracing::debug!(
|
||||
@@ -394,16 +402,19 @@ where
|
||||
"Accepted collation, connecting to validators."
|
||||
);
|
||||
|
||||
let validator_group: HashSet<_> = current_validators.validators.iter().map(Clone::clone).collect();
|
||||
let validator_group: HashSet<_> =
|
||||
current_validators.validators.iter().map(Clone::clone).collect();
|
||||
|
||||
// Issue a discovery request for the validators of the current group and the next group:
|
||||
connect_to_validators(
|
||||
ctx,
|
||||
current_validators.validators
|
||||
current_validators
|
||||
.validators
|
||||
.into_iter()
|
||||
.chain(next_validators.validators.into_iter())
|
||||
.collect(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
state.our_validators_groups.insert(relay_parent, validator_group.into());
|
||||
|
||||
@@ -411,7 +422,9 @@ where
|
||||
state.collation_result_senders.insert(receipt.hash(), result_sender);
|
||||
}
|
||||
|
||||
state.collations.insert(relay_parent, Collation { receipt, pov, status: CollationStatus::Created });
|
||||
state
|
||||
.collations
|
||||
.insert(relay_parent, Collation { receipt, pov, status: CollationStatus::Created });
|
||||
|
||||
let interested = state.peers_interested_in_leaf(&relay_parent);
|
||||
// Make sure already connected peers get collations:
|
||||
@@ -438,7 +451,7 @@ where
|
||||
for (idx, core) in cores.iter().enumerate() {
|
||||
if let CoreState::Scheduled(occupied) = core {
|
||||
if occupied.para_id == para_id {
|
||||
return Ok(Some(((idx as u32).into(), cores.len())));
|
||||
return Ok(Some(((idx as u32).into(), cores.len())))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -470,7 +483,8 @@ where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
let session_index = runtime.get_session_index(ctx.sender(), relay_parent).await?;
|
||||
let info = &runtime.get_session_info_by_index(ctx.sender(), relay_parent, session_index)
|
||||
let info = &runtime
|
||||
.get_session_info_by_index(ctx.sender(), relay_parent, session_index)
|
||||
.await?
|
||||
.session_info;
|
||||
tracing::debug!(target: LOG_TARGET, ?session_index, "Received session info");
|
||||
@@ -478,34 +492,31 @@ where
|
||||
let rotation_info = get_group_rotation_info(ctx, relay_parent).await?;
|
||||
|
||||
let current_group_index = rotation_info.group_for_core(core_index, cores);
|
||||
let current_validators = groups.get(current_group_index.0 as usize).map(|v| v.as_slice()).unwrap_or_default();
|
||||
let current_validators = groups
|
||||
.get(current_group_index.0 as usize)
|
||||
.map(|v| v.as_slice())
|
||||
.unwrap_or_default();
|
||||
|
||||
let next_group_idx = (current_group_index.0 as usize + 1) % groups.len();
|
||||
let next_validators = groups.get(next_group_idx).map(|v| v.as_slice()).unwrap_or_default();
|
||||
|
||||
let validators = &info.discovery_keys;
|
||||
|
||||
let current_validators = current_validators.iter().map(|i| validators[i.0 as usize].clone()).collect();
|
||||
let next_validators = next_validators.iter().map(|i| validators[i.0 as usize].clone()).collect();
|
||||
let current_validators =
|
||||
current_validators.iter().map(|i| validators[i.0 as usize].clone()).collect();
|
||||
let next_validators =
|
||||
next_validators.iter().map(|i| validators[i.0 as usize].clone()).collect();
|
||||
|
||||
let current_validators = GroupValidators {
|
||||
group: current_group_index,
|
||||
validators: current_validators,
|
||||
};
|
||||
let next_validators = GroupValidators {
|
||||
group: GroupIndex(next_group_idx as u32),
|
||||
validators: next_validators,
|
||||
};
|
||||
let current_validators =
|
||||
GroupValidators { group: current_group_index, validators: current_validators };
|
||||
let next_validators =
|
||||
GroupValidators { group: GroupIndex(next_group_idx as u32), validators: next_validators };
|
||||
|
||||
Ok((current_validators, next_validators))
|
||||
}
|
||||
|
||||
/// Issue a `Declare` collation message to the given `peer`.
|
||||
async fn declare<Context>(
|
||||
ctx: &mut Context,
|
||||
state: &mut State,
|
||||
peer: PeerId,
|
||||
)
|
||||
async fn declare<Context>(ctx: &mut Context, state: &mut State, peer: PeerId)
|
||||
where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
@@ -519,21 +530,17 @@ where
|
||||
state.collator_pair.sign(&declare_signature_payload),
|
||||
);
|
||||
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::SendCollationMessage(
|
||||
vec![peer],
|
||||
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
|
||||
)
|
||||
).await;
|
||||
ctx.send_message(NetworkBridgeMessage::SendCollationMessage(
|
||||
vec![peer],
|
||||
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Issue a connection request to a set of validators and
|
||||
/// revoke the previous connection request.
|
||||
async fn connect_to_validators<Context>(
|
||||
ctx: &mut Context,
|
||||
validator_ids: Vec<AuthorityDiscoveryId>,
|
||||
)
|
||||
async fn connect_to_validators<Context>(ctx: &mut Context, validator_ids: Vec<AuthorityDiscoveryId>)
|
||||
where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
@@ -542,8 +549,11 @@ where
|
||||
// will reissue a new request on new collation
|
||||
let (failed, _) = oneshot::channel();
|
||||
ctx.send_message(NetworkBridgeMessage::ConnectToValidators {
|
||||
validator_ids, peer_set: PeerSet::Collation, failed,
|
||||
}).await;
|
||||
validator_ids,
|
||||
peer_set: PeerSet::Collation,
|
||||
failed,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Advertise collation to the given `peer`.
|
||||
@@ -555,12 +565,12 @@ async fn advertise_collation<Context>(
|
||||
state: &mut State,
|
||||
relay_parent: Hash,
|
||||
peer: PeerId,
|
||||
)
|
||||
where
|
||||
) where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
let should_advertise = state.our_validators_groups
|
||||
let should_advertise = state
|
||||
.our_validators_groups
|
||||
.get(&relay_parent)
|
||||
.map(|g| g.should_advertise_to(&state.peer_ids, &peer))
|
||||
.unwrap_or(false);
|
||||
@@ -583,7 +593,7 @@ where
|
||||
"Not advertising collation as we already advertised it to this validator.",
|
||||
);
|
||||
return
|
||||
}
|
||||
},
|
||||
(Some(collation), true) => {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -595,16 +605,13 @@ where
|
||||
},
|
||||
}
|
||||
|
||||
let wire_message = protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
|
||||
relay_parent,
|
||||
);
|
||||
let wire_message = protocol_v1::CollatorProtocolMessage::AdvertiseCollation(relay_parent);
|
||||
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::SendCollationMessage(
|
||||
vec![peer.clone()],
|
||||
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
|
||||
)
|
||||
).await;
|
||||
ctx.send_message(NetworkBridgeMessage::SendCollationMessage(
|
||||
vec![peer.clone()],
|
||||
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
|
||||
))
|
||||
.await;
|
||||
|
||||
if let Some(validators) = state.our_validators_groups.get_mut(&relay_parent) {
|
||||
validators.advertised_to_peer(&state.peer_ids, &peer);
|
||||
@@ -631,10 +638,12 @@ where
|
||||
match msg {
|
||||
CollateOn(id) => {
|
||||
state.collating_on = Some(id);
|
||||
}
|
||||
},
|
||||
DistributeCollation(receipt, pov, result_sender) => {
|
||||
let _span1 = state.span_per_relay_parent
|
||||
.get(&receipt.descriptor.relay_parent).map(|s| s.child("distributing-collation"));
|
||||
let _span1 = state
|
||||
.span_per_relay_parent
|
||||
.get(&receipt.descriptor.relay_parent)
|
||||
.map(|s| s.child("distributing-collation"));
|
||||
let _span2 = jaeger::Span::new(&pov, "distributing-collation");
|
||||
match state.collating_on {
|
||||
Some(id) if receipt.descriptor.para_id != id => {
|
||||
@@ -646,32 +655,28 @@ where
|
||||
collating_on = %id,
|
||||
"DistributeCollation for unexpected para_id",
|
||||
);
|
||||
}
|
||||
},
|
||||
Some(id) => {
|
||||
distribute_collation(ctx, runtime, state, id, receipt, pov, result_sender).await?;
|
||||
}
|
||||
distribute_collation(ctx, runtime, state, id, receipt, pov, result_sender)
|
||||
.await?;
|
||||
},
|
||||
None => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
para_id = %receipt.descriptor.para_id,
|
||||
"DistributeCollation message while not collating on any",
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
ReportCollator(_) => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
"ReportCollator message is not expected on the collator side of the protocol",
|
||||
);
|
||||
}
|
||||
},
|
||||
NetworkBridgeUpdateV1(event) => {
|
||||
if let Err(e) = handle_network_msg(
|
||||
ctx,
|
||||
runtime,
|
||||
state,
|
||||
event,
|
||||
).await {
|
||||
if let Err(e) = handle_network_msg(ctx, runtime, state, event).await {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
err = ?e,
|
||||
@@ -680,11 +685,16 @@ where
|
||||
}
|
||||
},
|
||||
CollationFetchingRequest(incoming) => {
|
||||
let _span = state.span_per_relay_parent.get(&incoming.payload.relay_parent).map(|s| s.child("request-collation"));
|
||||
let _span = state
|
||||
.span_per_relay_parent
|
||||
.get(&incoming.payload.relay_parent)
|
||||
.map(|s| s.child("request-collation"));
|
||||
match state.collating_on {
|
||||
Some(our_para_id) => {
|
||||
Some(our_para_id) =>
|
||||
if our_para_id == incoming.payload.para_id {
|
||||
let (receipt, pov) = if let Some(collation) = state.collations.get_mut(&incoming.payload.relay_parent) {
|
||||
let (receipt, pov) = if let Some(collation) =
|
||||
state.collations.get_mut(&incoming.payload.relay_parent)
|
||||
{
|
||||
collation.status.advance_to_requested();
|
||||
(collation.receipt.clone(), collation.pov.clone())
|
||||
} else {
|
||||
@@ -694,23 +704,28 @@ where
|
||||
"received a `RequestCollation` for a relay parent we don't have collation stored.",
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
state.metrics.on_collation_sent_requested();
|
||||
|
||||
let _span = _span.as_ref().map(|s| s.child("sending"));
|
||||
|
||||
let waiting = state.waiting_collation_fetches.entry(incoming.payload.relay_parent).or_default();
|
||||
let waiting = state
|
||||
.waiting_collation_fetches
|
||||
.entry(incoming.payload.relay_parent)
|
||||
.or_default();
|
||||
|
||||
if !waiting.waiting_peers.insert(incoming.peer) {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
"Dropping incoming request as peer has a request in flight already."
|
||||
);
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::ReportPeer(incoming.peer, COST_APPARENT_FLOOD)
|
||||
).await;
|
||||
ctx.send_message(NetworkBridgeMessage::ReportPeer(
|
||||
incoming.peer,
|
||||
COST_APPARENT_FLOOD,
|
||||
))
|
||||
.await;
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
@@ -727,17 +742,16 @@ where
|
||||
our_para_id = %our_para_id,
|
||||
"received a `CollationFetchingRequest` for unexpected para_id",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
for_para_id = %incoming.payload.para_id,
|
||||
"received a `RequestCollation` while not collating on any para",
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
@@ -763,24 +777,24 @@ async fn send_collation(
|
||||
};
|
||||
|
||||
if let Err(_) = request.send_outgoing_response(response) {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
"Sending collation response failed",
|
||||
);
|
||||
tracing::warn!(target: LOG_TARGET, "Sending collation response failed",);
|
||||
}
|
||||
|
||||
state.active_collation_fetches.push(async move {
|
||||
let r = rx.timeout(MAX_UNSHARED_UPLOAD_TIME).await;
|
||||
if r.is_none() {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
?relay_parent,
|
||||
?peer_id,
|
||||
"Sending collation to validator timed out, carrying on with next validator."
|
||||
);
|
||||
state.active_collation_fetches.push(
|
||||
async move {
|
||||
let r = rx.timeout(MAX_UNSHARED_UPLOAD_TIME).await;
|
||||
if r.is_none() {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
?relay_parent,
|
||||
?peer_id,
|
||||
"Sending collation to validator timed out, carrying on with next validator."
|
||||
);
|
||||
}
|
||||
(relay_parent, peer_id)
|
||||
}
|
||||
(relay_parent, peer_id)
|
||||
}.boxed());
|
||||
.boxed(),
|
||||
);
|
||||
|
||||
state.metrics.on_collation_sent();
|
||||
}
|
||||
@@ -808,10 +822,9 @@ where
|
||||
);
|
||||
|
||||
// If we are declared to, this is another collator, and we should disconnect.
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation)
|
||||
).await;
|
||||
}
|
||||
ctx.send_message(NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation))
|
||||
.await;
|
||||
},
|
||||
AdvertiseCollation(_) => {
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
@@ -819,15 +832,16 @@ where
|
||||
"AdvertiseCollation message is not expected on the collator side of the protocol",
|
||||
);
|
||||
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::ReportPeer(origin.clone(), COST_UNEXPECTED_MESSAGE)
|
||||
).await;
|
||||
ctx.send_message(NetworkBridgeMessage::ReportPeer(
|
||||
origin.clone(),
|
||||
COST_UNEXPECTED_MESSAGE,
|
||||
))
|
||||
.await;
|
||||
|
||||
// If we are advertised to, this is another collator, and we should disconnect.
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation)
|
||||
).await;
|
||||
}
|
||||
ctx.send_message(NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation))
|
||||
.await;
|
||||
},
|
||||
CollationSeconded(relay_parent, statement) => {
|
||||
if !matches!(statement.unchecked_payload(), Statement::Seconded(_)) {
|
||||
tracing::warn!(
|
||||
@@ -837,12 +851,13 @@ where
|
||||
"Collation seconded message received with none-seconded statement.",
|
||||
);
|
||||
} else {
|
||||
let statement = runtime.check_signature(ctx.sender(), relay_parent, statement)
|
||||
let statement = runtime
|
||||
.check_signature(ctx.sender(), relay_parent, statement)
|
||||
.await?
|
||||
.map_err(NonFatal::InvalidStatementSignature)?;
|
||||
|
||||
let removed = state.collation_result_senders
|
||||
.remove(&statement.payload().candidate_hash());
|
||||
let removed =
|
||||
state.collation_result_senders.remove(&statement.payload().candidate_hash());
|
||||
|
||||
if let Some(sender) = removed {
|
||||
tracing::trace!(
|
||||
@@ -854,7 +869,7 @@ where
|
||||
let _ = sender.send(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -866,8 +881,7 @@ async fn handle_peer_view_change<Context>(
|
||||
state: &mut State,
|
||||
peer_id: PeerId,
|
||||
view: View,
|
||||
)
|
||||
where
|
||||
) where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
@@ -899,12 +913,7 @@ where
|
||||
PeerConnected(peer_id, observed_role, maybe_authority) => {
|
||||
// If it is possible that a disconnected validator would attempt a reconnect
|
||||
// it should be handled here.
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
?peer_id,
|
||||
?observed_role,
|
||||
"Peer connected",
|
||||
);
|
||||
tracing::trace!(target: LOG_TARGET, ?peer_id, ?observed_role, "Peer connected",);
|
||||
if let Some(authority) = maybe_authority {
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
@@ -916,49 +925,33 @@ where
|
||||
|
||||
declare(ctx, state, peer_id).await;
|
||||
}
|
||||
}
|
||||
},
|
||||
PeerViewChange(peer_id, view) => {
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
?peer_id,
|
||||
?view,
|
||||
"Peer view change",
|
||||
);
|
||||
tracing::trace!(target: LOG_TARGET, ?peer_id, ?view, "Peer view change",);
|
||||
handle_peer_view_change(ctx, state, peer_id, view).await;
|
||||
}
|
||||
},
|
||||
PeerDisconnected(peer_id) => {
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
?peer_id,
|
||||
"Peer disconnected",
|
||||
);
|
||||
tracing::trace!(target: LOG_TARGET, ?peer_id, "Peer disconnected",);
|
||||
state.peer_views.remove(&peer_id);
|
||||
state.peer_ids.remove(&peer_id);
|
||||
}
|
||||
},
|
||||
OurViewChange(view) => {
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
?view,
|
||||
"Own view change",
|
||||
);
|
||||
tracing::trace!(target: LOG_TARGET, ?view, "Own view change",);
|
||||
handle_our_view_change(state, view).await?;
|
||||
}
|
||||
},
|
||||
PeerMessage(remote, msg) => {
|
||||
handle_incoming_peer_message(ctx, runtime, state, remote, msg).await?;
|
||||
}
|
||||
},
|
||||
NewGossipTopology(..) => {
|
||||
// impossibru!
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handles our view changes.
|
||||
async fn handle_our_view_change(
|
||||
state: &mut State,
|
||||
view: OurView,
|
||||
) -> Result<()> {
|
||||
async fn handle_our_view_change(state: &mut State, view: OurView) -> Result<()> {
|
||||
for removed in state.view.difference(&view) {
|
||||
tracing::debug!(target: LOG_TARGET, relay_parent = ?removed, "Removing relay parent because our view changed.");
|
||||
|
||||
@@ -983,7 +976,7 @@ async fn handle_our_view_change(
|
||||
candidate_hash = ?collation.receipt.hash(),
|
||||
pov_hash = ?collation.pov.hash(),
|
||||
"Collation was requested.",
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
state.our_validators_groups.remove(removed);
|
||||
@@ -1005,7 +998,7 @@ pub(crate) async fn run<Context>(
|
||||
) -> Result<()>
|
||||
where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
use OverseerSignal::*;
|
||||
|
||||
|
||||
@@ -26,21 +26,17 @@ use sp_core::{crypto::Pair, Decode};
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
use sp_runtime::traits::AppVerify;
|
||||
|
||||
use polkadot_node_network_protocol::{
|
||||
our_view,
|
||||
view,
|
||||
request_response::request::IncomingRequest,
|
||||
};
|
||||
use polkadot_node_network_protocol::{our_view, request_response::request::IncomingRequest, view};
|
||||
use polkadot_node_primitives::BlockData;
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
use polkadot_primitives::v1::{
|
||||
AuthorityDiscoveryId, CandidateDescriptor, CollatorPair, GroupRotationInfo, ScheduledCore, SessionIndex,
|
||||
SessionInfo, ValidatorId, ValidatorIndex,
|
||||
AuthorityDiscoveryId, CandidateDescriptor, CollatorPair, GroupRotationInfo, ScheduledCore,
|
||||
SessionIndex, SessionInfo, ValidatorId, ValidatorIndex,
|
||||
};
|
||||
use polkadot_node_primitives::BlockData;
|
||||
use polkadot_subsystem::{
|
||||
jaeger,
|
||||
messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest},
|
||||
ActiveLeavesUpdate, ActivatedLeaf, LeafStatus,
|
||||
ActivatedLeaf, ActiveLeavesUpdate, LeafStatus,
|
||||
};
|
||||
use polkadot_subsystem_testhelpers as test_helpers;
|
||||
|
||||
@@ -103,22 +99,17 @@ impl Default for TestState {
|
||||
let validator_public = validator_pubkeys(&validators);
|
||||
let discovery_keys = validator_authority_id(&validators);
|
||||
|
||||
let validator_peer_id = std::iter::repeat_with(|| PeerId::random())
|
||||
.take(discovery_keys.len())
|
||||
.collect();
|
||||
let validator_peer_id =
|
||||
std::iter::repeat_with(|| PeerId::random()).take(discovery_keys.len()).collect();
|
||||
|
||||
let validator_groups = vec![vec![2, 0, 4], vec![3, 2, 4]]
|
||||
.into_iter().map(|g| g.into_iter().map(ValidatorIndex).collect()).collect();
|
||||
let group_rotation_info = GroupRotationInfo {
|
||||
session_start_block: 0,
|
||||
group_rotation_frequency: 100,
|
||||
now: 1,
|
||||
};
|
||||
.into_iter()
|
||||
.map(|g| g.into_iter().map(ValidatorIndex).collect())
|
||||
.collect();
|
||||
let group_rotation_info =
|
||||
GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 100, now: 1 };
|
||||
|
||||
let availability_core = CoreState::Scheduled(ScheduledCore {
|
||||
para_id,
|
||||
collator: None,
|
||||
});
|
||||
let availability_core = CoreState::Scheduled(ScheduledCore { para_id, collator: None });
|
||||
|
||||
let relay_parent = Hash::random();
|
||||
|
||||
@@ -155,7 +146,10 @@ impl TestState {
|
||||
}
|
||||
|
||||
fn current_group_validator_peer_ids(&self) -> Vec<PeerId> {
|
||||
self.current_group_validator_indices().iter().map(|i| self.validator_peer_id[i.0 as usize].clone()).collect()
|
||||
self.current_group_validator_indices()
|
||||
.iter()
|
||||
.map(|i| self.validator_peer_id[i.0 as usize].clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn current_group_validator_authority_ids(&self) -> Vec<AuthorityDiscoveryId> {
|
||||
@@ -169,7 +163,11 @@ impl TestState {
|
||||
///
|
||||
/// If `merge_views == true` it means the subsystem will be informed that we are working on the old `relay_parent`
|
||||
/// and the new one.
|
||||
async fn advance_to_new_round(&mut self, virtual_overseer: &mut VirtualOverseer, merge_views: bool) {
|
||||
async fn advance_to_new_round(
|
||||
&mut self,
|
||||
virtual_overseer: &mut VirtualOverseer,
|
||||
merge_views: bool,
|
||||
) {
|
||||
let old_relay_parent = self.relay_parent;
|
||||
|
||||
while self.relay_parent == old_relay_parent {
|
||||
@@ -184,8 +182,11 @@ impl TestState {
|
||||
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(our_view)),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,14 +203,8 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(
|
||||
) {
|
||||
let _ = env_logger::builder()
|
||||
.is_test(true)
|
||||
.filter(
|
||||
Some("polkadot_collator_protocol"),
|
||||
log::LevelFilter::Trace,
|
||||
)
|
||||
.filter(
|
||||
Some(LOG_TARGET),
|
||||
log::LevelFilter::Trace,
|
||||
)
|
||||
.filter(Some("polkadot_collator_protocol"), log::LevelFilter::Trace)
|
||||
.filter(Some(LOG_TARGET), log::LevelFilter::Trace)
|
||||
.try_init();
|
||||
|
||||
let pool = sp_core::testing::TaskExecutor::new();
|
||||
@@ -223,18 +218,20 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(
|
||||
futures::pin_mut!(test_fut);
|
||||
futures::pin_mut!(subsystem);
|
||||
|
||||
executor::block_on(future::join(async move {
|
||||
let mut overseer = test_fut.await;
|
||||
overseer_signal(&mut overseer, OverseerSignal::Conclude).await;
|
||||
}, subsystem)).1.unwrap();
|
||||
executor::block_on(future::join(
|
||||
async move {
|
||||
let mut overseer = test_fut.await;
|
||||
overseer_signal(&mut overseer, OverseerSignal::Conclude).await;
|
||||
},
|
||||
subsystem,
|
||||
))
|
||||
.1
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const TIMEOUT: Duration = Duration::from_millis(100);
|
||||
|
||||
async fn overseer_send(
|
||||
overseer: &mut VirtualOverseer,
|
||||
msg: CollatorProtocolMessage,
|
||||
) {
|
||||
async fn overseer_send(overseer: &mut VirtualOverseer, msg: CollatorProtocolMessage) {
|
||||
tracing::trace!(?msg, "sending message");
|
||||
overseer
|
||||
.send(FromOverseer::Communication { msg })
|
||||
@@ -243,9 +240,7 @@ async fn overseer_send(
|
||||
.expect(&format!("{:?} is more than enough for sending messages.", TIMEOUT));
|
||||
}
|
||||
|
||||
async fn overseer_recv(
|
||||
overseer: &mut VirtualOverseer,
|
||||
) -> AllMessages {
|
||||
async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages {
|
||||
let msg = overseer_recv_with_timeout(overseer, TIMEOUT)
|
||||
.await
|
||||
.expect(&format!("{:?} is more than enough to receive messages", TIMEOUT));
|
||||
@@ -260,16 +255,10 @@ async fn overseer_recv_with_timeout(
|
||||
timeout: Duration,
|
||||
) -> Option<AllMessages> {
|
||||
tracing::trace!("waiting for message...");
|
||||
overseer
|
||||
.recv()
|
||||
.timeout(timeout)
|
||||
.await
|
||||
overseer.recv().timeout(timeout).await
|
||||
}
|
||||
|
||||
async fn overseer_signal(
|
||||
overseer: &mut VirtualOverseer,
|
||||
signal: OverseerSignal,
|
||||
) {
|
||||
async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) {
|
||||
overseer
|
||||
.send(FromOverseer::Signal(signal))
|
||||
.timeout(TIMEOUT)
|
||||
@@ -279,10 +268,7 @@ async fn overseer_signal(
|
||||
|
||||
// Setup the system by sending the `CollateOn`, `ActiveLeaves` and `OurViewChange` messages.
|
||||
async fn setup_system(virtual_overseer: &mut VirtualOverseer, test_state: &TestState) {
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::CollateOn(test_state.para_id),
|
||||
).await;
|
||||
overseer_send(virtual_overseer, CollatorProtocolMessage::CollateOn(test_state.para_id)).await;
|
||||
|
||||
overseer_signal(
|
||||
virtual_overseer,
|
||||
@@ -292,14 +278,16 @@ async fn setup_system(virtual_overseer: &mut VirtualOverseer, test_state: &TestS
|
||||
status: LeafStatus::Fresh,
|
||||
span: Arc::new(jaeger::Span::Disabled),
|
||||
})),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent]),
|
||||
),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Result of [`distribute_collation`]
|
||||
@@ -316,9 +304,7 @@ async fn distribute_collation(
|
||||
should_connect: bool,
|
||||
) -> DistributeCollation {
|
||||
// Now we want to distribute a PoVBlock
|
||||
let pov_block = PoV {
|
||||
block_data: BlockData(vec![42, 43, 44]),
|
||||
};
|
||||
let pov_block = PoV { block_data: BlockData(vec![42, 43, 44]) };
|
||||
|
||||
let pov_hash = pov_block.hash();
|
||||
|
||||
@@ -327,12 +313,14 @@ async fn distribute_collation(
|
||||
relay_parent: test_state.relay_parent,
|
||||
pov_hash,
|
||||
..Default::default()
|
||||
}.build();
|
||||
}
|
||||
.build();
|
||||
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::DistributeCollation(candidate.clone(), pov_block.clone(), None),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
// obtain the availability cores.
|
||||
assert_matches!(
|
||||
@@ -355,7 +343,7 @@ async fn distribute_collation(
|
||||
)) => {
|
||||
assert_eq!(relay_parent, test_state.relay_parent);
|
||||
tx.send(Ok(test_state.current_session_index())).unwrap();
|
||||
}
|
||||
},
|
||||
|
||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||
relay_parent,
|
||||
@@ -365,22 +353,22 @@ async fn distribute_collation(
|
||||
assert_eq!(index, test_state.current_session_index());
|
||||
|
||||
tx.send(Ok(Some(test_state.session_info.clone()))).unwrap();
|
||||
}
|
||||
},
|
||||
|
||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||
relay_parent,
|
||||
RuntimeApiRequest::ValidatorGroups(tx)
|
||||
RuntimeApiRequest::ValidatorGroups(tx),
|
||||
)) => {
|
||||
assert_eq!(relay_parent, test_state.relay_parent);
|
||||
tx.send(Ok((
|
||||
test_state.session_info.validator_groups.clone(),
|
||||
test_state.group_rotation_info.clone(),
|
||||
))).unwrap();
|
||||
)))
|
||||
.unwrap();
|
||||
// This call is mandatory - we are done:
|
||||
break;
|
||||
}
|
||||
other =>
|
||||
panic!("Unexpected message received: {:?}", other),
|
||||
break
|
||||
},
|
||||
other => panic!("Unexpected message received: {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,35 +383,33 @@ async fn distribute_collation(
|
||||
);
|
||||
}
|
||||
|
||||
DistributeCollation {
|
||||
candidate,
|
||||
pov_block,
|
||||
}
|
||||
DistributeCollation { candidate, pov_block }
|
||||
}
|
||||
|
||||
/// Connect a peer
|
||||
async fn connect_peer(
|
||||
virtual_overseer: &mut VirtualOverseer,
|
||||
peer: PeerId,
|
||||
authority_id: Option<AuthorityDiscoveryId>
|
||||
authority_id: Option<AuthorityDiscoveryId>,
|
||||
) {
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerConnected(
|
||||
peer.clone(),
|
||||
polkadot_node_network_protocol::ObservedRole::Authority,
|
||||
authority_id,
|
||||
),
|
||||
),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected(
|
||||
peer.clone(),
|
||||
polkadot_node_network_protocol::ObservedRole::Authority,
|
||||
authority_id,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerViewChange(peer, view![]),
|
||||
),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange(
|
||||
peer,
|
||||
view![],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Disconnect a peer
|
||||
@@ -431,7 +417,8 @@ async fn disconnect_peer(virtual_overseer: &mut VirtualOverseer, peer: PeerId) {
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(peer)),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Check that the next received message is a `Declare` message.
|
||||
@@ -496,13 +483,19 @@ async fn expect_advertise_collation_msg(
|
||||
}
|
||||
|
||||
/// Send a message that the given peer's view changed.
|
||||
async fn send_peer_view_change(virtual_overseer: &mut VirtualOverseer, peer: &PeerId, hashes: Vec<Hash>) {
|
||||
async fn send_peer_view_change(
|
||||
virtual_overseer: &mut VirtualOverseer,
|
||||
peer: &PeerId,
|
||||
hashes: Vec<Hash>,
|
||||
) {
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerViewChange(peer.clone(), View::new(hashes, 0)),
|
||||
),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange(
|
||||
peer.clone(),
|
||||
View::new(hashes, 0),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -519,7 +512,8 @@ fn advertise_and_send_collation() {
|
||||
let DistributeCollation { candidate, pov_block } =
|
||||
distribute_collation(&mut virtual_overseer, &test_state, true).await;
|
||||
|
||||
for (val, peer) in test_state.current_group_validator_authority_ids()
|
||||
for (val, peer) in test_state
|
||||
.current_group_validator_authority_ids()
|
||||
.into_iter()
|
||||
.zip(test_state.current_group_validator_peer_ids())
|
||||
{
|
||||
@@ -546,33 +540,31 @@ fn advertise_and_send_collation() {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::CollationFetchingRequest(
|
||||
IncomingRequest::new(
|
||||
CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new(
|
||||
peer,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
// Second request by same validator should get dropped and peer reported:
|
||||
{
|
||||
let (tx, rx) = oneshot::channel();
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new(
|
||||
peer,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
)),
|
||||
)
|
||||
).await;
|
||||
// Second request by same validator should get dropped and peer reported:
|
||||
{
|
||||
let (tx, rx) = oneshot::channel();
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::CollationFetchingRequest(
|
||||
IncomingRequest::new(
|
||||
peer,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
)
|
||||
).await;
|
||||
.await;
|
||||
assert_matches!(
|
||||
overseer_recv(&mut virtual_overseer).await,
|
||||
AllMessages::NetworkBridge(NetworkBridgeMessage::ReportPeer(bad_peer, _)) => {
|
||||
@@ -609,17 +601,16 @@ fn advertise_and_send_collation() {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::CollationFetchingRequest(
|
||||
IncomingRequest::new(
|
||||
peer,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: old_relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new(
|
||||
peer,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: old_relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
// Re-requesting collation should fail:
|
||||
rx.await.unwrap_err();
|
||||
|
||||
@@ -630,13 +621,12 @@ fn advertise_and_send_collation() {
|
||||
// Send info about peer's view.
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerViewChange(
|
||||
peer.clone(),
|
||||
view![test_state.relay_parent],
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerViewChange(
|
||||
peer.clone(),
|
||||
view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &peer, test_state.relay_parent).await;
|
||||
virtual_overseer
|
||||
@@ -646,29 +636,26 @@ fn advertise_and_send_collation() {
|
||||
#[test]
|
||||
fn send_only_one_collation_per_relay_parent_at_a_time() {
|
||||
test_validator_send_sequence(|mut second_response_receiver, feedback_first_tx| async move {
|
||||
Delay::new(Duration::from_millis(100)).await;
|
||||
assert!(
|
||||
second_response_receiver.try_recv().unwrap().is_none(),
|
||||
"We should not have send the collation yet to the second validator",
|
||||
);
|
||||
Delay::new(Duration::from_millis(100)).await;
|
||||
assert!(
|
||||
second_response_receiver.try_recv().unwrap().is_none(),
|
||||
"We should not have send the collation yet to the second validator",
|
||||
);
|
||||
|
||||
// Signal that the collation fetch is finished
|
||||
feedback_first_tx.send(()).expect("Sending collation fetch finished");
|
||||
second_response_receiver
|
||||
}
|
||||
);
|
||||
// Signal that the collation fetch is finished
|
||||
feedback_first_tx.send(()).expect("Sending collation fetch finished");
|
||||
second_response_receiver
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_next_collation_after_max_unshared_upload_time() {
|
||||
test_validator_send_sequence(|second_response_receiver, _| async move {
|
||||
Delay::new(MAX_UNSHARED_UPLOAD_TIME + Duration::from_millis(50)).await;
|
||||
second_response_receiver
|
||||
}
|
||||
);
|
||||
Delay::new(MAX_UNSHARED_UPLOAD_TIME + Duration::from_millis(50)).await;
|
||||
second_response_receiver
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn collators_declare_to_connected_peers() {
|
||||
let test_state = TestState::default();
|
||||
@@ -721,7 +708,8 @@ fn collations_are_only_advertised_to_validators_with_correct_view() {
|
||||
|
||||
distribute_collation(&mut virtual_overseer, &test_state, true).await;
|
||||
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent).await;
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent)
|
||||
.await;
|
||||
|
||||
// The other validator announces that it changed its view.
|
||||
send_peer_view_change(&mut virtual_overseer, &peer, vec![test_state.relay_parent]).await;
|
||||
@@ -772,7 +760,8 @@ fn collate_on_two_different_relay_chain_blocks() {
|
||||
|
||||
send_peer_view_change(&mut virtual_overseer, &peer2, vec![test_state.relay_parent]).await;
|
||||
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent).await;
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &peer2, test_state.relay_parent)
|
||||
.await;
|
||||
virtual_overseer
|
||||
})
|
||||
}
|
||||
@@ -833,17 +822,16 @@ fn collators_reject_declare_messages() {
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer.clone(),
|
||||
protocol_v1::CollatorProtocolMessage::Declare(
|
||||
collator_pair2.public(),
|
||||
ParaId::from(5),
|
||||
collator_pair2.sign(b"garbage"),
|
||||
),
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage(
|
||||
peer.clone(),
|
||||
protocol_v1::CollatorProtocolMessage::Declare(
|
||||
collator_pair2.public(),
|
||||
ParaId::from(5),
|
||||
collator_pair2.sign(b"garbage"),
|
||||
),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_matches!(
|
||||
overseer_recv(&mut virtual_overseer).await,
|
||||
@@ -868,7 +856,7 @@ fn collators_reject_declare_messages() {
|
||||
fn test_validator_send_sequence<T, F>(handle_first_response: T)
|
||||
where
|
||||
T: FnOnce(oneshot::Receiver<sc_network::config::OutgoingResponse>, oneshot::Sender<()>) -> F,
|
||||
F: Future<Output=oneshot::Receiver<sc_network::config::OutgoingResponse>>
|
||||
F: Future<Output = oneshot::Receiver<sc_network::config::OutgoingResponse>>,
|
||||
{
|
||||
let test_state = TestState::default();
|
||||
let local_peer_id = test_state.local_peer_id.clone();
|
||||
@@ -882,7 +870,8 @@ where
|
||||
let DistributeCollation { candidate, pov_block } =
|
||||
distribute_collation(&mut virtual_overseer, &test_state, true).await;
|
||||
|
||||
for (val, peer) in test_state.current_group_validator_authority_ids()
|
||||
for (val, peer) in test_state
|
||||
.current_group_validator_authority_ids()
|
||||
.into_iter()
|
||||
.zip(test_state.current_group_validator_peer_ids())
|
||||
{
|
||||
@@ -900,29 +889,40 @@ where
|
||||
let validator_1 = test_state.current_group_validator_peer_ids()[1].clone();
|
||||
|
||||
// Send info about peer's view.
|
||||
send_peer_view_change(&mut virtual_overseer, &validator_0, vec![test_state.relay_parent]).await;
|
||||
send_peer_view_change(&mut virtual_overseer, &validator_1, vec![test_state.relay_parent]).await;
|
||||
send_peer_view_change(&mut virtual_overseer, &validator_0, vec![test_state.relay_parent])
|
||||
.await;
|
||||
send_peer_view_change(&mut virtual_overseer, &validator_1, vec![test_state.relay_parent])
|
||||
.await;
|
||||
|
||||
// The peer is interested in a leaf that we have a collation for;
|
||||
// advertise it.
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &validator_0, test_state.relay_parent).await;
|
||||
expect_advertise_collation_msg(&mut virtual_overseer, &validator_1, test_state.relay_parent).await;
|
||||
expect_advertise_collation_msg(
|
||||
&mut virtual_overseer,
|
||||
&validator_0,
|
||||
test_state.relay_parent,
|
||||
)
|
||||
.await;
|
||||
expect_advertise_collation_msg(
|
||||
&mut virtual_overseer,
|
||||
&validator_1,
|
||||
test_state.relay_parent,
|
||||
)
|
||||
.await;
|
||||
|
||||
// Request a collation.
|
||||
let (tx, rx) = oneshot::channel();
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::CollationFetchingRequest(
|
||||
IncomingRequest::new(
|
||||
validator_0,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new(
|
||||
validator_0,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
// Keep the feedback channel alive because we need to use it to inform about the finished transfer.
|
||||
let feedback_tx = assert_matches!(
|
||||
@@ -945,17 +945,16 @@ where
|
||||
let (tx, rx) = oneshot::channel();
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::CollationFetchingRequest(
|
||||
IncomingRequest::new(
|
||||
validator_1,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::CollationFetchingRequest(IncomingRequest::new(
|
||||
validator_1,
|
||||
CollationFetchingRequest {
|
||||
relay_parent: test_state.relay_parent,
|
||||
para_id: test_state.para_id,
|
||||
},
|
||||
tx,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
let rx = handle_first_response(rx, feedback_tx).await;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use polkadot_node_primitives::UncheckedSignedFullStatement;
|
||||
use polkadot_subsystem::errors::SubsystemError;
|
||||
use thiserror::Error;
|
||||
|
||||
use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal};
|
||||
use polkadot_node_subsystem_util::{runtime, unwrap_non_fatal, Fault};
|
||||
|
||||
use crate::LOG_TARGET;
|
||||
|
||||
@@ -82,9 +82,7 @@ pub enum NonFatal {
|
||||
///
|
||||
/// We basically always want to try and continue on error. This utility function is meant to
|
||||
/// consume top-level errors by simply logging them.
|
||||
pub fn log_error(result: Result<()>, ctx: &'static str)
|
||||
-> FatalResult<()>
|
||||
{
|
||||
pub fn log_error(result: Result<()>, ctx: &'static str) -> FatalResult<()> {
|
||||
if let Some(error) = unwrap_non_fatal(result.map_err(|e| e.0))? {
|
||||
tracing::warn!(target: LOG_TARGET, error = ?error, ctx)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
//! This subsystem implements both sides of the collator protocol.
|
||||
|
||||
#![deny(missing_docs, unused_crate_dependencies)]
|
||||
#![recursion_limit="256"]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -30,14 +30,9 @@ use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange as Rep};
|
||||
use polkadot_primitives::v1::CollatorPair;
|
||||
|
||||
use polkadot_subsystem::{
|
||||
SpawnedSubsystem,
|
||||
SubsystemContext,
|
||||
SubsystemSender,
|
||||
overseer,
|
||||
messages::{
|
||||
CollatorProtocolMessage, NetworkBridgeMessage,
|
||||
},
|
||||
errors::SubsystemError,
|
||||
messages::{CollatorProtocolMessage, NetworkBridgeMessage},
|
||||
overseer, SpawnedSubsystem, SubsystemContext, SubsystemSender,
|
||||
};
|
||||
|
||||
mod error;
|
||||
@@ -92,29 +87,19 @@ impl CollatorProtocolSubsystem {
|
||||
/// If `id` is `None` this is a validator side of the protocol.
|
||||
/// Caller must provide a registry for prometheus metrics.
|
||||
pub fn new(protocol_side: ProtocolSide) -> Self {
|
||||
Self {
|
||||
protocol_side,
|
||||
}
|
||||
Self { protocol_side }
|
||||
}
|
||||
|
||||
async fn run<Context>(self, ctx: Context) -> Result<()>
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
match self.protocol_side {
|
||||
ProtocolSide::Validator { keystore, eviction_policy, metrics } => validator_side::run(
|
||||
ctx,
|
||||
keystore,
|
||||
eviction_policy,
|
||||
metrics,
|
||||
).await,
|
||||
ProtocolSide::Collator(local_peer_id, collator_pair, metrics) => collator_side::run(
|
||||
ctx,
|
||||
local_peer_id,
|
||||
collator_pair,
|
||||
metrics,
|
||||
).await,
|
||||
ProtocolSide::Validator { keystore, eviction_policy, metrics } =>
|
||||
validator_side::run(ctx, keystore, eviction_policy, metrics).await,
|
||||
ProtocolSide::Collator(local_peer_id, collator_pair, metrics) =>
|
||||
collator_side::run(ctx, local_peer_id, collator_pair, metrics).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,10 +116,7 @@ where
|
||||
.map_err(|e| SubsystemError::with_origin("collator-protocol", e))
|
||||
.boxed();
|
||||
|
||||
SpawnedSubsystem {
|
||||
name: "collator-protocol-subsystem",
|
||||
future,
|
||||
}
|
||||
SpawnedSubsystem { name: "collator-protocol-subsystem", future }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +132,5 @@ where
|
||||
"reputation change for peer",
|
||||
);
|
||||
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::ReportPeer(peer, rep),
|
||||
).await;
|
||||
ctx.send_message(NetworkBridgeMessage::ReportPeer(peer, rep)).await;
|
||||
}
|
||||
|
||||
@@ -14,39 +14,44 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::{collections::{HashMap, HashSet}, sync::Arc, task::Poll};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::time::{Duration, Instant};
|
||||
use always_assert::never;
|
||||
use futures::{
|
||||
channel::oneshot, future::{BoxFuture, Fuse, FusedFuture}, FutureExt, StreamExt,
|
||||
stream::FuturesUnordered, select,
|
||||
channel::oneshot,
|
||||
future::{BoxFuture, Fuse, FusedFuture},
|
||||
select,
|
||||
stream::FuturesUnordered,
|
||||
FutureExt, StreamExt,
|
||||
};
|
||||
use futures_timer::Delay;
|
||||
use std::{
|
||||
collections::{hash_map::Entry, HashMap, HashSet},
|
||||
sync::Arc,
|
||||
task::Poll,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use sp_keystore::SyncCryptoStorePtr;
|
||||
|
||||
use polkadot_node_network_protocol::{
|
||||
request_response as req_res, v1 as protocol_v1,
|
||||
peer_set::PeerSet,
|
||||
request_response as req_res,
|
||||
request_response::{
|
||||
request::{Recipient, RequestError},
|
||||
v1::{CollationFetchingRequest, CollationFetchingResponse},
|
||||
OutgoingRequest, Requests,
|
||||
},
|
||||
OurView, PeerId, UnifiedReputationChange as Rep, View,
|
||||
v1 as protocol_v1, OurView, PeerId, UnifiedReputationChange as Rep, View,
|
||||
};
|
||||
use polkadot_node_primitives::{SignedFullStatement, PoV};
|
||||
use polkadot_node_primitives::{PoV, SignedFullStatement};
|
||||
use polkadot_node_subsystem_util::metrics::{self, prometheus};
|
||||
use polkadot_primitives::v1::{CandidateReceipt, CollatorId, Hash, Id as ParaId};
|
||||
use polkadot_subsystem::{
|
||||
overseer,
|
||||
jaeger,
|
||||
messages::{
|
||||
CollatorProtocolMessage, IfDisconnected,
|
||||
NetworkBridgeEvent, NetworkBridgeMessage, CandidateBackingMessage,
|
||||
CandidateBackingMessage, CollatorProtocolMessage, IfDisconnected, NetworkBridgeEvent,
|
||||
NetworkBridgeMessage,
|
||||
},
|
||||
FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, SubsystemSender,
|
||||
overseer, FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, SubsystemSender,
|
||||
};
|
||||
|
||||
use super::{modify_reputation, Result, LOG_TARGET};
|
||||
@@ -64,7 +69,8 @@ const COST_INVALID_SIGNATURE: Rep = Rep::Malicious("Invalid network message sign
|
||||
const COST_REPORT_BAD: Rep = Rep::Malicious("A collator was reported by another subsystem");
|
||||
const COST_WRONG_PARA: Rep = Rep::Malicious("A collator provided a collation for the wrong para");
|
||||
const COST_UNNEEDED_COLLATOR: Rep = Rep::CostMinor("An unneeded collator connected");
|
||||
const BENEFIT_NOTIFY_GOOD: Rep = Rep::BenefitMinor("A collator was noted good by another subsystem");
|
||||
const BENEFIT_NOTIFY_GOOD: Rep =
|
||||
Rep::BenefitMinor("A collator was noted good by another subsystem");
|
||||
|
||||
/// Time after starting a collation download from a collator we will start another one from the
|
||||
/// next collator even if the upload was not finished yet.
|
||||
@@ -105,13 +111,19 @@ impl Metrics {
|
||||
}
|
||||
|
||||
/// Provide a timer for `handle_collation_request_result` which observes on drop.
|
||||
fn time_handle_collation_request_result(&self) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
|
||||
self.0.as_ref().map(|metrics| metrics.handle_collation_request_result.start_timer())
|
||||
fn time_handle_collation_request_result(
|
||||
&self,
|
||||
) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
|
||||
self.0
|
||||
.as_ref()
|
||||
.map(|metrics| metrics.handle_collation_request_result.start_timer())
|
||||
}
|
||||
|
||||
/// Note the current number of collator peers.
|
||||
fn note_collator_peer_count(&self, collator_peers: usize) {
|
||||
self.0.as_ref().map(|metrics| metrics.collator_peer_count.set(collator_peers as u64));
|
||||
self.0
|
||||
.as_ref()
|
||||
.map(|metrics| metrics.collator_peer_count.set(collator_peers as u64));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,9 +136,9 @@ struct MetricsInner {
|
||||
}
|
||||
|
||||
impl metrics::Metrics for Metrics {
|
||||
fn try_register(registry: &prometheus::Registry)
|
||||
-> std::result::Result<Self, prometheus::PrometheusError>
|
||||
{
|
||||
fn try_register(
|
||||
registry: &prometheus::Registry,
|
||||
) -> std::result::Result<Self, prometheus::PrometheusError> {
|
||||
let metrics = MetricsInner {
|
||||
collation_requests: prometheus::register(
|
||||
prometheus::CounterVec::new(
|
||||
@@ -210,10 +222,7 @@ struct PeerData {
|
||||
|
||||
impl PeerData {
|
||||
fn new(view: View) -> Self {
|
||||
PeerData {
|
||||
view,
|
||||
state: PeerState::Connected(Instant::now()),
|
||||
}
|
||||
PeerData { view, state: PeerState::Connected(Instant::now()) }
|
||||
}
|
||||
|
||||
/// Update the view, clearing all advertisements that are no longer in the
|
||||
@@ -241,20 +250,17 @@ impl PeerData {
|
||||
&mut self,
|
||||
on_relay_parent: Hash,
|
||||
our_view: &View,
|
||||
)
|
||||
-> std::result::Result<(CollatorId, ParaId), AdvertisementError>
|
||||
{
|
||||
) -> std::result::Result<(CollatorId, ParaId), AdvertisementError> {
|
||||
match self.state {
|
||||
PeerState::Connected(_) => Err(AdvertisementError::UndeclaredCollator),
|
||||
_ if !our_view.contains(&on_relay_parent) => Err(AdvertisementError::OutOfOurView),
|
||||
PeerState::Collating(ref mut state) => {
|
||||
PeerState::Collating(ref mut state) =>
|
||||
if state.advertisements.insert(on_relay_parent) {
|
||||
state.last_active = Instant::now();
|
||||
Ok((state.collator_id.clone(), state.para_id.clone()))
|
||||
} else {
|
||||
Err(AdvertisementError::Duplicate)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +311,8 @@ impl PeerData {
|
||||
fn is_inactive(&self, policy: &crate::CollatorEvictionPolicy) -> bool {
|
||||
match self.state {
|
||||
PeerState::Connected(connected_at) => connected_at.elapsed() >= policy.undeclared,
|
||||
PeerState::Collating(ref state) => state.last_active.elapsed() >= policy.inactive_collator,
|
||||
PeerState::Collating(ref state) =>
|
||||
state.last_active.elapsed() >= policy.inactive_collator,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,7 +332,7 @@ struct GroupAssignments {
|
||||
struct ActiveParas {
|
||||
relay_parent_assignments: HashMap<Hash, GroupAssignments>,
|
||||
current_assignments: HashMap<ParaId, usize>,
|
||||
next_assignments: HashMap<ParaId, usize>
|
||||
next_assignments: HashMap<ParaId, usize>,
|
||||
}
|
||||
|
||||
impl ActiveParas {
|
||||
@@ -350,7 +357,6 @@ impl ActiveParas {
|
||||
.map(|x| x.ok())
|
||||
.flatten();
|
||||
|
||||
|
||||
let mc = polkadot_node_subsystem_util::request_availability_cores(relay_parent, sender)
|
||||
.await
|
||||
.await
|
||||
@@ -368,38 +374,32 @@ impl ActiveParas {
|
||||
);
|
||||
|
||||
continue
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let (para_now, para_next) = match polkadot_node_subsystem_util
|
||||
::signing_key_and_index(&validators, keystore)
|
||||
.await
|
||||
.and_then(|(_, index)| polkadot_node_subsystem_util::find_validator_group(
|
||||
&groups,
|
||||
index,
|
||||
))
|
||||
{
|
||||
Some(group) => {
|
||||
let next_rotation_info = rotation_info.bump_rotation();
|
||||
let (para_now, para_next) =
|
||||
match polkadot_node_subsystem_util::signing_key_and_index(&validators, keystore)
|
||||
.await
|
||||
.and_then(|(_, index)| {
|
||||
polkadot_node_subsystem_util::find_validator_group(&groups, index)
|
||||
}) {
|
||||
Some(group) => {
|
||||
let next_rotation_info = rotation_info.bump_rotation();
|
||||
|
||||
let core_now = rotation_info.core_for_group(group, cores.len());
|
||||
let core_next = next_rotation_info.core_for_group(group, cores.len());
|
||||
let core_now = rotation_info.core_for_group(group, cores.len());
|
||||
let core_next = next_rotation_info.core_for_group(group, cores.len());
|
||||
|
||||
(
|
||||
cores.get(core_now.0 as usize).and_then(|c| c.para_id()),
|
||||
cores.get(core_next.0 as usize).and_then(|c| c.para_id()),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
tracing::trace!(
|
||||
target: LOG_TARGET,
|
||||
?relay_parent,
|
||||
"Not a validator",
|
||||
);
|
||||
(
|
||||
cores.get(core_now.0 as usize).and_then(|c| c.para_id()),
|
||||
cores.get(core_next.0 as usize).and_then(|c| c.para_id()),
|
||||
)
|
||||
},
|
||||
None => {
|
||||
tracing::trace!(target: LOG_TARGET, ?relay_parent, "Not a validator",);
|
||||
|
||||
continue
|
||||
}
|
||||
};
|
||||
continue
|
||||
},
|
||||
};
|
||||
|
||||
// This code won't work well, if at all for parathreads. For parathreads we'll
|
||||
// have to be aware of which core the parathread claim is going to be multiplexed
|
||||
@@ -426,17 +426,12 @@ impl ActiveParas {
|
||||
*self.next_assignments.entry(para_next).or_default() += 1;
|
||||
}
|
||||
|
||||
self.relay_parent_assignments.insert(
|
||||
relay_parent,
|
||||
GroupAssignments { current: para_now, next: para_next },
|
||||
);
|
||||
self.relay_parent_assignments
|
||||
.insert(relay_parent, GroupAssignments { current: para_now, next: para_next });
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_outgoing(
|
||||
&mut self,
|
||||
old_relay_parents: impl IntoIterator<Item = Hash>,
|
||||
) {
|
||||
fn remove_outgoing(&mut self, old_relay_parents: impl IntoIterator<Item = Hash>) {
|
||||
for old_relay_parent in old_relay_parents {
|
||||
if let Some(assignments) = self.relay_parent_assignments.remove(&old_relay_parent) {
|
||||
let GroupAssignments { current, next } = assignments;
|
||||
@@ -482,16 +477,19 @@ struct PendingCollation {
|
||||
|
||||
impl PendingCollation {
|
||||
fn new(relay_parent: Hash, para_id: &ParaId, peer_id: &PeerId) -> Self {
|
||||
Self { relay_parent, para_id: para_id.clone(), peer_id: peer_id.clone(), commitments_hash: None }
|
||||
Self {
|
||||
relay_parent,
|
||||
para_id: para_id.clone(),
|
||||
peer_id: peer_id.clone(),
|
||||
commitments_hash: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type CollationEvent = (CollatorId, PendingCollation);
|
||||
|
||||
type PendingCollationFetch = (
|
||||
CollationEvent,
|
||||
std::result::Result<(CandidateReceipt, PoV), oneshot::Canceled>,
|
||||
);
|
||||
type PendingCollationFetch =
|
||||
(CollationEvent, std::result::Result<(CandidateReceipt, PoV), oneshot::Canceled>);
|
||||
|
||||
/// The status of the collations in [`CollationsPerRelayParent`].
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -567,7 +565,7 @@ impl CollationsPerRelayParent {
|
||||
let next = self.unfetched_collations.pop();
|
||||
self.waiting_collation = next.as_ref().map(|(_, collator_id)| collator_id.clone());
|
||||
next
|
||||
}
|
||||
},
|
||||
CollationStatus::WaitingOnValidation | CollationStatus::Fetching =>
|
||||
unreachable!("We have reset the status above!"),
|
||||
}
|
||||
@@ -622,20 +620,18 @@ fn collator_peer_id(
|
||||
peer_data: &HashMap<PeerId, PeerData>,
|
||||
collator_id: &CollatorId,
|
||||
) -> Option<PeerId> {
|
||||
peer_data.iter()
|
||||
.find_map(|(peer, data)|
|
||||
data.collator_id().filter(|c| c == &collator_id).map(|_| peer.clone())
|
||||
)
|
||||
peer_data.iter().find_map(|(peer, data)| {
|
||||
data.collator_id().filter(|c| c == &collator_id).map(|_| peer.clone())
|
||||
})
|
||||
}
|
||||
|
||||
async fn disconnect_peer<Context>(ctx: &mut Context, peer_id: PeerId)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::DisconnectPeer(peer_id, PeerSet::Collation)
|
||||
).await
|
||||
ctx.send_message(NetworkBridgeMessage::DisconnectPeer(peer_id, PeerSet::Collation))
|
||||
.await
|
||||
}
|
||||
|
||||
/// Another subsystem has requested to fetch collations on a particular leaf for some para.
|
||||
@@ -644,10 +640,9 @@ async fn fetch_collation<Context>(
|
||||
state: &mut State,
|
||||
pc: PendingCollation,
|
||||
id: CollatorId,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
@@ -657,7 +652,9 @@ where
|
||||
Delay::new(MAX_UNSHARED_DOWNLOAD_TIME).await;
|
||||
(collator_id, relay_parent)
|
||||
};
|
||||
state.collation_fetch_timeouts.push(timeout(id.clone(), relay_parent.clone()).boxed());
|
||||
state
|
||||
.collation_fetch_timeouts
|
||||
.push(timeout(id.clone(), relay_parent.clone()).boxed());
|
||||
|
||||
if state.peer_data.get(&peer_id).map_or(false, |d| d.has_advertised(&relay_parent)) {
|
||||
request_collation(ctx, state, relay_parent, para_id, peer_id, tx).await;
|
||||
@@ -671,9 +668,8 @@ async fn report_collator<Context>(
|
||||
ctx: &mut Context,
|
||||
peer_data: &HashMap<PeerId, PeerData>,
|
||||
id: CollatorId,
|
||||
)
|
||||
where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>
|
||||
) where
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
if let Some(peer_id) = collator_peer_id(peer_data, &id) {
|
||||
modify_reputation(ctx, peer_id, COST_REPORT_BAD).await;
|
||||
@@ -685,10 +681,9 @@ async fn note_good_collation<Context>(
|
||||
ctx: &mut Context,
|
||||
peer_data: &HashMap<PeerId, PeerData>,
|
||||
id: CollatorId,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
if let Some(peer_id) = collator_peer_id(peer_data, &id) {
|
||||
modify_reputation(ctx, peer_id, BENEFIT_NOTIFY_GOOD).await;
|
||||
@@ -701,18 +696,17 @@ async fn notify_collation_seconded<Context>(
|
||||
peer_id: PeerId,
|
||||
relay_parent: Hash,
|
||||
statement: SignedFullStatement,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
let wire_message = protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement.into());
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::SendCollationMessage(
|
||||
vec![peer_id],
|
||||
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
|
||||
)
|
||||
).await;
|
||||
let wire_message =
|
||||
protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement.into());
|
||||
ctx.send_message(NetworkBridgeMessage::SendCollationMessage(
|
||||
vec![peer_id],
|
||||
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
|
||||
))
|
||||
.await;
|
||||
|
||||
modify_reputation(ctx, peer_id, BENEFIT_NOTIFY_GOOD).await;
|
||||
}
|
||||
@@ -720,15 +714,12 @@ where
|
||||
/// A peer's view has changed. A number of things should be done:
|
||||
/// - Ongoing collation requests have to be canceled.
|
||||
/// - Advertisements by this peer that are no longer relevant have to be removed.
|
||||
async fn handle_peer_view_change(
|
||||
state: &mut State,
|
||||
peer_id: PeerId,
|
||||
view: View,
|
||||
) -> Result<()> {
|
||||
async fn handle_peer_view_change(state: &mut State, peer_id: PeerId, view: View) -> Result<()> {
|
||||
let peer_data = state.peer_data.entry(peer_id.clone()).or_default();
|
||||
|
||||
peer_data.update_view(view);
|
||||
state.requested_collations
|
||||
state
|
||||
.requested_collations
|
||||
.retain(|pc, _| pc.peer_id != peer_id || !peer_data.has_advertised(&pc.relay_parent));
|
||||
|
||||
Ok(())
|
||||
@@ -747,10 +738,9 @@ async fn request_collation<Context>(
|
||||
para_id: ParaId,
|
||||
peer_id: PeerId,
|
||||
result: oneshot::Sender<(CandidateReceipt, PoV)>,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
if !state.view.contains(&relay_parent) {
|
||||
tracing::debug!(
|
||||
@@ -760,7 +750,7 @@ where
|
||||
relay_parent = %relay_parent,
|
||||
"collation is no longer in view",
|
||||
);
|
||||
return;
|
||||
return
|
||||
}
|
||||
let pending_collation = PendingCollation::new(relay_parent, ¶_id, &peer_id);
|
||||
if state.requested_collations.contains_key(&pending_collation) {
|
||||
@@ -771,29 +761,27 @@ where
|
||||
?pending_collation.relay_parent,
|
||||
"collation has already been requested",
|
||||
);
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
let (full_request, response_recv) =
|
||||
OutgoingRequest::new(Recipient::Peer(peer_id), CollationFetchingRequest {
|
||||
relay_parent,
|
||||
para_id,
|
||||
});
|
||||
let (full_request, response_recv) = OutgoingRequest::new(
|
||||
Recipient::Peer(peer_id),
|
||||
CollationFetchingRequest { relay_parent, para_id },
|
||||
);
|
||||
let requests = Requests::CollationFetching(full_request);
|
||||
|
||||
let per_request = PerRequest {
|
||||
from_collator: response_recv.boxed().fuse(),
|
||||
to_requester: result,
|
||||
span: state.span_per_relay_parent.get(&relay_parent).map(|s| {
|
||||
s.child("collation-request")
|
||||
.with_para_id(para_id)
|
||||
}),
|
||||
span: state
|
||||
.span_per_relay_parent
|
||||
.get(&relay_parent)
|
||||
.map(|s| s.child("collation-request").with_para_id(para_id)),
|
||||
};
|
||||
|
||||
state.requested_collations.insert(
|
||||
PendingCollation::new(relay_parent, ¶_id, &peer_id),
|
||||
per_request
|
||||
);
|
||||
state
|
||||
.requested_collations
|
||||
.insert(PendingCollation::new(relay_parent, ¶_id, &peer_id), per_request);
|
||||
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -803,9 +791,11 @@ where
|
||||
"Requesting collation",
|
||||
);
|
||||
|
||||
ctx.send_message(
|
||||
NetworkBridgeMessage::SendRequests(vec![requests], IfDisconnected::ImmediateError)
|
||||
).await;
|
||||
ctx.send_message(NetworkBridgeMessage::SendRequests(
|
||||
vec![requests],
|
||||
IfDisconnected::ImmediateError,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Networking message has been received.
|
||||
@@ -814,10 +804,9 @@ async fn process_incoming_peer_message<Context>(
|
||||
state: &mut State,
|
||||
origin: PeerId,
|
||||
msg: protocol_v1::CollatorProtocolMessage,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
use protocol_v1::CollatorProtocolMessage::*;
|
||||
use sp_runtime::traits::AppVerify;
|
||||
@@ -833,7 +822,7 @@ where
|
||||
None => {
|
||||
modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await;
|
||||
return
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if peer_data.is_collating() {
|
||||
@@ -869,9 +858,12 @@ where
|
||||
tracing::trace!(target: LOG_TARGET, "Disconnecting unneeded collator");
|
||||
disconnect_peer(ctx, origin).await;
|
||||
}
|
||||
}
|
||||
},
|
||||
AdvertiseCollation(relay_parent) => {
|
||||
let _span = state.span_per_relay_parent.get(&relay_parent).map(|s| s.child("advertise-collation"));
|
||||
let _span = state
|
||||
.span_per_relay_parent
|
||||
.get(&relay_parent)
|
||||
.map(|s| s.child("advertise-collation"));
|
||||
if !state.view.contains(&relay_parent) {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -881,14 +873,14 @@ where
|
||||
);
|
||||
|
||||
modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await;
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
let peer_data = match state.peer_data.get_mut(&origin) {
|
||||
None => {
|
||||
modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await;
|
||||
return;
|
||||
}
|
||||
return
|
||||
},
|
||||
Some(p) => p,
|
||||
};
|
||||
|
||||
@@ -902,13 +894,10 @@ where
|
||||
"Received advertise collation",
|
||||
);
|
||||
|
||||
let pending_collation = PendingCollation::new(
|
||||
relay_parent,
|
||||
¶_id,
|
||||
&origin,
|
||||
);
|
||||
let pending_collation = PendingCollation::new(relay_parent, ¶_id, &origin);
|
||||
|
||||
let collations = state.collations_per_relay_parent.entry(relay_parent).or_default();
|
||||
let collations =
|
||||
state.collations_per_relay_parent.entry(relay_parent).or_default();
|
||||
|
||||
match collations.status {
|
||||
CollationStatus::Fetching | CollationStatus::WaitingOnValidation =>
|
||||
@@ -921,7 +910,7 @@ where
|
||||
},
|
||||
CollationStatus::Seconded => {},
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -932,33 +921,26 @@ where
|
||||
);
|
||||
|
||||
modify_reputation(ctx, origin, COST_UNEXPECTED_MESSAGE).await;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
CollationSeconded(_, _) => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
peer_id = ?origin,
|
||||
"Unexpected `CollationSeconded` message, decreasing reputation",
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// A leaf has become inactive so we want to
|
||||
/// - Cancel all ongoing collation requests that are on top of that leaf.
|
||||
/// - Remove all stored collations relevant to that leaf.
|
||||
async fn remove_relay_parent(
|
||||
state: &mut State,
|
||||
relay_parent: Hash,
|
||||
) -> Result<()> {
|
||||
state.requested_collations.retain(|k, _| {
|
||||
k.relay_parent != relay_parent
|
||||
});
|
||||
async fn remove_relay_parent(state: &mut State, relay_parent: Hash) -> Result<()> {
|
||||
state.requested_collations.retain(|k, _| k.relay_parent != relay_parent);
|
||||
|
||||
state.pending_candidates.retain(|k, _| {
|
||||
k != &relay_parent
|
||||
});
|
||||
state.pending_candidates.retain(|k, _| k != &relay_parent);
|
||||
|
||||
state.collations_per_relay_parent.remove(&relay_parent);
|
||||
Ok(())
|
||||
@@ -972,12 +954,13 @@ async fn handle_our_view_change<Context>(
|
||||
view: OurView,
|
||||
) -> Result<()>
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
let old_view = std::mem::replace(&mut state.view, view);
|
||||
|
||||
let added: HashMap<Hash, Arc<jaeger::Span>> = state.view
|
||||
let added: HashMap<Hash, Arc<jaeger::Span>> = state
|
||||
.view
|
||||
.span_per_head()
|
||||
.iter()
|
||||
.filter(|v| !old_view.contains(&v.0))
|
||||
@@ -989,10 +972,7 @@ where
|
||||
});
|
||||
|
||||
let added = state.view.difference(&old_view).cloned().collect::<Vec<_>>();
|
||||
let removed = old_view
|
||||
.difference(&state.view)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
let removed = old_view.difference(&state.view).cloned().collect::<Vec<_>>();
|
||||
|
||||
for removed in removed.iter().cloned() {
|
||||
remove_relay_parent(state, removed).await?;
|
||||
@@ -1028,8 +1008,8 @@ async fn handle_network_msg<Context>(
|
||||
bridge_message: NetworkBridgeEvent<protocol_v1::CollatorProtocolMessage>,
|
||||
) -> Result<()>
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
use NetworkBridgeEvent::*;
|
||||
|
||||
@@ -1044,7 +1024,7 @@ where
|
||||
},
|
||||
NewGossipTopology(..) => {
|
||||
// impossibru!
|
||||
}
|
||||
},
|
||||
PeerViewChange(peer_id, view) => {
|
||||
handle_peer_view_change(state, peer_id, view).await?;
|
||||
},
|
||||
@@ -1053,7 +1033,7 @@ where
|
||||
},
|
||||
PeerMessage(remote, msg) => {
|
||||
process_incoming_peer_message(ctx, state, remote, msg).await;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1065,10 +1045,9 @@ async fn process_msg<Context>(
|
||||
keystore: &SyncCryptoStorePtr,
|
||||
msg: CollatorProtocolMessage,
|
||||
state: &mut State,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
use CollatorProtocolMessage::*;
|
||||
|
||||
@@ -1081,36 +1060,31 @@ where
|
||||
para_id = %id,
|
||||
"CollateOn message is not expected on the validator side of the protocol",
|
||||
);
|
||||
}
|
||||
},
|
||||
DistributeCollation(_, _, _) => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
"DistributeCollation message is not expected on the validator side of the protocol",
|
||||
);
|
||||
}
|
||||
},
|
||||
ReportCollator(id) => {
|
||||
report_collator(ctx, &state.peer_data, id).await;
|
||||
}
|
||||
},
|
||||
NetworkBridgeUpdateV1(event) => {
|
||||
if let Err(e) = handle_network_msg(
|
||||
ctx,
|
||||
state,
|
||||
keystore,
|
||||
event,
|
||||
).await {
|
||||
if let Err(e) = handle_network_msg(ctx, state, keystore, event).await {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
err = ?e,
|
||||
"Failed to handle incoming network message",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
CollationFetchingRequest(_) => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
"CollationFetchingRequest message is not expected on the validator side of the protocol",
|
||||
);
|
||||
}
|
||||
},
|
||||
Seconded(parent, stmt) => {
|
||||
if let Some(collation_event) = state.pending_candidates.remove(&parent) {
|
||||
let (collator_id, pending_collation) = collation_event;
|
||||
@@ -1128,11 +1102,13 @@ where
|
||||
"Collation has been seconded, but the relay parent is deactivated",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
Invalid(parent, candidate_receipt) => {
|
||||
let id = match state.pending_candidates.entry(parent) {
|
||||
Entry::Occupied(entry)
|
||||
if entry.get().1.commitments_hash == Some(candidate_receipt.commitments_hash) => entry.remove().0,
|
||||
if entry.get().1.commitments_hash ==
|
||||
Some(candidate_receipt.commitments_hash) =>
|
||||
entry.remove().0,
|
||||
Entry::Occupied(_) => {
|
||||
tracing::error!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1141,14 +1117,14 @@ where
|
||||
"Reported invalid candidate for unknown `pending_candidate`!",
|
||||
);
|
||||
return
|
||||
}
|
||||
},
|
||||
Entry::Vacant(_) => return,
|
||||
};
|
||||
|
||||
report_collator(ctx, &state.peer_data, id.clone()).await;
|
||||
|
||||
dequeue_next_collation_and_fetch(ctx, state, parent, id).await;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1172,20 +1148,18 @@ pub(crate) async fn run<Context>(
|
||||
metrics: Metrics,
|
||||
) -> Result<()>
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
use OverseerSignal::*;
|
||||
|
||||
let mut state = State {
|
||||
metrics,
|
||||
..Default::default()
|
||||
};
|
||||
let mut state = State { metrics, ..Default::default() };
|
||||
|
||||
let next_inactivity_stream = futures::stream::unfold(
|
||||
Instant::now() + ACTIVITY_POLL,
|
||||
|next_check| async move { Some(((), wait_until_next_check(next_check).await)) }
|
||||
).fuse();
|
||||
let next_inactivity_stream =
|
||||
futures::stream::unfold(Instant::now() + ACTIVITY_POLL, |next_check| async move {
|
||||
Some(((), wait_until_next_check(next_check).await))
|
||||
})
|
||||
.fuse();
|
||||
|
||||
futures::pin_mut!(next_inactivity_stream);
|
||||
|
||||
@@ -1227,8 +1201,13 @@ where
|
||||
for (pending_collation, per_req) in state.requested_collations.iter_mut() {
|
||||
// Despite the await, this won't block on the response itself.
|
||||
let finished = poll_collation_response(
|
||||
&mut ctx, &state.metrics, &state.span_per_relay_parent, pending_collation, per_req,
|
||||
).await;
|
||||
&mut ctx,
|
||||
&state.metrics,
|
||||
&state.span_per_relay_parent,
|
||||
pending_collation,
|
||||
per_req,
|
||||
)
|
||||
.await;
|
||||
if !finished {
|
||||
retained_requested.insert(pending_collation.clone());
|
||||
}
|
||||
@@ -1240,13 +1219,15 @@ where
|
||||
|
||||
/// Dequeue another collation and fetch.
|
||||
async fn dequeue_next_collation_and_fetch(
|
||||
ctx: &mut (impl SubsystemContext<Message = CollatorProtocolMessage> + overseer::SubsystemContext<Message = CollatorProtocolMessage>),
|
||||
ctx: &mut (impl SubsystemContext<Message = CollatorProtocolMessage>
|
||||
+ overseer::SubsystemContext<Message = CollatorProtocolMessage>),
|
||||
state: &mut State,
|
||||
relay_parent: Hash,
|
||||
// The collator we tried to fetch from last.
|
||||
previous_fetch: CollatorId,
|
||||
) {
|
||||
if let Some((next, id)) = state.collations_per_relay_parent
|
||||
if let Some((next, id)) = state
|
||||
.collations_per_relay_parent
|
||||
.get_mut(&relay_parent)
|
||||
.and_then(|c| c.get_next_collation_to_fetch(Some(previous_fetch)))
|
||||
{
|
||||
@@ -1259,10 +1240,9 @@ async fn handle_collation_fetched_result<Context>(
|
||||
ctx: &mut Context,
|
||||
state: &mut State,
|
||||
(mut collation_event, res): PendingCollationFetch,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
// If no prior collation for this relay parent has been seconded, then
|
||||
// memoize the collation_event for that relay_parent, such that we may
|
||||
@@ -1301,13 +1281,12 @@ where
|
||||
|
||||
if let Entry::Vacant(entry) = state.pending_candidates.entry(relay_parent) {
|
||||
collation_event.1.commitments_hash = Some(candidate_receipt.commitments_hash);
|
||||
ctx.send_message(
|
||||
CandidateBackingMessage::Second(
|
||||
relay_parent.clone(),
|
||||
candidate_receipt,
|
||||
pov,
|
||||
)
|
||||
).await;
|
||||
ctx.send_message(CandidateBackingMessage::Second(
|
||||
relay_parent.clone(),
|
||||
candidate_receipt,
|
||||
pov,
|
||||
))
|
||||
.await;
|
||||
|
||||
entry.insert(collation_event);
|
||||
} else {
|
||||
@@ -1327,10 +1306,9 @@ async fn disconnect_inactive_peers<Context>(
|
||||
ctx: &mut Context,
|
||||
eviction_policy: &crate::CollatorEvictionPolicy,
|
||||
peers: &HashMap<PeerId, PeerData>,
|
||||
)
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
) where
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
{
|
||||
for (peer, peer_data) in peers {
|
||||
if peer_data.is_inactive(&eviction_policy) {
|
||||
@@ -1352,10 +1330,9 @@ async fn poll_collation_response<Context>(
|
||||
spans: &HashMap<Hash, PerLeafSpan>,
|
||||
pending_collation: &PendingCollation,
|
||||
per_req: &mut PerRequest,
|
||||
)
|
||||
-> bool
|
||||
) -> bool
|
||||
where
|
||||
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
|
||||
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
|
||||
Context: SubsystemContext,
|
||||
{
|
||||
if never!(per_req.from_collator.is_terminated()) {
|
||||
@@ -1367,8 +1344,9 @@ where
|
||||
}
|
||||
|
||||
if let Poll::Ready(response) = futures::poll!(&mut per_req.from_collator) {
|
||||
let _span = spans.get(&pending_collation.relay_parent)
|
||||
.map(|s| s.child("received-collation"));
|
||||
let _span = spans
|
||||
.get(&pending_collation.relay_parent)
|
||||
.map(|s| s.child("received-collation"));
|
||||
let _timer = metrics.time_handle_collation_request_result();
|
||||
|
||||
let mut metrics_result = Err(());
|
||||
@@ -1384,12 +1362,9 @@ where
|
||||
err = ?err,
|
||||
"Collator provided response that could not be decoded"
|
||||
);
|
||||
modify_reputation(
|
||||
ctx,
|
||||
pending_collation.peer_id.clone(),
|
||||
COST_CORRUPTED_MESSAGE
|
||||
).await;
|
||||
}
|
||||
modify_reputation(ctx, pending_collation.peer_id.clone(), COST_CORRUPTED_MESSAGE)
|
||||
.await;
|
||||
},
|
||||
Err(RequestError::NetworkError(err)) => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1404,7 +1379,7 @@ where
|
||||
// which would result in reduced reputation for proper nodes, but the
|
||||
// same can happen for penalties on timeouts, which we also have.
|
||||
modify_reputation(ctx, pending_collation.peer_id.clone(), COST_NETWORK_ERROR).await;
|
||||
}
|
||||
},
|
||||
Err(RequestError::Canceled(_)) => {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1417,8 +1392,9 @@ where
|
||||
// sensible. In theory this could be exploited, by DoSing this node,
|
||||
// which would result in reduced reputation for proper nodes, but the
|
||||
// same can happen for penalties on timeouts, which we also have.
|
||||
modify_reputation(ctx, pending_collation.peer_id.clone(), COST_REQUEST_TIMED_OUT).await;
|
||||
}
|
||||
modify_reputation(ctx, pending_collation.peer_id.clone(), COST_REQUEST_TIMED_OUT)
|
||||
.await;
|
||||
},
|
||||
Ok(CollationFetchingResponse::Collation(receipt, _))
|
||||
if receipt.descriptor().para_id != pending_collation.para_id =>
|
||||
{
|
||||
@@ -1446,7 +1422,7 @@ where
|
||||
std::mem::swap(&mut tx, &mut (per_req.to_requester));
|
||||
let result = tx.send((receipt, pov));
|
||||
|
||||
if let Err(_) = result {
|
||||
if let Err(_) = result {
|
||||
tracing::warn!(
|
||||
target: LOG_TARGET,
|
||||
hash = ?pending_collation.relay_parent,
|
||||
@@ -1458,7 +1434,7 @@ where
|
||||
metrics_result = Ok(());
|
||||
success = "true";
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
metrics.on_request(metrics_result);
|
||||
per_req.span.as_mut().map(|s| s.add_string_tag("success", success));
|
||||
|
||||
@@ -15,26 +15,26 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
use std::{iter, time::Duration};
|
||||
use std::sync::Arc;
|
||||
use assert_matches::assert_matches;
|
||||
use futures::{executor, future, Future};
|
||||
use sp_core::{crypto::Pair, Encode};
|
||||
use sp_keystore::SyncCryptoStore;
|
||||
use sp_keystore::testing::KeyStore as TestKeyStore;
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
use assert_matches::assert_matches;
|
||||
use sp_keystore::{testing::KeyStore as TestKeyStore, SyncCryptoStore};
|
||||
use std::{iter, sync::Arc, time::Duration};
|
||||
|
||||
use polkadot_primitives::v1::{
|
||||
CollatorPair, ValidatorId, ValidatorIndex, CoreState, CandidateDescriptor,
|
||||
GroupRotationInfo, ScheduledCore, OccupiedCore, GroupIndex,
|
||||
use polkadot_node_network_protocol::{
|
||||
our_view,
|
||||
request_response::{Requests, ResponseSender},
|
||||
ObservedRole,
|
||||
};
|
||||
use polkadot_node_primitives::BlockData;
|
||||
use polkadot_node_subsystem_util::TimeoutExt;
|
||||
use polkadot_subsystem_testhelpers as test_helpers;
|
||||
use polkadot_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest};
|
||||
use polkadot_node_network_protocol::{
|
||||
our_view, ObservedRole, request_response::{Requests, ResponseSender},
|
||||
use polkadot_primitives::v1::{
|
||||
CandidateDescriptor, CollatorPair, CoreState, GroupIndex, GroupRotationInfo, OccupiedCore,
|
||||
ScheduledCore, ValidatorId, ValidatorIndex,
|
||||
};
|
||||
use polkadot_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest};
|
||||
use polkadot_subsystem_testhelpers as test_helpers;
|
||||
|
||||
const ACTIVITY_TIMEOUT: Duration = Duration::from_millis(500);
|
||||
const DECLARE_TIMEOUT: Duration = Duration::from_millis(25);
|
||||
@@ -58,10 +58,7 @@ impl Default for TestState {
|
||||
|
||||
let chain_ids = vec![chain_a, chain_b];
|
||||
let relay_parent = Hash::repeat_byte(0x05);
|
||||
let collators = iter::repeat(())
|
||||
.map(|_| CollatorPair::generate().0)
|
||||
.take(5)
|
||||
.collect();
|
||||
let collators = iter::repeat(()).map(|_| CollatorPair::generate().0).take(5).collect();
|
||||
|
||||
let validators = vec![
|
||||
Sr25519Keyring::Alice,
|
||||
@@ -78,17 +75,11 @@ impl Default for TestState {
|
||||
vec![ValidatorIndex(4)],
|
||||
];
|
||||
|
||||
let group_rotation_info = GroupRotationInfo {
|
||||
session_start_block: 0,
|
||||
group_rotation_frequency: 1,
|
||||
now: 0,
|
||||
};
|
||||
let group_rotation_info =
|
||||
GroupRotationInfo { session_start_block: 0, group_rotation_frequency: 1, now: 0 };
|
||||
|
||||
let cores = vec![
|
||||
CoreState::Scheduled(ScheduledCore {
|
||||
para_id: chain_ids[0],
|
||||
collator: None,
|
||||
}),
|
||||
CoreState::Scheduled(ScheduledCore { para_id: chain_ids[0], collator: None }),
|
||||
CoreState::Free,
|
||||
CoreState::Occupied(OccupiedCore {
|
||||
next_up_on_available: None,
|
||||
@@ -129,14 +120,8 @@ struct TestHarness {
|
||||
fn test_harness<T: Future<Output = VirtualOverseer>>(test: impl FnOnce(TestHarness) -> T) {
|
||||
let _ = env_logger::builder()
|
||||
.is_test(true)
|
||||
.filter(
|
||||
Some("polkadot_collator_protocol"),
|
||||
log::LevelFilter::Trace,
|
||||
)
|
||||
.filter(
|
||||
Some(LOG_TARGET),
|
||||
log::LevelFilter::Trace,
|
||||
)
|
||||
.filter(Some("polkadot_collator_protocol"), log::LevelFilter::Trace)
|
||||
.filter(Some(LOG_TARGET), log::LevelFilter::Trace)
|
||||
.try_init();
|
||||
|
||||
let pool = sp_core::testing::TaskExecutor::new();
|
||||
@@ -144,10 +129,12 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(test: impl FnOnce(TestHarne
|
||||
let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone());
|
||||
|
||||
let keystore = TestKeyStore::new();
|
||||
keystore.sr25519_generate_new(
|
||||
polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID,
|
||||
Some(&Sr25519Keyring::Alice.to_seed()),
|
||||
).unwrap();
|
||||
keystore
|
||||
.sr25519_generate_new(
|
||||
polkadot_primitives::v1::PARACHAIN_KEY_TYPE_ID,
|
||||
Some(&Sr25519Keyring::Alice.to_seed()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let subsystem = run(
|
||||
context,
|
||||
@@ -164,18 +151,20 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(test: impl FnOnce(TestHarne
|
||||
futures::pin_mut!(test_fut);
|
||||
futures::pin_mut!(subsystem);
|
||||
|
||||
executor::block_on(future::join(async move {
|
||||
let mut overseer = test_fut.await;
|
||||
overseer_signal(&mut overseer, OverseerSignal::Conclude).await;
|
||||
}, subsystem)).1.unwrap();
|
||||
executor::block_on(future::join(
|
||||
async move {
|
||||
let mut overseer = test_fut.await;
|
||||
overseer_signal(&mut overseer, OverseerSignal::Conclude).await;
|
||||
},
|
||||
subsystem,
|
||||
))
|
||||
.1
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const TIMEOUT: Duration = Duration::from_millis(200);
|
||||
|
||||
async fn overseer_send(
|
||||
overseer: &mut VirtualOverseer,
|
||||
msg: CollatorProtocolMessage,
|
||||
) {
|
||||
async fn overseer_send(overseer: &mut VirtualOverseer, msg: CollatorProtocolMessage) {
|
||||
tracing::trace!("Sending message:\n{:?}", &msg);
|
||||
overseer
|
||||
.send(FromOverseer::Communication { msg })
|
||||
@@ -184,9 +173,7 @@ async fn overseer_send(
|
||||
.expect(&format!("{:?} is enough for sending messages.", TIMEOUT));
|
||||
}
|
||||
|
||||
async fn overseer_recv(
|
||||
overseer: &mut VirtualOverseer,
|
||||
) -> AllMessages {
|
||||
async fn overseer_recv(overseer: &mut VirtualOverseer) -> AllMessages {
|
||||
let msg = overseer_recv_with_timeout(overseer, TIMEOUT)
|
||||
.await
|
||||
.expect(&format!("{:?} is enough to receive messages.", TIMEOUT));
|
||||
@@ -201,16 +188,10 @@ async fn overseer_recv_with_timeout(
|
||||
timeout: Duration,
|
||||
) -> Option<AllMessages> {
|
||||
tracing::trace!("Waiting for message...");
|
||||
overseer
|
||||
.recv()
|
||||
.timeout(timeout)
|
||||
.await
|
||||
overseer.recv().timeout(timeout).await
|
||||
}
|
||||
|
||||
async fn overseer_signal(
|
||||
overseer: &mut VirtualOverseer,
|
||||
signal: OverseerSignal,
|
||||
) {
|
||||
async fn overseer_signal(overseer: &mut VirtualOverseer, signal: OverseerSignal) {
|
||||
overseer
|
||||
.send(FromOverseer::Signal(signal))
|
||||
.timeout(TIMEOUT)
|
||||
@@ -275,10 +256,7 @@ async fn assert_candidate_backing_second(
|
||||
}
|
||||
|
||||
/// Assert that a collator got disconnected.
|
||||
async fn assert_collator_disconnect(
|
||||
virtual_overseer: &mut VirtualOverseer,
|
||||
expected_peer: PeerId,
|
||||
) {
|
||||
async fn assert_collator_disconnect(virtual_overseer: &mut VirtualOverseer, expected_peer: PeerId) {
|
||||
assert_matches!(
|
||||
overseer_recv(virtual_overseer).await,
|
||||
AllMessages::NetworkBridge(NetworkBridgeMessage::DisconnectPeer(
|
||||
@@ -324,28 +302,26 @@ async fn connect_and_declare_collator(
|
||||
) {
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerConnected(
|
||||
peer.clone(),
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
),
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected(
|
||||
peer.clone(),
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer.clone(),
|
||||
protocol_v1::CollatorProtocolMessage::Declare(
|
||||
collator.public(),
|
||||
para_id,
|
||||
collator.sign(&protocol_v1::declare_signature_payload(&peer)),
|
||||
)
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage(
|
||||
peer.clone(),
|
||||
protocol_v1::CollatorProtocolMessage::Declare(
|
||||
collator.public(),
|
||||
para_id,
|
||||
collator.sign(&protocol_v1::declare_signature_payload(&peer)),
|
||||
),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Advertise a collation.
|
||||
@@ -356,15 +332,12 @@ async fn advertise_collation(
|
||||
) {
|
||||
overseer_send(
|
||||
virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer,
|
||||
protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
|
||||
relay_parent,
|
||||
)
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage(
|
||||
peer,
|
||||
protocol_v1::CollatorProtocolMessage::AdvertiseCollation(relay_parent),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
// As we receive a relevant advertisement act on it and issue a collation request.
|
||||
@@ -373,29 +346,39 @@ fn act_on_advertisement() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let pair = CollatorPair::generate().0;
|
||||
tracing::trace!("activating");
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
|
||||
connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await;
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_b.clone(),
|
||||
pair.clone(),
|
||||
test_state.chain_ids[0],
|
||||
)
|
||||
.await;
|
||||
|
||||
advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await;
|
||||
|
||||
assert_fetch_collation_request(&mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0]).await;
|
||||
assert_fetch_collation_request(
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
)
|
||||
.await;
|
||||
|
||||
virtual_overseer
|
||||
});
|
||||
@@ -407,16 +390,15 @@ fn collator_reporting_works() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
@@ -428,19 +410,22 @@ fn collator_reporting_works() {
|
||||
peer_b.clone(),
|
||||
test_state.collators[0].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_c.clone(),
|
||||
test_state.collators[1].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::ReportCollator(test_state.collators[0].public()),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_matches!(
|
||||
overseer_recv(&mut virtual_overseer).await,
|
||||
@@ -462,22 +447,19 @@ fn collator_authentication_verification_works() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerConnected(
|
||||
peer_b,
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
),
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected(
|
||||
peer_b,
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
// the peer sends a declare message but sign the wrong payload
|
||||
overseer_send(
|
||||
@@ -521,18 +503,17 @@ fn fetch_collations_works() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let second = Hash::random();
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent, second])
|
||||
),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent, second],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
@@ -545,14 +526,16 @@ fn fetch_collations_works() {
|
||||
peer_b.clone(),
|
||||
test_state.collators[0].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_c.clone(),
|
||||
test_state.collators[1].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await;
|
||||
advertise_collation(&mut virtual_overseer, peer_c.clone(), test_state.relay_parent).await;
|
||||
@@ -561,7 +544,8 @@ fn fetch_collations_works() {
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(
|
||||
overseer_recv_with_timeout(&mut &mut virtual_overseer, Duration::from_millis(30)).await.is_none(),
|
||||
@@ -572,29 +556,35 @@ fn fetch_collations_works() {
|
||||
let mut candidate_a = CandidateReceipt::default();
|
||||
candidate_a.descriptor.para_id = test_state.chain_ids[0];
|
||||
candidate_a.descriptor.relay_parent = test_state.relay_parent;
|
||||
response_channel.send(Ok(
|
||||
CollationFetchingResponse::Collation(
|
||||
candidate_a.clone(),
|
||||
pov.clone(),
|
||||
).encode()
|
||||
)).expect("Sending response should succeed");
|
||||
response_channel
|
||||
.send(Ok(
|
||||
CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode()
|
||||
))
|
||||
.expect("Sending response should succeed");
|
||||
|
||||
assert_candidate_backing_second(
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
&pov,
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(peer_b.clone())),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(
|
||||
peer_b.clone(),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(peer_c.clone())),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerDisconnected(
|
||||
peer_c.clone(),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
let peer_c = PeerId::random();
|
||||
@@ -605,32 +595,32 @@ fn fetch_collations_works() {
|
||||
peer_b.clone(),
|
||||
test_state.collators[2].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_c.clone(),
|
||||
test_state.collators[3].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_d.clone(),
|
||||
test_state.collators[4].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
advertise_collation(&mut virtual_overseer, peer_b.clone(), second).await;
|
||||
advertise_collation(&mut virtual_overseer, peer_c.clone(), second).await;
|
||||
advertise_collation(&mut virtual_overseer, peer_d.clone(), second).await;
|
||||
|
||||
// Dropping the response channel should lead to fetching the second collation.
|
||||
assert_fetch_collation_request(
|
||||
&mut virtual_overseer,
|
||||
second,
|
||||
test_state.chain_ids[0],
|
||||
).await;
|
||||
assert_fetch_collation_request(&mut virtual_overseer, second, test_state.chain_ids[0])
|
||||
.await;
|
||||
|
||||
assert_matches!(
|
||||
overseer_recv(&mut virtual_overseer).await,
|
||||
@@ -643,20 +633,16 @@ fn fetch_collations_works() {
|
||||
}
|
||||
);
|
||||
|
||||
let response_channel_non_exclusive = assert_fetch_collation_request(
|
||||
&mut virtual_overseer,
|
||||
second,
|
||||
test_state.chain_ids[0],
|
||||
).await;
|
||||
let response_channel_non_exclusive =
|
||||
assert_fetch_collation_request(&mut virtual_overseer, second, test_state.chain_ids[0])
|
||||
.await;
|
||||
|
||||
// Third collator should receive response after that timeout:
|
||||
Delay::new(MAX_UNSHARED_DOWNLOAD_TIME + Duration::from_millis(50)).await;
|
||||
|
||||
let response_channel = assert_fetch_collation_request(
|
||||
&mut virtual_overseer,
|
||||
second,
|
||||
test_state.chain_ids[0],
|
||||
).await;
|
||||
let response_channel =
|
||||
assert_fetch_collation_request(&mut virtual_overseer, second, test_state.chain_ids[0])
|
||||
.await;
|
||||
|
||||
let pov = PoV { block_data: BlockData(vec![1]) };
|
||||
let mut candidate_a = CandidateReceipt::default();
|
||||
@@ -664,26 +650,25 @@ fn fetch_collations_works() {
|
||||
candidate_a.descriptor.relay_parent = second;
|
||||
|
||||
// First request finishes now:
|
||||
response_channel_non_exclusive.send(Ok(
|
||||
CollationFetchingResponse::Collation(
|
||||
candidate_a.clone(),
|
||||
pov.clone(),
|
||||
).encode()
|
||||
)).expect("Sending response should succeed");
|
||||
response_channel_non_exclusive
|
||||
.send(Ok(
|
||||
CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode()
|
||||
))
|
||||
.expect("Sending response should succeed");
|
||||
|
||||
response_channel.send(Ok(
|
||||
CollationFetchingResponse::Collation(
|
||||
candidate_a.clone(),
|
||||
pov.clone(),
|
||||
).encode()
|
||||
)).expect("Sending response should succeed");
|
||||
response_channel
|
||||
.send(Ok(
|
||||
CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode()
|
||||
))
|
||||
.expect("Sending response should succeed");
|
||||
|
||||
assert_candidate_backing_second(
|
||||
&mut virtual_overseer,
|
||||
second,
|
||||
test_state.chain_ids[0],
|
||||
&pov,
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
virtual_overseer
|
||||
});
|
||||
@@ -695,18 +680,17 @@ fn fetch_next_collation_on_invalid_collation() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let second = Hash::random();
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent, second])
|
||||
),
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent, second],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
@@ -719,14 +703,16 @@ fn fetch_next_collation_on_invalid_collation() {
|
||||
peer_b.clone(),
|
||||
test_state.collators[0].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_c.clone(),
|
||||
test_state.collators[1].clone(),
|
||||
test_state.chain_ids[0].clone(),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await;
|
||||
advertise_collation(&mut virtual_overseer, peer_c.clone(), test_state.relay_parent).await;
|
||||
@@ -735,28 +721,33 @@ fn fetch_next_collation_on_invalid_collation() {
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
let pov = PoV { block_data: BlockData(vec![]) };
|
||||
let mut candidate_a = CandidateReceipt::default();
|
||||
candidate_a.descriptor.para_id = test_state.chain_ids[0];
|
||||
candidate_a.descriptor.relay_parent = test_state.relay_parent;
|
||||
response_channel.send(Ok(
|
||||
CollationFetchingResponse::Collation(
|
||||
candidate_a.clone(),
|
||||
pov.clone(),
|
||||
).encode()
|
||||
)).expect("Sending response should succeed");
|
||||
response_channel
|
||||
.send(Ok(
|
||||
CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()).encode()
|
||||
))
|
||||
.expect("Sending response should succeed");
|
||||
|
||||
let receipt = assert_candidate_backing_second(
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
&pov,
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
// Inform that the candidate was invalid.
|
||||
overseer_send(&mut virtual_overseer, CollatorProtocolMessage::Invalid(test_state.relay_parent, receipt)).await;
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::Invalid(test_state.relay_parent, receipt),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_matches!(
|
||||
overseer_recv(&mut virtual_overseer).await,
|
||||
@@ -774,7 +765,8 @@ fn fetch_next_collation_on_invalid_collation() {
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
|
||||
virtual_overseer
|
||||
});
|
||||
@@ -785,9 +777,7 @@ fn inactive_disconnected() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let pair = CollatorPair::generate().0;
|
||||
|
||||
@@ -795,19 +785,31 @@ fn inactive_disconnected() {
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![hash_a])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![hash_a],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
|
||||
connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await;
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_b.clone(),
|
||||
pair.clone(),
|
||||
test_state.chain_ids[0],
|
||||
)
|
||||
.await;
|
||||
advertise_collation(&mut virtual_overseer, peer_b.clone(), test_state.relay_parent).await;
|
||||
|
||||
assert_fetch_collation_request(&mut virtual_overseer, test_state.relay_parent, test_state.chain_ids[0]).await;
|
||||
assert_fetch_collation_request(
|
||||
&mut virtual_overseer,
|
||||
test_state.relay_parent,
|
||||
test_state.chain_ids[0],
|
||||
)
|
||||
.await;
|
||||
|
||||
Delay::new(ACTIVITY_TIMEOUT * 3).await;
|
||||
|
||||
@@ -832,9 +834,7 @@ fn activity_extends_life() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let pair = CollatorPair::generate().0;
|
||||
|
||||
@@ -844,10 +844,11 @@ fn activity_extends_life() {
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![hash_a, hash_b, hash_c])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![hash_a, hash_b, hash_c],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
// 3 heads, 3 times.
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
@@ -856,13 +857,20 @@ fn activity_extends_life() {
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
|
||||
connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await;
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_b.clone(),
|
||||
pair.clone(),
|
||||
test_state.chain_ids[0],
|
||||
)
|
||||
.await;
|
||||
|
||||
Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
|
||||
|
||||
advertise_collation(&mut virtual_overseer, peer_b.clone(), hash_a).await;
|
||||
|
||||
assert_fetch_collation_request(&mut virtual_overseer, hash_a, test_state.chain_ids[0]).await;
|
||||
assert_fetch_collation_request(&mut virtual_overseer, hash_a, test_state.chain_ids[0])
|
||||
.await;
|
||||
|
||||
Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
|
||||
|
||||
@@ -879,7 +887,8 @@ fn activity_extends_life() {
|
||||
}
|
||||
);
|
||||
|
||||
assert_fetch_collation_request(&mut virtual_overseer, hash_b, test_state.chain_ids[0]).await;
|
||||
assert_fetch_collation_request(&mut virtual_overseer, hash_b, test_state.chain_ids[0])
|
||||
.await;
|
||||
|
||||
Delay::new(ACTIVITY_TIMEOUT * 2 / 3).await;
|
||||
|
||||
@@ -896,7 +905,8 @@ fn activity_extends_life() {
|
||||
}
|
||||
);
|
||||
|
||||
assert_fetch_collation_request(&mut virtual_overseer, hash_c, test_state.chain_ids[0]).await;
|
||||
assert_fetch_collation_request(&mut virtual_overseer, hash_c, test_state.chain_ids[0])
|
||||
.await;
|
||||
|
||||
Delay::new(ACTIVITY_TIMEOUT * 3 / 2).await;
|
||||
|
||||
@@ -922,16 +932,15 @@ fn disconnect_if_no_declare() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
@@ -939,14 +948,13 @@ fn disconnect_if_no_declare() {
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerConnected(
|
||||
peer_b.clone(),
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected(
|
||||
peer_b.clone(),
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_collator_disconnect(&mut virtual_overseer, peer_b.clone()).await;
|
||||
|
||||
@@ -959,18 +967,17 @@ fn disconnect_if_wrong_declare() {
|
||||
let test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let pair = CollatorPair::generate().0;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
@@ -978,28 +985,26 @@ fn disconnect_if_wrong_declare() {
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerConnected(
|
||||
peer_b.clone(),
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerConnected(
|
||||
peer_b.clone(),
|
||||
ObservedRole::Full,
|
||||
None,
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_b.clone(),
|
||||
protocol_v1::CollatorProtocolMessage::Declare(
|
||||
pair.public(),
|
||||
ParaId::from(69),
|
||||
pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
|
||||
)
|
||||
)
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::PeerMessage(
|
||||
peer_b.clone(),
|
||||
protocol_v1::CollatorProtocolMessage::Declare(
|
||||
pair.public(),
|
||||
ParaId::from(69),
|
||||
pair.sign(&protocol_v1::declare_signature_payload(&peer_b)),
|
||||
),
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_matches!(
|
||||
overseer_recv(&mut virtual_overseer).await,
|
||||
@@ -1023,33 +1028,39 @@ fn view_change_clears_old_collators() {
|
||||
let mut test_state = TestState::default();
|
||||
|
||||
test_harness(|test_harness| async move {
|
||||
let TestHarness {
|
||||
mut virtual_overseer,
|
||||
} = test_harness;
|
||||
let TestHarness { mut virtual_overseer } = test_harness;
|
||||
|
||||
let pair = CollatorPair::generate().0;
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![test_state.relay_parent])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![test_state.relay_parent],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
let peer_b = PeerId::random();
|
||||
|
||||
connect_and_declare_collator(&mut virtual_overseer, peer_b.clone(), pair.clone(), test_state.chain_ids[0]).await;
|
||||
connect_and_declare_collator(
|
||||
&mut virtual_overseer,
|
||||
peer_b.clone(),
|
||||
pair.clone(),
|
||||
test_state.chain_ids[0],
|
||||
)
|
||||
.await;
|
||||
|
||||
let hash_b = Hash::repeat_byte(69);
|
||||
|
||||
overseer_send(
|
||||
&mut virtual_overseer,
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(
|
||||
NetworkBridgeEvent::OurViewChange(our_view![hash_b])
|
||||
)
|
||||
).await;
|
||||
CollatorProtocolMessage::NetworkBridgeUpdateV1(NetworkBridgeEvent::OurViewChange(
|
||||
our_view![hash_b],
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
|
||||
test_state.group_rotation_info = test_state.group_rotation_info.bump_rotation();
|
||||
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
|
||||
|
||||
Reference in New Issue
Block a user