Skip to content

Commit

Permalink
Backport polkadot 7013 (#281)
Browse files Browse the repository at this point in the history
* backport paritytech/polkadot#7013

* Bump node version to v0.1.24-3
  • Loading branch information
jasl authored Apr 27, 2023
1 parent e680cea commit c37925e
Show file tree
Hide file tree
Showing 22 changed files with 10,198 additions and 3 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ members = [

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

# TODO: Remove after upgrade to Polkdaot v0.9.42
[patch."https://github.com/paritytech/cumulus"]
Expand Down
2 changes: 1 addition & 1 deletion node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "khala-node"
version = "0.1.24-2"
version = "0.1.24-3"
license = "Apache-2.0"
homepage = "https://phala.network/"
repository = "https://github.com/Phala-Network/khala-parachain"
Expand Down
38 changes: 38 additions & 0 deletions polkadot/node/core/dispute-coordinator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "polkadot-node-core-dispute-coordinator"
version = "0.9.41"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"

[dependencies]
futures = "0.3.21"
gum = { package = "tracing-gum", git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
parity-scale-codec = "3.3.0"
kvdb = "0.13.0"
thiserror = "1.0.31"
lru = "0.9.0"
fatality = "0.0.6"

polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
polkadot-node-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
polkadot-node-subsystem = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
polkadot-node-subsystem-util = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }

sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }


[dev-dependencies]
kvdb-memorydb = "0.13.0"
polkadot-node-subsystem-test-helpers = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
assert_matches = "1.4.0"
test-helpers = { package = "polkadot-primitives-test-helpers", git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.41" }
futures-timer = "3.0.2"
sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }
sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.41" }

[features]
# If not enabled, the dispute coordinator will do nothing.
disputes = []
171 changes: 171 additions & 0 deletions polkadot/node/core/dispute-coordinator/src/backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
// Copyright 2020 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/>.

//! An abstraction over storage used by the chain selection subsystem.
//!
//! This provides both a [`Backend`] trait and an [`OverlayedBackend`]
//! struct which allows in-memory changes to be applied on top of a
//! [`Backend`], maintaining consistency between queries and temporary writes,
//! before any commit to the underlying storage is made.
use polkadot_primitives::{CandidateHash, SessionIndex};

use std::collections::HashMap;

use super::db::v1::{CandidateVotes, RecentDisputes};
use crate::error::FatalResult;

#[derive(Debug)]
pub enum BackendWriteOp {
WriteEarliestSession(SessionIndex),
WriteRecentDisputes(RecentDisputes),
WriteCandidateVotes(SessionIndex, CandidateHash, CandidateVotes),
DeleteCandidateVotes(SessionIndex, CandidateHash),
}

/// An abstraction over backend storage for the logic of this subsystem.
pub trait Backend {
/// Load the earliest session, if any.
fn load_earliest_session(&self) -> FatalResult<Option<SessionIndex>>;

/// Load the recent disputes, if any.
fn load_recent_disputes(&self) -> FatalResult<Option<RecentDisputes>>;

/// Load the candidate votes for the specific session-candidate pair, if any.
fn load_candidate_votes(
&self,
session: SessionIndex,
candidate_hash: &CandidateHash,
) -> FatalResult<Option<CandidateVotes>>;

/// Atomically writes the list of operations, with later operations taking precedence over
/// prior.
fn write<I>(&mut self, ops: I) -> FatalResult<()>
where
I: IntoIterator<Item = BackendWriteOp>;
}

/// An in-memory overlay for the backend.
///
/// This maintains read-only access to the underlying backend, but can be converted into a set of
/// write operations which will, when written to the underlying backend, give the same view as the
/// state of the overlay.
pub struct OverlayedBackend<'a, B: 'a> {
inner: &'a B,

// `None` means unchanged.
earliest_session: Option<SessionIndex>,
// `None` means unchanged.
recent_disputes: Option<RecentDisputes>,
// `None` means deleted, missing means query inner.
candidate_votes: HashMap<(SessionIndex, CandidateHash), Option<CandidateVotes>>,
}

impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> {
pub fn new(backend: &'a B) -> Self {
Self {
inner: backend,
earliest_session: None,
recent_disputes: None,
candidate_votes: HashMap::new(),
}
}

/// Returns true if the are no write operations to perform.
pub fn is_empty(&self) -> bool {
self.earliest_session.is_none() &&
self.recent_disputes.is_none() &&
self.candidate_votes.is_empty()
}

/// Load the earliest session, if any.
pub fn load_earliest_session(&self) -> FatalResult<Option<SessionIndex>> {
if let Some(val) = self.earliest_session {
return Ok(Some(val))
}

self.inner.load_earliest_session()
}

/// Load the recent disputes, if any.
pub fn load_recent_disputes(&self) -> FatalResult<Option<RecentDisputes>> {
if let Some(val) = &self.recent_disputes {
return Ok(Some(val.clone()))
}

self.inner.load_recent_disputes()
}

/// Load the candidate votes for the specific session-candidate pair, if any.
pub fn load_candidate_votes(
&self,
session: SessionIndex,
candidate_hash: &CandidateHash,
) -> FatalResult<Option<CandidateVotes>> {
if let Some(val) = self.candidate_votes.get(&(session, *candidate_hash)) {
return Ok(val.clone())
}

self.inner.load_candidate_votes(session, candidate_hash)
}

/// Prepare a write to the "earliest session" field of the DB.
///
/// Later calls to this function will override earlier ones.
pub fn write_earliest_session(&mut self, session: SessionIndex) {
self.earliest_session = Some(session);
}

/// Prepare a write to the recent disputes stored in the DB.
///
/// Later calls to this function will override earlier ones.
pub fn write_recent_disputes(&mut self, recent_disputes: RecentDisputes) {
self.recent_disputes = Some(recent_disputes)
}

/// Prepare a write of the candidate votes under the indicated candidate.
///
/// Later calls to this function for the same candidate will override earlier ones.
pub fn write_candidate_votes(
&mut self,
session: SessionIndex,
candidate_hash: CandidateHash,
votes: CandidateVotes,
) {
self.candidate_votes.insert((session, candidate_hash), Some(votes));
}

/// Transform this backend into a set of write-ops to be written to the inner backend.
pub fn into_write_ops(self) -> impl Iterator<Item = BackendWriteOp> {
let earliest_session_ops = self
.earliest_session
.map(|s| BackendWriteOp::WriteEarliestSession(s))
.into_iter();

let recent_dispute_ops =
self.recent_disputes.map(|d| BackendWriteOp::WriteRecentDisputes(d)).into_iter();

let candidate_vote_ops =
self.candidate_votes
.into_iter()
.map(|((session, candidate), votes)| match votes {
Some(votes) => BackendWriteOp::WriteCandidateVotes(session, candidate, votes),
None => BackendWriteOp::DeleteCandidateVotes(session, candidate),
});

earliest_session_ops.chain(recent_dispute_ops).chain(candidate_vote_ops)
}
}
19 changes: 19 additions & 0 deletions polkadot/node/core/dispute-coordinator/src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2020 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/>.

//! Database component for the dispute coordinator.
pub(super) mod v1;
Loading

0 comments on commit c37925e

Please sign in to comment.