Skip to content
This repository was archived by the owner on Dec 1, 2025. It is now read-only.

Commit c37925e

Browse files
authored
Backport polkadot 7013 (#281)
* backport paritytech/polkadot#7013 * Bump node version to v0.1.24-3
1 parent e680cea commit c37925e

22 files changed

Lines changed: 10198 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ members = [
5656

5757
[patch."https://github.com/paritytech/polkadot"]
5858
polkadot-service = { path = "polkadot/node/service" }
59+
# TODO: Remove after upgrade to Polkdaot v0.9.42
60+
polkadot-node-core-dispute-coordinator = { path = "polkadot/node/core/dispute-coordinator" }
5961

6062
# TODO: Remove after upgrade to Polkdaot v0.9.42
6163
[patch."https://github.com/paritytech/cumulus"]

node/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "khala-node"
3-
version = "0.1.24-2"
3+
version = "0.1.24-3"
44
license = "Apache-2.0"
55
homepage = "https://phala.network/"
66
repository = "https://github.com/Phala-Network/khala-parachain"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
[package]
2+
name = "polkadot-node-core-dispute-coordinator"
3+
version = "0.9.41"
4+
authors = ["Parity Technologies <admin@parity.io>"]
5+
edition = "2021"
6+
7+
[dependencies]
8+
futures = "0.3.21"
9+
gum = { package = "tracing-gum", git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
10+
parity-scale-codec = "3.3.0"
11+
kvdb = "0.13.0"
12+
thiserror = "1.0.31"
13+
lru = "0.9.0"
14+
fatality = "0.0.6"
15+
16+
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
17+
polkadot-node-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
18+
polkadot-node-subsystem = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
19+
polkadot-node-subsystem-util = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
20+
21+
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
22+
23+
24+
[dev-dependencies]
25+
kvdb-memorydb = "0.13.0"
26+
polkadot-node-subsystem-test-helpers = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
27+
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
28+
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
29+
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
30+
assert_matches = "1.4.0"
31+
test-helpers = { package = "polkadot-primitives-test-helpers", git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
32+
futures-timer = "3.0.2"
33+
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
34+
sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
35+
36+
[features]
37+
# If not enabled, the dispute coordinator will do nothing.
38+
disputes = []
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Copyright 2020 Parity Technologies (UK) Ltd.
2+
// This file is part of Polkadot.
3+
4+
// Polkadot is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Polkadot is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//! An abstraction over storage used by the chain selection subsystem.
18+
//!
19+
//! This provides both a [`Backend`] trait and an [`OverlayedBackend`]
20+
//! struct which allows in-memory changes to be applied on top of a
21+
//! [`Backend`], maintaining consistency between queries and temporary writes,
22+
//! before any commit to the underlying storage is made.
23+
24+
use polkadot_primitives::{CandidateHash, SessionIndex};
25+
26+
use std::collections::HashMap;
27+
28+
use super::db::v1::{CandidateVotes, RecentDisputes};
29+
use crate::error::FatalResult;
30+
31+
#[derive(Debug)]
32+
pub enum BackendWriteOp {
33+
WriteEarliestSession(SessionIndex),
34+
WriteRecentDisputes(RecentDisputes),
35+
WriteCandidateVotes(SessionIndex, CandidateHash, CandidateVotes),
36+
DeleteCandidateVotes(SessionIndex, CandidateHash),
37+
}
38+
39+
/// An abstraction over backend storage for the logic of this subsystem.
40+
pub trait Backend {
41+
/// Load the earliest session, if any.
42+
fn load_earliest_session(&self) -> FatalResult<Option<SessionIndex>>;
43+
44+
/// Load the recent disputes, if any.
45+
fn load_recent_disputes(&self) -> FatalResult<Option<RecentDisputes>>;
46+
47+
/// Load the candidate votes for the specific session-candidate pair, if any.
48+
fn load_candidate_votes(
49+
&self,
50+
session: SessionIndex,
51+
candidate_hash: &CandidateHash,
52+
) -> FatalResult<Option<CandidateVotes>>;
53+
54+
/// Atomically writes the list of operations, with later operations taking precedence over
55+
/// prior.
56+
fn write<I>(&mut self, ops: I) -> FatalResult<()>
57+
where
58+
I: IntoIterator<Item = BackendWriteOp>;
59+
}
60+
61+
/// An in-memory overlay for the backend.
62+
///
63+
/// This maintains read-only access to the underlying backend, but can be converted into a set of
64+
/// write operations which will, when written to the underlying backend, give the same view as the
65+
/// state of the overlay.
66+
pub struct OverlayedBackend<'a, B: 'a> {
67+
inner: &'a B,
68+
69+
// `None` means unchanged.
70+
earliest_session: Option<SessionIndex>,
71+
// `None` means unchanged.
72+
recent_disputes: Option<RecentDisputes>,
73+
// `None` means deleted, missing means query inner.
74+
candidate_votes: HashMap<(SessionIndex, CandidateHash), Option<CandidateVotes>>,
75+
}
76+
77+
impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> {
78+
pub fn new(backend: &'a B) -> Self {
79+
Self {
80+
inner: backend,
81+
earliest_session: None,
82+
recent_disputes: None,
83+
candidate_votes: HashMap::new(),
84+
}
85+
}
86+
87+
/// Returns true if the are no write operations to perform.
88+
pub fn is_empty(&self) -> bool {
89+
self.earliest_session.is_none() &&
90+
self.recent_disputes.is_none() &&
91+
self.candidate_votes.is_empty()
92+
}
93+
94+
/// Load the earliest session, if any.
95+
pub fn load_earliest_session(&self) -> FatalResult<Option<SessionIndex>> {
96+
if let Some(val) = self.earliest_session {
97+
return Ok(Some(val))
98+
}
99+
100+
self.inner.load_earliest_session()
101+
}
102+
103+
/// Load the recent disputes, if any.
104+
pub fn load_recent_disputes(&self) -> FatalResult<Option<RecentDisputes>> {
105+
if let Some(val) = &self.recent_disputes {
106+
return Ok(Some(val.clone()))
107+
}
108+
109+
self.inner.load_recent_disputes()
110+
}
111+
112+
/// Load the candidate votes for the specific session-candidate pair, if any.
113+
pub fn load_candidate_votes(
114+
&self,
115+
session: SessionIndex,
116+
candidate_hash: &CandidateHash,
117+
) -> FatalResult<Option<CandidateVotes>> {
118+
if let Some(val) = self.candidate_votes.get(&(session, *candidate_hash)) {
119+
return Ok(val.clone())
120+
}
121+
122+
self.inner.load_candidate_votes(session, candidate_hash)
123+
}
124+
125+
/// Prepare a write to the "earliest session" field of the DB.
126+
///
127+
/// Later calls to this function will override earlier ones.
128+
pub fn write_earliest_session(&mut self, session: SessionIndex) {
129+
self.earliest_session = Some(session);
130+
}
131+
132+
/// Prepare a write to the recent disputes stored in the DB.
133+
///
134+
/// Later calls to this function will override earlier ones.
135+
pub fn write_recent_disputes(&mut self, recent_disputes: RecentDisputes) {
136+
self.recent_disputes = Some(recent_disputes)
137+
}
138+
139+
/// Prepare a write of the candidate votes under the indicated candidate.
140+
///
141+
/// Later calls to this function for the same candidate will override earlier ones.
142+
pub fn write_candidate_votes(
143+
&mut self,
144+
session: SessionIndex,
145+
candidate_hash: CandidateHash,
146+
votes: CandidateVotes,
147+
) {
148+
self.candidate_votes.insert((session, candidate_hash), Some(votes));
149+
}
150+
151+
/// Transform this backend into a set of write-ops to be written to the inner backend.
152+
pub fn into_write_ops(self) -> impl Iterator<Item = BackendWriteOp> {
153+
let earliest_session_ops = self
154+
.earliest_session
155+
.map(|s| BackendWriteOp::WriteEarliestSession(s))
156+
.into_iter();
157+
158+
let recent_dispute_ops =
159+
self.recent_disputes.map(|d| BackendWriteOp::WriteRecentDisputes(d)).into_iter();
160+
161+
let candidate_vote_ops =
162+
self.candidate_votes
163+
.into_iter()
164+
.map(|((session, candidate), votes)| match votes {
165+
Some(votes) => BackendWriteOp::WriteCandidateVotes(session, candidate, votes),
166+
None => BackendWriteOp::DeleteCandidateVotes(session, candidate),
167+
});
168+
169+
earliest_session_ops.chain(recent_dispute_ops).chain(candidate_vote_ops)
170+
}
171+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2020 Parity Technologies (UK) Ltd.
2+
// This file is part of Polkadot.
3+
4+
// Polkadot is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Polkadot is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//! Database component for the dispute coordinator.
18+
19+
pub(super) mod v1;

0 commit comments

Comments
 (0)