From 866aa1e8d433c087cfe776dd36386f82625c1f35 Mon Sep 17 00:00:00 2001
From: Andrei Eres <eresav@me.com>
Date: Fri, 23 Jun 2023 13:45:48 +0200
Subject: [PATCH] Warn if participated in the losing side of a dispute (#7404)

* Warn if participated in the losing side of a dispute

* Update naming

* Additionally filter by candidate hash

* Debug zombienet tests

* Update 0002-parachains-disputes.zndsl

* Debug zombienet

* Update node/core/dispute-coordinator/src/initialized.rs

Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com>

* Add checking to zombienet tests

---------

Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com>
---
 .../dispute-coordinator/src/initialized.rs    | 30 +++++++++++++++++++
 .../functional/0002-parachains-disputes.zndsl |  3 ++
 .../0003-parachains-garbage-candidate.zndsl   |  3 ++
 3 files changed, 36 insertions(+)

diff --git a/polkadot/node/core/dispute-coordinator/src/initialized.rs b/polkadot/node/core/dispute-coordinator/src/initialized.rs
index 7d64c91fb63..9efd4794679 100644
--- a/polkadot/node/core/dispute-coordinator/src/initialized.rs
+++ b/polkadot/node/core/dispute-coordinator/src/initialized.rs
@@ -1003,6 +1003,16 @@ impl Initialized {
 
 		gum::trace!(target: LOG_TARGET, ?candidate_hash, ?session, "Loaded votes");
 
+		let controlled_indices = env.controlled_indices();
+		let own_statements = statements
+			.iter()
+			.filter(|(statement, validator_index)| {
+				controlled_indices.contains(validator_index) &&
+					*statement.candidate_hash() == candidate_hash
+			})
+			.cloned()
+			.collect::<Vec<_>>();
+
 		let import_result = {
 			let intermediate_result = old_state.import_statements(&env, statements, now);
 
@@ -1307,6 +1317,16 @@ impl Initialized {
 				session,
 				"Dispute on candidate concluded with 'valid' result",
 			);
+			for (statement, validator_index) in own_statements.iter() {
+				if statement.statement().indicates_invalidity() {
+					gum::warn!(
+						target: LOG_TARGET,
+						?candidate_hash,
+						?validator_index,
+						"Voted against a candidate that was concluded valid.",
+					);
+				}
+			}
 			self.metrics.on_concluded_valid();
 		}
 		if import_result.is_freshly_concluded_against() {
@@ -1316,6 +1336,16 @@ impl Initialized {
 				session,
 				"Dispute on candidate concluded with 'invalid' result",
 			);
+			for (statement, validator_index) in own_statements.iter() {
+				if statement.statement().indicates_validity() {
+					gum::warn!(
+						target: LOG_TARGET,
+						?candidate_hash,
+						?validator_index,
+						"Voted for a candidate that was concluded invalid.",
+					);
+				}
+			}
 			self.metrics.on_concluded_invalid();
 		}
 
diff --git a/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl b/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl
index e17ac79399f..31f2b372f89 100644
--- a/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl
+++ b/polkadot/zombienet_tests/functional/0002-parachains-disputes.zndsl
@@ -53,3 +53,6 @@ ferdie: reports polkadot_parachain_disputes_finality_lag is 0
 eve: reports polkadot_parachain_disputes_finality_lag is 0
 one: reports polkadot_parachain_disputes_finality_lag is 0
 two: reports polkadot_parachain_disputes_finality_lag is 0
+
+# Check participating in the losing side of a dispute logged
+alice: log line contains "Voted against a candidate that was concluded valid." within 180 seconds
diff --git a/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl b/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl
index c4b2dbf20a1..ccc1ea258f5 100644
--- a/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl
+++ b/polkadot/zombienet_tests/functional/0003-parachains-garbage-candidate.zndsl
@@ -39,3 +39,6 @@ honest-validator-2: reports parachain_candidate_disputes_total is at least 2 wit
 # Disputes should always end as "invalid"
 honest-validator-0: reports parachain_candidate_dispute_concluded{validity="invalid"} is at least 2 within 15 seconds
 honest-validator-1: reports parachain_candidate_dispute_concluded{validity="valid"} is 0 within 15 seconds
+
+# Check participating in the losing side of a dispute logged
+malus-validator: log line contains "Voted for a candidate that was concluded invalid." within 180 seconds
-- 
GitLab