Skip to content

Commit

Permalink
fix: add thea client and pallet (#412)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfaisal committed May 27, 2022
1 parent b9748fd commit bd83fa6
Show file tree
Hide file tree
Showing 30 changed files with 7,262 additions and 0 deletions.
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

0 comments on commit bd83fa6

Please sign in to comment.