Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
ameba23 committed Dec 18, 2024
2 parents f1334e6 + 6fa0bef commit 172d2e0
Show file tree
Hide file tree
Showing 24 changed files with 400 additions and 72 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ At the moment this project **does not** adhere to
- In [#1153](https://github.com/entropyxyz/entropy-core/pull/1153/) the program runtime was updated to accept
multiple oracle inputs, this means any programs that were compiled and used need to be recompiled to the new
runtime
- In [#1128](https://github.com/entropyxyz/entropy-core/pull/1128) mnemonics can no longer be passed
in to `entropy-tss` via the `--mnemonic` command line argument, a file, or an environment variable.
Instead they are randomly generated internally and can be retrieved with the `/info` HTTP route.
- In [#1179](https://github.com/entropyxyz/entropy-core/pull/1179) the format of TDX Quote input data has
been changed.
- In [#1147](https://github.com/entropyxyz/entropy-core/pull/1147) a field is added to the
Expand All @@ -35,6 +38,8 @@ runtime
certificate chain.

### Added
- In [#1128](https://github.com/entropyxyz/entropy-core/pull/1128) an `/info` route was added to `entropy-tss`
which can be used to get the TSS account ID and x25519 public key.
- Protocol message versioning ([#1140](https://github.com/entropyxyz/entropy-core/pull/1140))
- CLI command to get oracle headings ([#1170](https://github.com/entropyxyz/entropy-core/pull/1170))
- Add TSS endpoint to get TDX quote ([#1173](https://github.com/entropyxyz/entropy-core/pull/1173))
Expand All @@ -43,6 +48,7 @@ runtime
- In ([#1209]()) a `production` feature flag was added to `entropy` which if enabled will use
non-mock verification of PCK certificate chains in TDX quotes, meaning TSS servers must be running
on TDX hardware
- On-chain unresponsiveness reporting [(#1215)](https://github.com/entropyxyz/entropy-core/pull/1215)

### Changed
- Use correct key rotation endpoint in OCW ([#1104](https://github.com/entropyxyz/entropy-core/pull/1104))
Expand Down
4 changes: 4 additions & 0 deletions Cargo.lock

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

Binary file modified crates/client/entropy_metadata.scale
Binary file not shown.
31 changes: 0 additions & 31 deletions crates/threshold-signature-server/src/helpers/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,37 +207,6 @@ pub struct StartupArgs {
/// Returns the AccountID and Diffie-Hellman Public Keys associated with this server.
#[arg(long = "setup-only")]
pub setup_only: bool,

/// The BIP-39 mnemonic (i.e seed phrase) to use for deriving the Threshold Signature Server
/// SR25519 account ID and the X25519 public key.
///
/// The SR25519 account is responsible for signing and submitting extrinsics to the Entropy
/// network.
///
/// The X25519 public key is used for encrypting/decrypting messages to other threshold
/// servers.
///
/// Note that this may keep a mnemonic in your shell history. If you would like to avoid this
/// use one of the alternative options, or tools like the 1Password CLI.
///
/// **Alternatives**: There are two other ways to supply the mnemonic to the TSS: the
/// `--mnemonic-file` flag and the `THRESHOLD_SERVER_MNEMONIC` environment variable.
///
/// **Warning**: Passing this flag will overwrite any existing mnemonic! If you would like to
/// use an existing mnemonic omit this flag when running the process.
#[arg(long = "mnemonic")]
pub mnemonic: Option<bip39::Mnemonic>,

/// The path to a file containing the BIP-39 mnemonic (i.e seed phrase) to use for deriving the
/// Threshold Signature Server SR25519 account ID and the X25519 public key.
///
/// **Alternatives**: There are two other ways to supply the mnemonic to the TSS: the
/// `--mnemonic` flag and the `THRESHOLD_SERVER_MNEMONIC` environment variable.
///
/// **Warning**: Passing this flag will overwrite any existing mnemonic! If you would like to
/// use an existing mnemonic omit this flag when running the process.
#[arg(long = "mnemonic-file", conflicts_with = "mnemonic")]
pub mnemonic_file: Option<PathBuf>,
}

pub async fn has_mnemonic(kv: &KvManager) -> bool {
Expand Down
8 changes: 7 additions & 1 deletion crates/threshold-signature-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@
//! http://127.0.0.1:3001/user/sign_tx
//! ```
//!
//! ### For the node operator
//!
//! [`/info`](crate::node_info::api::info()) - Get - get a Json object of type
//! [crate::node_info::api::TssPublicKeys] which contains the TSS account ID and x25519 public key.
//!
//! ### For the blockchain node
//!
//! ### For other instances of the threshold server
Expand Down Expand Up @@ -185,7 +190,7 @@ use crate::{
attestation::api::{attest, get_attest},
health::api::healthz,
launch::Configuration,
node_info::api::{hashes, version as get_version},
node_info::api::{hashes, info, version as get_version},
r#unsafe::api::{delete, put, remove_keys, unsafe_get},
signing_client::{api::*, ListenerState},
user::api::*,
Expand Down Expand Up @@ -218,6 +223,7 @@ pub fn app(app_state: AppState) -> Router {
.route("/healthz", get(healthz))
.route("/version", get(get_version))
.route("/hashes", get(hashes))
.route("/info", get(info))
.route("/ws", get(ws_handler));

// Unsafe routes are for testing purposes only
Expand Down
43 changes: 9 additions & 34 deletions crates/threshold-signature-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use clap::Parser;
use entropy_tss::{
app,
launch::{
development_mnemonic, load_kv_store, setup_latest_block_number, setup_mnemonic, setup_only,
Configuration, StartupArgs, ValidatorName,
development_mnemonic, has_mnemonic, load_kv_store, setup_latest_block_number,
setup_mnemonic, setup_only, Configuration, StartupArgs, ValidatorName,
},
AppState,
};
Expand Down Expand Up @@ -66,39 +66,14 @@ async fn main() {

let app_state = AppState::new(configuration.clone(), kv_store.clone());

// We consider the inputs in order of most to least explicit: CLI flag, supplied file,
// environment variable.
let user_mnemonic = args
.mnemonic
.or_else(|| {
args.mnemonic_file.map(|path| {
let file = std::fs::read(path).expect("Unable to read mnemonic file.");
let mnemonic = std::str::from_utf8(&file)
.expect("Unable to convert provided mnemonic to UTF-8 string.")
.trim();

bip39::Mnemonic::parse_normalized(mnemonic)
.expect("Unable to parse given mnemonic.")
})
})
.or_else(|| {
std::env::var("THRESHOLD_SERVER_MNEMONIC").ok().map(|mnemonic| {
bip39::Mnemonic::parse_normalized(&mnemonic)
.expect("Unable to parse given mnemonic.")
})
});

if let Some(mnemonic) = user_mnemonic {
setup_mnemonic(&kv_store, mnemonic).await
} else if cfg!(test) || validator_name.is_some() {
if cfg!(test) || validator_name.is_some() {
setup_mnemonic(&kv_store, development_mnemonic(&validator_name)).await
} else {
let has_mnemonic = entropy_tss::launch::has_mnemonic(&kv_store).await;
assert!(
has_mnemonic,
"No mnemonic provided. Please provide one or use a development account."
);
};
} else if !has_mnemonic(&kv_store).await {
let mut rng = rand::thread_rng();
let mnemonic = bip39::Mnemonic::generate_in_with(&mut rng, bip39::Language::English, 24)
.expect("Failed to generate mnemonic");
setup_mnemonic(&kv_store, mnemonic).await
}

setup_latest_block_number(&kv_store).await.expect("Issue setting up Latest Block Number");

Expand Down
26 changes: 24 additions & 2 deletions crates/threshold-signature-server/src/node_info/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,40 @@
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use axum::Json;
use entropy_shared::types::HashingAlgorithm;
use crate::{get_signer_and_x25519_secret, node_info::errors::GetInfoError, AppState};
use axum::{extract::State, Json};
use entropy_shared::{types::HashingAlgorithm, X25519PublicKey};
use serde::{Deserialize, Serialize};
use sp_core::Pair;
use strum::IntoEnumIterator;
use subxt::utils::AccountId32;

/// Returns the version and commit data
#[tracing::instrument]
pub async fn version() -> String {
format!("{}-{}", env!("CARGO_PKG_VERSION"), env!("VERGEN_GIT_DESCRIBE"))
}

/// Lists the supported hashing algorithms
#[tracing::instrument]
pub async fn hashes() -> Json<Vec<HashingAlgorithm>> {
let hashing_algos = HashingAlgorithm::iter().collect::<Vec<_>>();
Json(hashing_algos)
}

/// Public signing and encryption keys associated with a TS server
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct TssPublicKeys {
pub tss_account: AccountId32,
pub x25519_public_key: X25519PublicKey,
}

/// Returns the TS server's public keys and HTTP endpoint
#[tracing::instrument(skip_all)]
pub async fn info(State(app_state): State<AppState>) -> Result<Json<TssPublicKeys>, GetInfoError> {
let (signer, x25519_secret) = get_signer_and_x25519_secret(&app_state.kv_store).await?;
let tss_account = AccountId32(signer.signer().public().0);
let x25519_public_key = *x25519_dalek::PublicKey::from(&x25519_secret).as_bytes();

Ok(Json(TssPublicKeys { x25519_public_key, tss_account }))
}
34 changes: 34 additions & 0 deletions crates/threshold-signature-server/src/node_info/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2023 Entropy Cryptography Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
};
use thiserror::Error;

/// Errors for protocol execution
#[derive(Debug, Error)]
pub enum GetInfoError {
#[error("Could not get public keys: {0}")]
User(#[from] crate::user::errors::UserErr),
}

impl IntoResponse for GetInfoError {
fn into_response(self) -> Response {
tracing::error!("{:?}", format!("{self}"));
let body = format!("{self}").into_bytes();
(StatusCode::INTERNAL_SERVER_ERROR, body).into_response()
}
}
1 change: 1 addition & 0 deletions crates/threshold-signature-server/src/node_info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

//! Provides information about this instance of `entropy-tss`
pub mod api;
mod errors;

#[cfg(test)]
mod tests;
25 changes: 24 additions & 1 deletion crates/threshold-signature-server/src/node_info/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::helpers::tests::{initialize_test_logger, setup_client};
use crate::{
helpers::tests::{initialize_test_logger, setup_client},
node_info::api::TssPublicKeys,
};
use entropy_kvdb::clean_tests;
use entropy_shared::types::HashingAlgorithm;
use entropy_testing_utils::constants::{TSS_ACCOUNTS, X25519_PUBLIC_KEYS};
use serial_test::serial;

#[tokio::test]
Expand Down Expand Up @@ -55,3 +59,22 @@ async fn hashes_test() {
);
clean_tests();
}

#[tokio::test]
#[serial]
async fn info_test() {
clean_tests();
initialize_test_logger().await;
setup_client().await;
let client = reqwest::Client::new();
let response = client.get("http://127.0.0.1:3001/info").send().await.unwrap();
let public_keys: TssPublicKeys = response.json().await.unwrap();
assert_eq!(
public_keys,
TssPublicKeys {
tss_account: TSS_ACCOUNTS[0].clone(),
x25519_public_key: X25519_PUBLIC_KEYS[0],
}
);
clean_tests();
}
2 changes: 2 additions & 0 deletions pallets/attestation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ tdx-quote={ git="https://github.com/entropyxyz/tdx-quote.git", branch="peg/cert-
] }
rand_core="0.6.4"

pallet-slashing={ version="0.3.0", path="../slashing", default-features=false }

[features]
default=['std']
runtime-benchmarks=['frame-benchmarking', 'tdx-quote/mock', 'pallet-session']
Expand Down
13 changes: 13 additions & 0 deletions pallets/attestation/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ frame_support::construct_runtime!(
Historical: pallet_session_historical,
BagsList: pallet_bags_list,
Parameters: pallet_parameters,
Slashing: pallet_slashing,
}
);

Expand Down Expand Up @@ -341,6 +342,18 @@ impl pallet_parameters::Config for Test {
type WeightInfo = ();
}

parameter_types! {
pub const ReportThreshold: u32 = 5;
}

impl pallet_slashing::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AuthorityId = UintAuthorityId;
type ReportThreshold = ReportThreshold;
type ValidatorSet = Historical;
type ReportUnresponsiveness = ();
}

// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
Expand Down
5 changes: 3 additions & 2 deletions pallets/propagation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ sp-staking ={ version="27.0.0", default-features=false }
entropy-shared={ version="0.3.0", path="../../crates/shared", default-features=false, features=[
"wasm-no-std",
] }
pallet-registry={ version="0.3.0", path="../registry", default-features=false }
pallet-attestation={ version="0.3.0", path="../attestation", default-features=false }
pallet-programs={ version="0.3.0", path="../programs", default-features=false }
pallet-registry={ version="0.3.0", path="../registry", default-features=false }
pallet-staking-extension={ version="0.3.0", path="../staking", default-features=false }
pallet-attestation={ version="0.3.0", path="../attestation", default-features=false }

[dev-dependencies]
parking_lot="0.12.3"
Expand All @@ -49,6 +49,7 @@ sp-keystore ={ version="0.35.0" }
sp-npos-elections ={ version="27.0.0", default-features=false }
pallet-parameters ={ version="0.3.0", path="../parameters", default-features=false }
pallet-oracle ={ version='0.3.0', path='../oracle', default-features=false }
pallet-slashing ={ version="0.3.0", path="../slashing", default-features=false }

[features]
default=['std']
Expand Down
13 changes: 13 additions & 0 deletions pallets/propagation/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ frame_support::construct_runtime!(
Parameters: pallet_parameters,
Attestation: pallet_attestation,
Oracle: pallet_oracle,
Slashing: pallet_slashing,
}
);

Expand Down Expand Up @@ -393,6 +394,18 @@ impl pallet_attestation::Config for Test {
type Randomness = TestPastRandomness;
}

parameter_types! {
pub const ReportThreshold: u32 = 5;
}

impl pallet_slashing::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AuthorityId = UintAuthorityId;
type ReportThreshold = ReportThreshold;
type ValidatorSet = Historical;
type ReportUnresponsiveness = ();
}

// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap();
Expand Down
1 change: 1 addition & 0 deletions pallets/registry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ sp-io ={ version="31.0.0", default-features=false }
sp-npos-elections ={ version="27.0.0", default-features=false }
sp-staking ={ version="27.0.0", default-features=false }
pallet-oracle ={ version='0.3.0', path='../oracle', default-features=false }
pallet-slashing ={ version="0.3.0", path="../slashing", default-features=false }

[features]

Expand Down
Loading

0 comments on commit 172d2e0

Please sign in to comment.