mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 02:51:08 +00:00
Use same fmt and clippy configs as in Substrate (#7611)
* Use same rustfmt.toml as Substrate Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * format format file Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Format with new config Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add Substrate Clippy config Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Print Clippy version in CI Otherwise its difficult to reproduce locally. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make fmt happy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update node/core/pvf/src/error.rs Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io> * Update node/core/pvf/src/error.rs Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io> --------- Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io>
This commit is contained in:
committed by
GitHub
parent
ac435c96cf
commit
342d720573
@@ -14,7 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! The disputes module is responsible for selecting dispute votes to be sent with the inherent data.
|
||||
//! The disputes module is responsible for selecting dispute votes to be sent with the inherent
|
||||
//! data.
|
||||
|
||||
use crate::LOG_TARGET;
|
||||
use futures::channel::oneshot;
|
||||
@@ -22,7 +23,8 @@ use polkadot_node_primitives::CandidateVotes;
|
||||
use polkadot_node_subsystem::{messages::DisputeCoordinatorMessage, overseer};
|
||||
use polkadot_primitives::{CandidateHash, SessionIndex};
|
||||
|
||||
/// Request the relevant dispute statements for a set of disputes identified by `CandidateHash` and the `SessionIndex`.
|
||||
/// Request the relevant dispute statements for a set of disputes identified by `CandidateHash` and
|
||||
/// the `SessionIndex`.
|
||||
async fn request_votes(
|
||||
sender: &mut impl overseer::ProvisionerSenderTrait,
|
||||
disputes_to_query: Vec<(SessionIndex, CandidateHash)>,
|
||||
|
||||
@@ -48,7 +48,8 @@ pub const MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME: usize = 200;
|
||||
/// Controls how much dispute votes to be fetched from the `dispute-coordinator` per iteration in
|
||||
/// `fn vote_selection`. The purpose is to fetch the votes in batches until
|
||||
/// `MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME` is reached. If all votes are fetched in single call
|
||||
/// we might fetch votes which we never use. This will create unnecessary load on `dispute-coordinator`.
|
||||
/// we might fetch votes which we never use. This will create unnecessary load on
|
||||
/// `dispute-coordinator`.
|
||||
///
|
||||
/// This value should be less than `MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME`. Increase it in case
|
||||
/// `provisioner` sends too many `QueryCandidateVotes` messages to `dispite-coordinator`.
|
||||
@@ -68,22 +69,23 @@ const VOTES_SELECTION_BATCH_SIZE: usize = 11;
|
||||
/// * Offchain vs Onchain
|
||||
/// * Concluded onchain vs Unconcluded onchain
|
||||
///
|
||||
/// Provisioner fetches all disputes from `dispute-coordinator` and separates them in multiple partitions.
|
||||
/// Please refer to `struct PartitionedDisputes` for details about the actual partitions.
|
||||
/// Each partition has got a priority implicitly assigned to it and the disputes are selected based on this
|
||||
/// priority (e.g. disputes in partition 1, then if there is space - disputes from partition 2 and so on).
|
||||
/// Provisioner fetches all disputes from `dispute-coordinator` and separates them in multiple
|
||||
/// partitions. Please refer to `struct PartitionedDisputes` for details about the actual
|
||||
/// partitions. Each partition has got a priority implicitly assigned to it and the disputes are
|
||||
/// selected based on this priority (e.g. disputes in partition 1, then if there is space - disputes
|
||||
/// from partition 2 and so on).
|
||||
///
|
||||
/// # Votes selection
|
||||
///
|
||||
/// Besides the prioritization described above the votes in each partition are filtered too. Provisioner
|
||||
/// fetches all onchain votes and filters them out from all partitions. As a result the Runtime receives
|
||||
/// only fresh votes (votes it didn't know about).
|
||||
/// Besides the prioritization described above the votes in each partition are filtered too.
|
||||
/// Provisioner fetches all onchain votes and filters them out from all partitions. As a result the
|
||||
/// Runtime receives only fresh votes (votes it didn't know about).
|
||||
///
|
||||
/// # How the onchain votes are fetched
|
||||
///
|
||||
/// The logic outlined above relies on `RuntimeApiRequest::Disputes` message from the Runtime. The user
|
||||
/// check the Runtime version before calling `select_disputes`. If the function is used with old runtime
|
||||
/// an error is logged and the logic will continue with empty onchain votes `HashMap`.
|
||||
/// The logic outlined above relies on `RuntimeApiRequest::Disputes` message from the Runtime. The
|
||||
/// user check the Runtime version before calling `select_disputes`. If the function is used with
|
||||
/// old runtime an error is logged and the logic will continue with empty onchain votes `HashMap`.
|
||||
pub async fn select_disputes<Sender>(
|
||||
sender: &mut Sender,
|
||||
metrics: &metrics::Metrics,
|
||||
@@ -110,7 +112,8 @@ where
|
||||
r
|
||||
},
|
||||
Err(GetOnchainDisputesError::NotSupported(runtime_api_err, relay_parent)) => {
|
||||
// Runtime version is checked before calling this method, so the error below should never happen!
|
||||
// Runtime version is checked before calling this method, so the error below should
|
||||
// never happen!
|
||||
gum::error!(
|
||||
target: LOG_TARGET,
|
||||
?runtime_api_err,
|
||||
@@ -152,7 +155,8 @@ where
|
||||
gum::trace!(target: LOG_TARGET, ?leaf, "Filtering recent disputes");
|
||||
|
||||
// Filter out unconfirmed disputes. However if the dispute is already onchain - don't skip it.
|
||||
// In this case we'd better push as much fresh votes as possible to bring it to conclusion faster.
|
||||
// In this case we'd better push as much fresh votes as possible to bring it to conclusion
|
||||
// faster.
|
||||
let recent_disputes = recent_disputes
|
||||
.into_iter()
|
||||
.filter(|d| d.2.is_confirmed_concluded() || onchain.contains_key(&(d.0, d.1)))
|
||||
@@ -178,9 +182,9 @@ where
|
||||
make_multi_dispute_statement_set(metrics, result)
|
||||
}
|
||||
|
||||
/// Selects dispute votes from `PartitionedDisputes` which should be sent to the runtime. Votes which
|
||||
/// are already onchain are filtered out. Result should be sorted by `(SessionIndex, CandidateHash)`
|
||||
/// which is enforced by the `BTreeMap`. This is a requirement from the runtime.
|
||||
/// Selects dispute votes from `PartitionedDisputes` which should be sent to the runtime. Votes
|
||||
/// which are already onchain are filtered out. Result should be sorted by `(SessionIndex,
|
||||
/// CandidateHash)` which is enforced by the `BTreeMap`. This is a requirement from the runtime.
|
||||
async fn vote_selection<Sender>(
|
||||
sender: &mut Sender,
|
||||
partitioned: PartitionedDisputes,
|
||||
@@ -237,9 +241,9 @@ where
|
||||
for (session_index, candidate_hash, selected_votes) in votes {
|
||||
let votes_len = selected_votes.valid.raw().len() + selected_votes.invalid.len();
|
||||
if votes_len + total_votes_len > MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME {
|
||||
// we are done - no more votes can be added. Importantly, we don't add any votes for a dispute here
|
||||
// if we can't fit them all. This gives us an important invariant, that backing votes for
|
||||
// disputes make it into the provisioned vote set.
|
||||
// we are done - no more votes can be added. Importantly, we don't add any votes for
|
||||
// a dispute here if we can't fit them all. This gives us an important invariant,
|
||||
// that backing votes for disputes make it into the provisioned vote set.
|
||||
gum::trace!(
|
||||
target: LOG_TARGET,
|
||||
?request_votes_counter,
|
||||
@@ -483,7 +487,8 @@ fn make_multi_dispute_statement_set(
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Gets the on-chain disputes at a given block number and returns them as a `HashMap` so that searching in them is cheap.
|
||||
/// Gets the on-chain disputes at a given block number and returns them as a `HashMap` so that
|
||||
/// searching in them is cheap.
|
||||
pub async fn get_onchain_disputes<Sender>(
|
||||
sender: &mut Sender,
|
||||
relay_parent: Hash,
|
||||
|
||||
@@ -237,21 +237,22 @@ fn partitioning_happy_case() {
|
||||
);
|
||||
}
|
||||
|
||||
// This test verifies the double voting behavior. Currently we don't care if a supermajority is achieved with or
|
||||
// without the 'help' of a double vote (a validator voting for and against at the same time). This makes the test
|
||||
// a bit pointless but anyway I'm leaving it here to make this decision explicit and have the test code ready in
|
||||
// case this behavior needs to be further tested in the future.
|
||||
// Link to the PR with the discussions: https://github.com/paritytech/polkadot/pull/5567
|
||||
// This test verifies the double voting behavior. Currently we don't care if a supermajority is
|
||||
// achieved with or without the 'help' of a double vote (a validator voting for and against at the
|
||||
// same time). This makes the test a bit pointless but anyway I'm leaving it here to make this
|
||||
// decision explicit and have the test code ready in case this behavior needs to be further tested
|
||||
// in the future. Link to the PR with the discussions: https://github.com/paritytech/polkadot/pull/5567
|
||||
#[test]
|
||||
fn partitioning_doubled_onchain_vote() {
|
||||
let mut input = Vec::<(SessionIndex, CandidateHash, DisputeStatus)>::new();
|
||||
let mut onchain = HashMap::<(u32, CandidateHash), DisputeState>::new();
|
||||
|
||||
// Dispute A relies on a 'double onchain vote' to conclude. Validator with index 0 has voted both `for` and `against`.
|
||||
// Despite that this dispute should be considered 'can conclude onchain'.
|
||||
// Dispute A relies on a 'double onchain vote' to conclude. Validator with index 0 has voted
|
||||
// both `for` and `against`. Despite that this dispute should be considered 'can conclude
|
||||
// onchain'.
|
||||
let dispute_a = (3, CandidateHash(Hash::random()), DisputeStatus::Active);
|
||||
// Dispute B has supermajority + 1 votes, so the doubled onchain vote doesn't affect it. It should be considered
|
||||
// as 'can conclude onchain'.
|
||||
// Dispute B has supermajority + 1 votes, so the doubled onchain vote doesn't affect it. It
|
||||
// should be considered as 'can conclude onchain'.
|
||||
let dispute_b = (4, CandidateHash(Hash::random()), DisputeStatus::Active);
|
||||
input.push(dispute_a.clone());
|
||||
input.push(dispute_b.clone());
|
||||
|
||||
@@ -81,7 +81,8 @@ pub enum Error {
|
||||
OverseerExited(SubsystemError),
|
||||
}
|
||||
|
||||
/// Used by `get_onchain_disputes` to represent errors related to fetching on-chain disputes from the Runtime
|
||||
/// Used by `get_onchain_disputes` to represent errors related to fetching on-chain disputes from
|
||||
/// the Runtime
|
||||
#[allow(dead_code)] // Remove when promoting to stable
|
||||
#[fatality::fatality]
|
||||
pub enum GetOnchainDisputesError {
|
||||
|
||||
@@ -466,11 +466,11 @@ async fn send_inherent_data(
|
||||
/// - not more than one per validator
|
||||
/// - each 1 bit must correspond to an occupied core
|
||||
///
|
||||
/// If we have too many, an arbitrary selection policy is fine. For purposes of maximizing availability,
|
||||
/// we pick the one with the greatest number of 1 bits.
|
||||
/// If we have too many, an arbitrary selection policy is fine. For purposes of maximizing
|
||||
/// availability, we pick the one with the greatest number of 1 bits.
|
||||
///
|
||||
/// Note: This does not enforce any sorting precondition on the output; the ordering there will be unrelated
|
||||
/// to the sorting of the input.
|
||||
/// Note: This does not enforce any sorting precondition on the output; the ordering there will be
|
||||
/// unrelated to the sorting of the input.
|
||||
fn select_availability_bitfields(
|
||||
cores: &[CoreState],
|
||||
bitfields: &[SignedAvailabilityBitfield],
|
||||
@@ -532,7 +532,8 @@ fn select_availability_bitfields(
|
||||
selected.into_values().collect()
|
||||
}
|
||||
|
||||
/// Determine which cores are free, and then to the degree possible, pick a candidate appropriate to each free core.
|
||||
/// Determine which cores are free, and then to the degree possible, pick a candidate appropriate to
|
||||
/// each free core.
|
||||
async fn select_candidates(
|
||||
availability_cores: &[CoreState],
|
||||
bitfields: &[SignedAvailabilityBitfield],
|
||||
@@ -593,7 +594,8 @@ async fn select_candidates(
|
||||
|
||||
let computed_validation_data_hash = validation_data.hash();
|
||||
|
||||
// we arbitrarily pick the first of the backed candidates which match the appropriate selection criteria
|
||||
// we arbitrarily pick the first of the backed candidates which match the appropriate
|
||||
// selection criteria
|
||||
if let Some(candidate) = candidates.iter().find(|backed_candidate| {
|
||||
let descriptor = &backed_candidate.descriptor;
|
||||
descriptor.para_id == scheduled_core.para_id &&
|
||||
@@ -628,12 +630,12 @@ async fn select_candidates(
|
||||
gum::trace!(target: LOG_TARGET, leaf_hash=?relay_parent,
|
||||
"Got {} backed candidates", candidates.len());
|
||||
|
||||
// `selected_candidates` is generated in ascending order by core index, and `GetBackedCandidates`
|
||||
// _should_ preserve that property, but let's just make sure.
|
||||
// `selected_candidates` is generated in ascending order by core index, and
|
||||
// `GetBackedCandidates` _should_ preserve that property, but let's just make sure.
|
||||
//
|
||||
// We can't easily map from `BackedCandidate` to `core_idx`, but we know that every selected candidate
|
||||
// maps to either 0 or 1 backed candidate, and the hashes correspond. Therefore, by checking them
|
||||
// in order, we can ensure that the backed candidates are also in order.
|
||||
// We can't easily map from `BackedCandidate` to `core_idx`, but we know that every selected
|
||||
// candidate maps to either 0 or 1 backed candidate, and the hashes correspond. Therefore, by
|
||||
// checking them in order, we can ensure that the backed candidates are also in order.
|
||||
let mut backed_idx = 0;
|
||||
for selected in selected_candidates {
|
||||
if selected ==
|
||||
@@ -705,8 +707,9 @@ fn bitfields_indicate_availability(
|
||||
let validator_idx = bitfield.validator_index().0 as usize;
|
||||
match availability.get_mut(validator_idx) {
|
||||
None => {
|
||||
// in principle, this function might return a `Result<bool, Error>` so that we can more clearly express this error condition
|
||||
// however, in practice, that would just push off an error-handling routine which would look a whole lot like this one.
|
||||
// in principle, this function might return a `Result<bool, Error>` so that we can
|
||||
// more clearly express this error condition however, in practice, that would just
|
||||
// push off an error-handling routine which would look a whole lot like this one.
|
||||
// simpler to just handle the error internally here.
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -726,8 +729,8 @@ fn bitfields_indicate_availability(
|
||||
3 * availability.count_ones() >= 2 * availability.len()
|
||||
}
|
||||
|
||||
// If we have to be absolutely precise here, this method gets the version of the `ParachainHost` api.
|
||||
// For brevity we'll just call it 'runtime version'.
|
||||
// If we have to be absolutely precise here, this method gets the version of the `ParachainHost`
|
||||
// api. For brevity we'll just call it 'runtime version'.
|
||||
async fn has_required_runtime(
|
||||
sender: &mut impl overseer::ProvisionerSenderTrait,
|
||||
relay_parent: Hash,
|
||||
|
||||
@@ -28,9 +28,10 @@ struct MetricsInner {
|
||||
/// Bitfields array length in `ProvisionerInherentData` (the result for `RequestInherentData`)
|
||||
inherent_data_response_bitfields: prometheus::Histogram,
|
||||
|
||||
/// The following metrics track how many disputes/votes the runtime will have to process. These will count
|
||||
/// all recent statements meaning every dispute from last sessions: 10 min on Rococo, 60 min on Kusama and
|
||||
/// 4 hours on Polkadot. The metrics are updated only when the node authors a block, so values vary across nodes.
|
||||
/// The following metrics track how many disputes/votes the runtime will have to process. These
|
||||
/// will count all recent statements meaning every dispute from last sessions: 10 min on
|
||||
/// Rococo, 60 min on Kusama and 4 hours on Polkadot. The metrics are updated only when the
|
||||
/// node authors a block, so values vary across nodes.
|
||||
inherent_data_dispute_statement_sets: prometheus::Counter<prometheus::U64>,
|
||||
inherent_data_dispute_statements: prometheus::CounterVec<prometheus::U64>,
|
||||
|
||||
|
||||
@@ -90,7 +90,8 @@ mod select_availability_bitfields {
|
||||
let cores = vec![occupied_core(0), occupied_core(1)];
|
||||
|
||||
// we pass in three bitfields with two validators
|
||||
// this helps us check the postcondition that we get two bitfields back, for which the validators differ
|
||||
// this helps us check the postcondition that we get two bitfields back, for which the
|
||||
// validators differ
|
||||
let bitfields = vec![
|
||||
signed_bitfield(&keystore, bitvec.clone(), ValidatorIndex(0)),
|
||||
signed_bitfield(&keystore, bitvec.clone(), ValidatorIndex(1)),
|
||||
|
||||
Reference in New Issue
Block a user