1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2017-2022 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.

use crate::error::GetOnchainDisputesError;
use polkadot_node_subsystem::overseer;
use polkadot_primitives::v2::{CandidateHash, DisputeState, Hash, SessionIndex};
use std::collections::HashMap;

pub async fn get_onchain_disputes<Sender>(
	_sender: &mut Sender,
	_relay_parent: Hash,
) -> Result<HashMap<(SessionIndex, CandidateHash), DisputeState>, GetOnchainDisputesError>
where
	Sender: overseer::ProvisionerSenderTrait,
{
	let _onchain = Result::<
		HashMap<(SessionIndex, CandidateHash), DisputeState>,
		GetOnchainDisputesError,
	>::Ok(HashMap::new());
	#[cfg(feature = "staging-client")]
	let _onchain = self::staging_impl::get_onchain_disputes(_sender, _relay_parent).await;

	_onchain
}

// Merge this module with the outer (current one) when promoting to stable
#[cfg(feature = "staging-client")]
mod staging_impl {
	use super::*; // remove this when promoting to stable
	use crate::LOG_TARGET;
	use futures::channel::oneshot;
	use polkadot_node_subsystem::{
		errors::RuntimeApiError,
		messages::{RuntimeApiMessage, RuntimeApiRequest},
		SubsystemSender,
	};

	/// Gets the on-chain disputes at a given block number and returns them as a `HashSet` so that searching in them is cheap.
	pub async fn get_onchain_disputes(
		sender: &mut impl SubsystemSender<RuntimeApiMessage>,
		relay_parent: Hash,
	) -> Result<HashMap<(SessionIndex, CandidateHash), DisputeState>, GetOnchainDisputesError> {
		gum::trace!(target: LOG_TARGET, ?relay_parent, "Fetching on-chain disputes");
		let (tx, rx) = oneshot::channel();
		sender
			.send_message(
				RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::StagingDisputes(tx))
					.into(),
			)
			.await;

		rx.await
			.map_err(|_| GetOnchainDisputesError::Channel)
			.and_then(|res| {
				res.map_err(|e| match e {
					RuntimeApiError::Execution { .. } =>
						GetOnchainDisputesError::Execution(e, relay_parent),
					RuntimeApiError::NotSupported { .. } =>
						GetOnchainDisputesError::NotSupported(e, relay_parent),
				})
			})
			.map(|v| v.into_iter().map(|e| ((e.0, e.1), e.2)).collect())
	}
}