-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add thea client and pallet (#412)
- Loading branch information
1 parent
b9748fd
commit bd83fa6
Showing
30 changed files
with
7,262 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 = "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Thea Client |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | ||
} | ||
} |
Oops, something went wrong.