Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add thea to mainnet #412

Merged
merged 1 commit into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions client/thea/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[package]
name = "thea-client"
version = "0.1.0"
edition = "2021"
build ="build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
futures = "0.3"
hex = "0.4"
log = "0.4"
parking_lot = "0.11"
thiserror = "1.0"

codec = { version = "3.0.0", package = "parity-scale-codec", features = ["derive"] }
prometheus = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch ="polkadot-v0.9.19" }
frame-support = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-io = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-api = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-application-crypto = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-arithmetic = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-blockchain = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-consensus = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-core = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate', features = ["full_crypto"] }
sp-keystore = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-runtime = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-inherents = { branch="polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate'}
sc-client-api = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sc-keystore = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }

multi-party-ecdsa = { git = "https://github.com/ZenGo-X/multi-party-ecdsa.git", branch = "master"}
curv = { package = "curv-kzen", version = "0.9", default-features = false }
round-based = { version = "0.1.0", features = [] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.64"
thea-primitives = { path = "../../primitives/thea" }
rand = "0.8.4"
lazy_static = "1.4.0"
async-trait = { version = "0.1.50"}
#libsecp256k1 = { version = "0.7", default-features = false }
secp256k1 = {version="0.22.1", features = ["recovery"]}

[dev-dependencies]
strum = { version = "0.21", features = ["derive"] }
sc-network = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sc-network-test = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sc-consensus = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sp-tracing = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.19", package = "sc-finality-grandpa" }
sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.19", package = "sp-finality-grandpa" }
thea-primitives = { path = "../../primitives/thea" }
serde = { version = "1", features = ["derive"] }
substrate-test-runtime-client = { branch = "polkadot-v0.9.19", git = 'https://github.com/paritytech/substrate' }
tokio = { version = "1.17.0" }
tempfile = "*"
1 change: 1 addition & 0 deletions client/thea/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Thea Client
24 changes: 24 additions & 0 deletions client/thea/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This file is part of Polkadex.

// Copyright (C) 2020-2022 Polkadex oü.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.

//! Benchmarking setup for pallet-thea

fn main() {
// Required for gmp to work in Apple M1 chips, brew install gmp
println!(r"cargo:rustc-link-search=/opt/homebrew/Cellar/gmp/6.2.1_1/lib");
}
20 changes: 20 additions & 0 deletions client/thea/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "thea-client-rpc"
version = "0.1.0"
edition = "2021"
authors = ["Polkadex Technology"]
license = "GPL-3.0"
description = "RPC for Thea client for substrate"

[dependencies]
serde = { version = "1.0.132", features = ["derive"] }
jsonrpc-core = "18.0.0"
jsonrpc-core-client = "18.0.0"
jsonrpc-derive = "18.0.0"
codec = { version = "2.2.0", package = "parity-scale-codec", features = ["derive"] }
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.19" }
sc-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.19" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.19" }
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.19" }
thea-client = { path = ".." }
thea-primitives = { path = "../../../primitives/thea" }
61 changes: 61 additions & 0 deletions client/thea/rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// This file is part of Polkadex.

// Copyright (C) 2020-2022 Polkadex oü.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.

use jsonrpc_core::Result as RpcResult;
use jsonrpc_derive::rpc;
use std::sync::{mpsc::Receiver, Arc, Mutex};
use thea_client::worker::RoundInfo;

#[rpc]
pub trait TheaRpcApi {
type Metadata;

#[rpc(name = "theaInfo")]
fn thea_info(&self) -> RpcResult<RoundInfo>;
}

pub struct TheaRpcApiHandler {
cache: Mutex<RoundInfo>,
// this wrapping is required by rpc boundaries
updater: Arc<Mutex<Receiver<RoundInfo>>>,
}

impl TheaRpcApiHandler {
pub fn new(updater: Arc<Mutex<Receiver<RoundInfo>>>) -> Self {
Self { updater, cache: Mutex::new(RoundInfo::default()) }
}
}

impl TheaRpcApi for TheaRpcApiHandler {
type Metadata = sc_rpc::Metadata;

fn thea_info(&self) -> RpcResult<RoundInfo> {
// read latest from the channel
if let Ok(upd_ref) = self.updater.lock() {
if let Ok(mut inner) = self.cache.lock() {
// exhausting sent updates if any to get latest state
while let Ok(update) = upd_ref.recv_timeout(std::time::Duration::from_millis(50)) {
*inner = update;
}
}
}

// send cached data
Ok(self.cache.lock().map_err(|_| jsonrpc_core::Error::internal_error())?.clone())
}
}
148 changes: 148 additions & 0 deletions client/thea/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// This file is part of Substrate.

// Copyright (C) 2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.

//! THEA gadget specific errors
//!
//! Used for THEA gadget interal error handling only

use log::error;
use multi_party_ecdsa::protocols::multi_party_ecdsa::gg_2020::state_machine::{
keygen::Error as StateMachineKeygenError,
sign::{Error as StateMachineOfflineStageError, SignError},
};
use round_based::IsCritical;
use sp_api::ApiError;
use std::{fmt::Debug, num::ParseIntError};
use thea_primitives::{SigningError, ValidatorSetId};

#[derive(Debug, thiserror::Error, PartialEq)]
pub enum Error {
#[error("Keystore error: {0}")]
Keystore(String),
#[error("Signature error: {0}")]
Signature(String),
#[error("UnableToFindAuthorityFromKeystore")]
UnableToFindAuthorityFromKeystore,
#[error("Round Not found error: {0}")]
RoundNotFound(ValidatorSetId),
#[error("Stage Not found")]
StageNotFound,
#[error("Local Party Not Initialized error")]
LocalPartyNotInitialized,
#[error("Offline Party Not Initialized error")]
OfflinePartyNotInitialized,
#[error("Attempted to Pick Output before protocol completion")]
ProtocolNotComplete,
#[error("Error in encoding/decoding: {0}")]
SerdeError(String),
#[error("No block in Queue with Unsigned Payload")]
NoBlockInQueue,
#[error("Critical StateMachine error")]
CriticalKeygenStateMachineError,
#[error("StateMachine error")]
StateKeygenMachineError,
#[error("Critical OfflineStage StateMachine error")]
CriticalOfflineStageStateMachineError,
#[error("OfflineStage StateMachine error")]
StateOfflineStageMachineError,
#[error("local key is not initialized yet")]
LocalKeyNotReady,
#[error("No Pending Payloads")]
NoPayloadPending,
#[error("Error calling runtime api: {0}")]
RuntimeApiError(String),
#[error("Thea Runtime Api Error: {0}")]
TheaRuntimeApiError(String),
#[error("Error during ECDSA Signature generation: {0}")]
ECDSASignatureError(String),
#[error("Unable to find signing session")]
UnableToFindSigningSession,
#[error("Integer overflow")]
IntegerOverflow,
#[error("Given vector/slice/btreeset overflows the bounded version's limit")]
BoundedVecOrSliceError,
#[error("Libsecp256k1 Error: {0}")]
Libsecp256k1error(String),
#[error("Error: {0}")]
Other(String),
}

impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Self {
Self::SerdeError(err.to_string())
}
}

impl From<StateMachineKeygenError> for Error {
fn from(err: StateMachineKeygenError) -> Self {
if err.is_critical() {
error!(target: "thea", "Critical State machine error: {:?}", err);
Self::CriticalKeygenStateMachineError
} else {
error!(target: "thea", " State machine error: {:?}", err);
Self::StateKeygenMachineError
}
}
}

impl From<()> for Error {
fn from(_x: ()) -> Self {
Self::BoundedVecOrSliceError
}
}

impl From<StateMachineOfflineStageError> for Error {
fn from(err: StateMachineOfflineStageError) -> Self {
if err.is_critical() {
error!(target: "thea", "Critical State machine error: {:?}", err);
Self::CriticalOfflineStageStateMachineError
} else {
error!(target: "thea", " State machine error: {:?}", err);
Self::StateOfflineStageMachineError
}
}
}

impl From<ApiError> for Error {
fn from(err: ApiError) -> Self {
Self::RuntimeApiError(err.to_string())
}
}
impl From<SigningError> for Error {
fn from(err: SigningError) -> Self {
Self::TheaRuntimeApiError(err.to_string())
}
}

impl From<SignError> for Error {
fn from(err: SignError) -> Self {
Self::ECDSASignatureError(err.to_string())
}
}

impl From<ParseIntError> for Error {
fn from(err: ParseIntError) -> Self {
Self::Other(err.to_string())
}
}

impl From<secp256k1::Error> for Error {
fn from(err: secp256k1::Error) -> Self {
Self::Libsecp256k1error(err.to_string())
}
}
Loading