From 5c65241fdb5dbd3cb9e114b99573a2badc3ed058 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Thu, 13 Jul 2023 18:31:04 +0200 Subject: [PATCH 1/5] Add dispute initiators to dispute info --- essentials/src/collector/mod.rs | 52 ++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/essentials/src/collector/mod.rs b/essentials/src/collector/mod.rs index 6f4f0ffc..7e31a0cc 100644 --- a/essentials/src/collector/mod.rs +++ b/essentials/src/collector/mod.rs @@ -19,13 +19,14 @@ mod ws; use crate::{ api::{ - subxt_wrapper::{RequestExecutor, SubxtWrapperError}, + subxt_wrapper::{InherentData, RequestExecutor, SubxtWrapperError}, ApiService, }, chain_events::{ decode_chain_event, ChainEvent, SubxtCandidateEvent, SubxtCandidateEventType, SubxtDispute, SubxtDisputeResult, }, chain_subscription::ChainSubscriptionEvent, + metadata::polkadot_primitives::DisputeStatement, storage::{RecordTime, RecordsStorageConfig, StorageEntry}, types::{Timestamp, H256}, utils::RetryOptions, @@ -112,6 +113,7 @@ pub type CollectorStorageApi = ApiService; #[derive(Clone, Debug, Encode, Decode)] pub struct DisputeInfo { pub initiated: ::Index, + pub initiators_idx: Vec, pub dispute: SubxtDispute, pub parachain_id: u32, pub outcome: Option, @@ -541,7 +543,17 @@ impl Collector { self.state.current_session_index = cur_session; self.broadcast_event(CollectorUpdateEvent::NewSession(cur_session)).await?; } + self.write_parainherent_data(block_hash, block_number, ts).await?; + Ok(()) + } + + async fn write_parainherent_data( + &mut self, + block_hash: H256, + block_number: u32, + ts: Timestamp, + ) -> color_eyre::Result<(), CollectorError> { let inherent_data = self .executor .extract_parainherent_data(self.endpoint.as_str(), Some(block_hash)) @@ -767,6 +779,7 @@ impl Collector { let now = get_unix_time_unwrap(); let para_id = candidate.parachain_id(); candidate.candidate_disputed = Some(CandidateDisputed { disputed: relay_block_number, concluded: None }); + let initiators_idx = self.extract_dispute_initiators(dispute_event).await?; if let Some(to_websocket) = self.to_websocket.as_mut() { to_websocket .send(WebSocketUpdateEvent { @@ -781,7 +794,8 @@ impl Collector { // Fill and write dispute info structure let dispute_info = DisputeInfo { dispute: dispute_event.clone(), - initiated: self.state.current_relay_chain_block_number, + initiated: relay_block_number, + initiators_idx, concluded: None, parachain_id: candidate.parachain_id(), outcome: None, @@ -796,10 +810,7 @@ impl Collector { self.storage_write_prefixed( CollectorPrefixType::Dispute(para_id), dispute_event.candidate_hash, - StorageEntry::new_onchain( - RecordTime::with_ts(self.state.current_relay_chain_block_number, now), - dispute_info, - ), + StorageEntry::new_onchain(RecordTime::with_ts(relay_block_number, now), dispute_info), ) .await?; @@ -807,13 +818,40 @@ impl Collector { self.storage_replace_prefixed( CollectorPrefixType::Candidate(para_id), dispute_event.candidate_hash, - StorageEntry::new_onchain(RecordTime::with_ts(self.state.current_relay_chain_block_number, now), candidate), + StorageEntry::new_onchain(RecordTime::with_ts(relay_block_number, now), candidate), ) .await; Ok(()) } + async fn extract_dispute_initiators(&mut self, dispute_event: &SubxtDispute) -> color_eyre::Result> { + let entry = match self + .storage_read_prefixed(CollectorPrefixType::InherentData, dispute_event.relay_parent_block) + .await + { + Some(v) => v, + None => return Ok(vec![]), + }; + + let data: InherentData = entry.into_inner()?; + let statement_set = match data + .disputes + .iter() + .find(|&d| d.candidate_hash.0 == dispute_event.candidate_hash) + { + Some(v) => v, + None => return Ok(vec![]), + }; + + Ok(statement_set + .statements + .iter() + .filter(|(statement, _, _)| matches!(statement, DisputeStatement::Invalid(_))) + .map(|(_, idx, _)| idx.0) + .collect()) + } + async fn process_dispute_concluded( &mut self, dispute_event: &SubxtDispute, From 6e426f9111a96fe0c88415115e190f223c7e35da Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Fri, 14 Jul 2023 10:52:38 +0200 Subject: [PATCH 2/5] Add sessin index to dispute info --- essentials/src/collector/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/essentials/src/collector/mod.rs b/essentials/src/collector/mod.rs index 7e31a0cc..3d36ea0d 100644 --- a/essentials/src/collector/mod.rs +++ b/essentials/src/collector/mod.rs @@ -113,7 +113,8 @@ pub type CollectorStorageApi = ApiService; #[derive(Clone, Debug, Encode, Decode)] pub struct DisputeInfo { pub initiated: ::Index, - pub initiators_idx: Vec, + pub initiator_indices: Vec, + pub session_index: u32, pub dispute: SubxtDispute, pub parachain_id: u32, pub outcome: Option, @@ -779,7 +780,7 @@ impl Collector { let now = get_unix_time_unwrap(); let para_id = candidate.parachain_id(); candidate.candidate_disputed = Some(CandidateDisputed { disputed: relay_block_number, concluded: None }); - let initiators_idx = self.extract_dispute_initiators(dispute_event).await?; + let initiator_indices = self.extract_dispute_initiators(dispute_event).await?; if let Some(to_websocket) = self.to_websocket.as_mut() { to_websocket .send(WebSocketUpdateEvent { @@ -795,7 +796,8 @@ impl Collector { let dispute_info = DisputeInfo { dispute: dispute_event.clone(), initiated: relay_block_number, - initiators_idx, + initiator_indices, + session_index: self.state.current_session_index, concluded: None, parachain_id: candidate.parachain_id(), outcome: None, From 2fce4629a5947736f910e41c5f278e98d148fec4 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Fri, 14 Jul 2023 11:46:30 +0200 Subject: [PATCH 3/5] Show dispute initiators --- parachain-tracer/src/progress.rs | 10 ++++++++++ parachain-tracer/src/tracker.rs | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/parachain-tracer/src/progress.rs b/parachain-tracer/src/progress.rs index 6e4fc578..5f7841cf 100644 --- a/parachain-tracer/src/progress.rs +++ b/parachain-tracer/src/progress.rs @@ -245,6 +245,16 @@ impl Display for DisputesTracker { }, } + if !self.initiators.is_empty() { + for (validator_idx, validator_address) in &self.initiators { + writeln!( + f, + "\t\t\tšŸš€ Validator initiated dispute: {}", + format!("idx: {}, address: {}", validator_idx, validator_address).magenta(), + )?; + } + } + if !self.misbehaving_validators.is_empty() { for (validator_idx, validator_address) in &self.misbehaving_validators { writeln!( diff --git a/parachain-tracer/src/tracker.rs b/parachain-tracer/src/tracker.rs index 0386a787..2c048c32 100644 --- a/parachain-tracer/src/tracker.rs +++ b/parachain-tracer/src/tracker.rs @@ -73,6 +73,8 @@ pub struct DisputesTracker { pub voted_for: u32, /// Number of validators voted that a candidate is invalid pub voted_against: u32, + /// A vector of validators initiateds the dispute (index + identify) + pub initiators: Vec<(u32, String)>, /// A vector of validators voted against supermajority (index + identify) pub misbehaving_validators: Vec<(u32, String)>, /// Dispute conclusion time: how many blocks have passed since DisputeInitiated event @@ -581,11 +583,24 @@ impl SubxtTracker { .map(|(_, idx, _)| extract_validator_address(session_info.as_ref(), idx.0)) .collect() }; + + let initiators_session_info = if session_index == stored_dispute.session_index { + session_info + } else { + self.get_session_keys(stored_dispute.session_index).await + }; + let initiators: Vec<_> = stored_dispute + .initiator_indices + .iter() + .map(|idx| extract_validator_address(initiators_session_info.as_ref(), *idx)) + .collect(); + self.disputes.push(DisputesTracker { candidate: dispute_info.candidate_hash.0, voted_for, voted_against, outcome, + initiators, misbehaving_validators, resolve_time: Some( stored_dispute From 8d7388f2634b68cf1446e202239e2b307fa6800e Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Fri, 14 Jul 2023 12:05:08 +0200 Subject: [PATCH 4/5] Read dispute session index from its statement --- essentials/src/collector/mod.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/essentials/src/collector/mod.rs b/essentials/src/collector/mod.rs index 3d36ea0d..0defbe4e 100644 --- a/essentials/src/collector/mod.rs +++ b/essentials/src/collector/mod.rs @@ -780,7 +780,7 @@ impl Collector { let now = get_unix_time_unwrap(); let para_id = candidate.parachain_id(); candidate.candidate_disputed = Some(CandidateDisputed { disputed: relay_block_number, concluded: None }); - let initiator_indices = self.extract_dispute_initiators(dispute_event).await?; + let (initiator_indices, session_index) = self.extract_dispute_initiators(dispute_event).await?; if let Some(to_websocket) = self.to_websocket.as_mut() { to_websocket .send(WebSocketUpdateEvent { @@ -797,7 +797,7 @@ impl Collector { dispute: dispute_event.clone(), initiated: relay_block_number, initiator_indices, - session_index: self.state.current_session_index, + session_index, concluded: None, parachain_id: candidate.parachain_id(), outcome: None, @@ -827,13 +827,17 @@ impl Collector { Ok(()) } - async fn extract_dispute_initiators(&mut self, dispute_event: &SubxtDispute) -> color_eyre::Result> { + async fn extract_dispute_initiators( + &mut self, + dispute_event: &SubxtDispute, + ) -> color_eyre::Result<(Vec, u32)> { + let default_value = (vec![], self.state.current_session_index); let entry = match self .storage_read_prefixed(CollectorPrefixType::InherentData, dispute_event.relay_parent_block) .await { Some(v) => v, - None => return Ok(vec![]), + None => return Ok(default_value), }; let data: InherentData = entry.into_inner()?; @@ -843,15 +847,18 @@ impl Collector { .find(|&d| d.candidate_hash.0 == dispute_event.candidate_hash) { Some(v) => v, - None => return Ok(vec![]), + None => return Ok(default_value), }; - Ok(statement_set - .statements - .iter() - .filter(|(statement, _, _)| matches!(statement, DisputeStatement::Invalid(_))) - .map(|(_, idx, _)| idx.0) - .collect()) + Ok(( + statement_set + .statements + .iter() + .filter(|(statement, _, _)| matches!(statement, DisputeStatement::Invalid(_))) + .map(|(_, idx, _)| idx.0) + .collect(), + statement_set.session, + )) } async fn process_dispute_concluded( From 9bc829663a12da6997b9ab326376136c2d9bb2bb Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Fri, 14 Jul 2023 12:59:09 +0200 Subject: [PATCH 5/5] Update parachain-tracer/src/progress.rs Co-authored-by: ordian --- parachain-tracer/src/progress.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parachain-tracer/src/progress.rs b/parachain-tracer/src/progress.rs index 5f7841cf..cd7e7b49 100644 --- a/parachain-tracer/src/progress.rs +++ b/parachain-tracer/src/progress.rs @@ -249,7 +249,7 @@ impl Display for DisputesTracker { for (validator_idx, validator_address) in &self.initiators { writeln!( f, - "\t\t\tšŸš€ Validator initiated dispute: {}", + "\t\t\tšŸ˜  Validator initiated dispute: {}", format!("idx: {}, address: {}", validator_idx, validator_address).magenta(), )?; }