mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 10:31:04 +00:00
Malus: improvements in dispute ancestor and suggest garbage candidate implementation (#5011)
* Implement fake validation results Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * refactor Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * cargo lock Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * spell check Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * spellcheck Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * typos Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Review feedback Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * move stuff around Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * chores Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Impl valid - still wip Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fixes Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fmt Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Pull Ladi's implementation: https://github.com/paritytech/polkadot/pull/4711 Co-authored-by: Lldenaurois <Ljdenaurois@gmail.com> Co-authored-by: Andrei Sandu <andrei-mihail@parity.io> Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Fix build Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Logs and comments Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * WIP: suggest garbage candidate + implement validation result caching Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fix Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Do commitment hash checks in candidate validation Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Minor refactor in approval, backing, dispute-coord Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Working version of suggest garbage candidate Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Dedup Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * cleanup #1 Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Fix tests Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * remove debug leftovers Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fmt Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Accidentally commited some local test Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * spellcheck Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * some more fixes Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Refactor and fix it Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * review feedback Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * typo Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * tests review feedback Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * refactor disputer Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fix tests Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Fix zombienet disputes test Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * spellcheck Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fix Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Fix ui tests Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * fix typo Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> Co-authored-by: Lldenaurois <Ljdenaurois@gmail.com>
This commit is contained in:
@@ -31,8 +31,8 @@ use futures::{
|
||||
};
|
||||
|
||||
use polkadot_node_primitives::{
|
||||
AvailableData, PoV, SignedDisputeStatement, SignedFullStatement, Statement, ValidationResult,
|
||||
BACKING_EXECUTION_TIMEOUT,
|
||||
AvailableData, InvalidCandidate, PoV, SignedDisputeStatement, SignedFullStatement, Statement,
|
||||
ValidationResult, BACKING_EXECUTION_TIMEOUT,
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
self as util,
|
||||
@@ -41,8 +41,8 @@ use polkadot_node_subsystem_util::{
|
||||
request_validators, FromJobCommand, JobSender, Validator,
|
||||
};
|
||||
use polkadot_primitives::v2::{
|
||||
BackedCandidate, CandidateCommitments, CandidateDescriptor, CandidateHash, CandidateReceipt,
|
||||
CollatorId, CommittedCandidateReceipt, CoreIndex, CoreState, Hash, Id as ParaId, SessionIndex,
|
||||
BackedCandidate, CandidateCommitments, CandidateHash, CandidateReceipt, CollatorId,
|
||||
CommittedCandidateReceipt, CoreIndex, CoreState, Hash, Id as ParaId, SessionIndex,
|
||||
SigningContext, ValidatorId, ValidatorIndex, ValidatorSignature, ValidityAttestation,
|
||||
};
|
||||
use polkadot_subsystem::{
|
||||
@@ -378,14 +378,14 @@ async fn request_pov(
|
||||
|
||||
async fn request_candidate_validation(
|
||||
sender: &mut JobSender<impl SubsystemSender>,
|
||||
candidate: CandidateDescriptor,
|
||||
candidate_receipt: CandidateReceipt,
|
||||
pov: Arc<PoV>,
|
||||
) -> Result<ValidationResult, Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
sender
|
||||
.send_message(CandidateValidationMessage::ValidateFromChainState(
|
||||
candidate,
|
||||
candidate_receipt,
|
||||
pov,
|
||||
BACKING_EXECUTION_TIMEOUT,
|
||||
tx,
|
||||
@@ -456,11 +456,9 @@ async fn validate_and_make_available(
|
||||
.with_pov(&pov)
|
||||
.with_para_id(candidate.descriptor().para_id)
|
||||
});
|
||||
request_candidate_validation(&mut sender, candidate.descriptor.clone(), pov.clone()).await?
|
||||
request_candidate_validation(&mut sender, candidate.clone(), pov.clone()).await?
|
||||
};
|
||||
|
||||
let expected_commitments_hash = candidate.commitments_hash;
|
||||
|
||||
let res = match v {
|
||||
ValidationResult::Valid(commitments, validation_data) => {
|
||||
gum::debug!(
|
||||
@@ -469,41 +467,39 @@ async fn validate_and_make_available(
|
||||
"Validation successful",
|
||||
);
|
||||
|
||||
// If validation produces a new set of commitments, we vote the candidate as invalid.
|
||||
if commitments.hash() != expected_commitments_hash {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
candidate_hash = ?candidate.hash(),
|
||||
actual_commitments = ?commitments,
|
||||
"Commitments obtained with validation don't match the announced by the candidate receipt",
|
||||
);
|
||||
Err(candidate)
|
||||
} else {
|
||||
let erasure_valid = make_pov_available(
|
||||
&mut sender,
|
||||
n_validators,
|
||||
pov.clone(),
|
||||
candidate.hash(),
|
||||
validation_data,
|
||||
candidate.descriptor.erasure_root,
|
||||
span.as_ref(),
|
||||
)
|
||||
.await?;
|
||||
let erasure_valid = make_pov_available(
|
||||
&mut sender,
|
||||
n_validators,
|
||||
pov.clone(),
|
||||
candidate.hash(),
|
||||
validation_data,
|
||||
candidate.descriptor.erasure_root,
|
||||
span.as_ref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
match erasure_valid {
|
||||
Ok(()) => Ok((candidate, commitments, pov.clone())),
|
||||
Err(InvalidErasureRoot) => {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
candidate_hash = ?candidate.hash(),
|
||||
actual_commitments = ?commitments,
|
||||
"Erasure root doesn't match the announced by the candidate receipt",
|
||||
);
|
||||
Err(candidate)
|
||||
},
|
||||
}
|
||||
match erasure_valid {
|
||||
Ok(()) => Ok((candidate, commitments, pov.clone())),
|
||||
Err(InvalidErasureRoot) => {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
candidate_hash = ?candidate.hash(),
|
||||
actual_commitments = ?commitments,
|
||||
"Erasure root doesn't match the announced by the candidate receipt",
|
||||
);
|
||||
Err(candidate)
|
||||
},
|
||||
}
|
||||
},
|
||||
ValidationResult::Invalid(InvalidCandidate::CommitmentsHashMismatch) => {
|
||||
// If validation produces a new set of commitments, we vote the candidate as invalid.
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
candidate_hash = ?candidate.hash(),
|
||||
"Validation yielded different commitments",
|
||||
);
|
||||
Err(candidate)
|
||||
},
|
||||
ValidationResult::Invalid(reason) => {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -24,7 +24,8 @@ use futures::{future, Future};
|
||||
use polkadot_node_primitives::{BlockData, InvalidCandidate};
|
||||
use polkadot_node_subsystem_test_helpers as test_helpers;
|
||||
use polkadot_primitives::v2::{
|
||||
CollatorId, GroupRotationInfo, HeadData, PersistedValidationData, ScheduledCore,
|
||||
CandidateDescriptor, CollatorId, GroupRotationInfo, HeadData, PersistedValidationData,
|
||||
ScheduledCore,
|
||||
};
|
||||
use polkadot_subsystem::{
|
||||
messages::{
|
||||
@@ -332,12 +333,12 @@ fn backing_second_works() {
|
||||
virtual_overseer.recv().await,
|
||||
AllMessages::CandidateValidation(
|
||||
CandidateValidationMessage::ValidateFromChainState(
|
||||
c,
|
||||
candidate_receipt,
|
||||
pov,
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && &candidate_receipt.descriptor == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && candidate.commitments.hash() == candidate_receipt.commitments_hash => {
|
||||
tx.send(Ok(
|
||||
ValidationResult::Valid(CandidateCommitments {
|
||||
head_data: expected_head_data.clone(),
|
||||
@@ -419,6 +420,8 @@ fn backing_works() {
|
||||
.build();
|
||||
|
||||
let candidate_a_hash = candidate_a.hash();
|
||||
let candidate_a_commitments_hash = candidate_a.commitments.hash();
|
||||
|
||||
let public1 = CryptoStore::sr25519_generate_new(
|
||||
&*test_state.keystore,
|
||||
ValidatorId::ID,
|
||||
@@ -497,7 +500,7 @@ fn backing_works() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && c.commitments_hash == candidate_a_commitments_hash=> {
|
||||
tx.send(Ok(
|
||||
ValidationResult::Valid(CandidateCommitments {
|
||||
head_data: expected_head_data.clone(),
|
||||
@@ -594,6 +597,8 @@ fn backing_works_while_validation_ongoing() {
|
||||
.build();
|
||||
|
||||
let candidate_a_hash = candidate_a.hash();
|
||||
let candidate_a_commitments_hash = candidate_a.commitments.hash();
|
||||
|
||||
let public1 = CryptoStore::sr25519_generate_new(
|
||||
&*test_state.keystore,
|
||||
ValidatorId::ID,
|
||||
@@ -691,7 +696,7 @@ fn backing_works_while_validation_ongoing() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && candidate_a_commitments_hash == c.commitments_hash => {
|
||||
// we never validate the candidate. our local node
|
||||
// shouldn't issue any statements.
|
||||
std::mem::forget(tx);
|
||||
@@ -799,6 +804,8 @@ fn backing_misbehavior_works() {
|
||||
.build();
|
||||
|
||||
let candidate_a_hash = candidate_a.hash();
|
||||
let candidate_a_commitments_hash = candidate_a.commitments.hash();
|
||||
|
||||
let public2 = CryptoStore::sr25519_generate_new(
|
||||
&*test_state.keystore,
|
||||
ValidatorId::ID,
|
||||
@@ -865,7 +872,7 @@ fn backing_misbehavior_works() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && candidate_a_commitments_hash == c.commitments_hash => {
|
||||
tx.send(Ok(
|
||||
ValidationResult::Valid(CandidateCommitments {
|
||||
head_data: expected_head_data.clone(),
|
||||
@@ -1025,7 +1032,7 @@ fn backing_dont_second_invalid() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate_a.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap();
|
||||
}
|
||||
);
|
||||
@@ -1054,7 +1061,7 @@ fn backing_dont_second_invalid() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate_b.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate_b.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
tx.send(Ok(
|
||||
ValidationResult::Valid(CandidateCommitments {
|
||||
head_data: expected_head_data.clone(),
|
||||
@@ -1185,7 +1192,7 @@ fn backing_second_after_first_fails_works() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && c.commitments_hash == candidate.commitments.hash() => {
|
||||
tx.send(Ok(ValidationResult::Invalid(InvalidCandidate::BadReturn))).unwrap();
|
||||
}
|
||||
);
|
||||
@@ -1319,7 +1326,7 @@ fn backing_works_after_failed_validation() {
|
||||
timeout,
|
||||
tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT => {
|
||||
) if pov == pov && c.descriptor() == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && c.commitments_hash == candidate.commitments.hash() => {
|
||||
tx.send(Err(ValidationFailed("Internal test error".into()))).unwrap();
|
||||
}
|
||||
);
|
||||
@@ -1696,7 +1703,7 @@ fn retry_works() {
|
||||
timeout,
|
||||
_tx,
|
||||
)
|
||||
) if pov == pov && &c == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT
|
||||
) if pov == pov && c.descriptor() == candidate.descriptor() && timeout == BACKING_EXECUTION_TIMEOUT && c.commitments_hash == candidate.commitments.hash()
|
||||
);
|
||||
virtual_overseer
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user