Skip to content

Commit

Permalink
Tidy following app state change
Browse files Browse the repository at this point in the history
  • Loading branch information
ameba23 committed Dec 13, 2024
1 parent 542849e commit 15d3bbe
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 160 deletions.
17 changes: 6 additions & 11 deletions crates/threshold-signature-server/src/attestation/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use crate::{
attestation::errors::AttestationErr,
chain_api::{entropy, get_api, get_rpc, EntropyConfig},
get_signer_and_x25519_secret,
helpers::{
launch::LATEST_BLOCK_NUMBER_ATTEST,
substrate::{query_chain, submit_transaction},
Expand Down Expand Up @@ -46,8 +45,6 @@ pub async fn attest(
State(app_state): State<AppState>,
input: Bytes,
) -> Result<StatusCode, AttestationErr> {
let signer = app_state.signer;
let x25519_secret = app_state.x25519_secret;
let attestation_requests = OcwMessageAttestationRequest::decode(&mut input.as_ref())?;

let api = get_api(&app_state.configuration.endpoint).await?;
Expand All @@ -60,15 +57,15 @@ pub async fn attest(
validate_new_attestation(block_number, &attestation_requests, &app_state.kv_store).await?;

// Check whether there is an attestion request for us
if !attestation_requests.tss_account_ids.contains(&signer.signer().public().0) {
if !attestation_requests.tss_account_ids.contains(&app_state.signer.public().0) {
return Ok(StatusCode::OK);
}

// Get the input nonce for this attestation
// Also acts as chain check to make sure data is on chain
let nonce = {
let pending_attestation_query =
entropy::storage().attestation().pending_attestations(signer.account_id());
entropy::storage().attestation().pending_attestations(app_state.signer().account_id());
query_chain(&api, &rpc, pending_attestation_query, None)
.await?
.ok_or_else(|| AttestationErr::Unexpected)?
Expand All @@ -77,11 +74,11 @@ pub async fn attest(
// TODO (#1181): since this endpoint is currently only used in tests we don't know what the context should be
let context = QuoteContext::Validate;

let quote = create_quote(nonce, &signer, &x25519_secret, context).await?;
let quote = create_quote(nonce, &app_state.signer(), &app_state.x25519_secret, context).await?;

// Submit the quote
let attest_tx = entropy::tx().attestation().attest(quote.clone());
submit_transaction(&api, &rpc, &signer, &attest_tx, None).await?;
submit_transaction(&api, &rpc, &app_state.signer(), &attest_tx, None).await?;

Ok(StatusCode::OK)
}
Expand All @@ -95,17 +92,15 @@ pub async fn get_attest(
State(app_state): State<AppState>,
Query(context_querystring): Query<QuoteContextQuery>,
) -> Result<(StatusCode, Vec<u8>), AttestationErr> {
let signer = app_state.signer;
let x25519_secret = app_state.x25519_secret;
let api = get_api(&app_state.configuration.endpoint).await?;
let rpc = get_rpc(&app_state.configuration.endpoint).await?;

// Request attestation to get nonce
let nonce = request_attestation(&api, &rpc, signer.signer()).await?;
let nonce = request_attestation(&api, &rpc, &app_state.signer).await?;

let context = context_querystring.as_quote_context()?;

let quote = create_quote(nonce, &signer, &x25519_secret, context).await?;
let quote = create_quote(nonce, &app_state.signer(), &app_state.x25519_secret, context).await?;

Ok((StatusCode::OK, quote))
}
Expand Down
40 changes: 0 additions & 40 deletions crates/threshold-signature-server/src/helpers/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ use subxt::ext::sp_core::{
sr25519, Pair,
};

use crate::helpers::validator::get_signer_and_x25519_secret;

pub const DEFAULT_MNEMONIC: &str =
"alarm mutual concert decrease hurry invest culture survey diagram crash snap click";
pub const DEFAULT_BOB_MNEMONIC: &str =
Expand Down Expand Up @@ -236,44 +234,6 @@ pub fn development_mnemonic(validator_name: &Option<ValidatorName>) -> bip39::Mn
.expect("Unable to parse given mnemonic.")
}

// pub async fn setup_mnemonic(mnemonic: bip39::Mnemonic) -> (sr25519::Pair, StaticSecret) {
// let (pair, static_secret) =
// get_signer_and_x25519_secret(kv).await.expect("Cannot derive keypairs");
// let x25519_public_key = x25519_dalek::PublicKey::from(&static_secret).to_bytes();
//
// // Write the shared secret in the KVDB
// let shared_secret_reservation = kv
// .kv()
// .reserve_key(FORBIDDEN_KEY_SHARED_SECRET.to_string())
// .await
// .expect("Issue reserving ss key");
// kv.kv()
// .put(shared_secret_reservation, static_secret.to_bytes().to_vec())
// .await
// .expect("failed to update secret share");
//
// // Write the Diffie-Hellman key in the KVDB
// let diffie_hellman_reservation = kv
// .kv()
// .reserve_key(FORBIDDEN_KEY_DIFFIE_HELLMAN_PUBLIC.to_string())
// .await
// .expect("Issue reserving DH key");
//
// kv.kv()
// .put(diffie_hellman_reservation, x25519_public_key.to_vec())
// .await
// .expect("failed to update dh");
//
// // Now we write the TSS AccountID and X25519 public key to files for convenience reasons.
// let formatted_dh_public = format!("{x25519_public_key:?}").replace('"', "");
// fs::write(".entropy/public_key", formatted_dh_public).expect("Failed to write public key file");
//
// let id = AccountId32::new(pair.signer().public().0);
// fs::write(".entropy/account_id", format!("{id}")).expect("Failed to write account_id file");
//
// tracing::debug!("Starting process with account ID: `{id}`");
// }

pub async fn threshold_account_id(kv: &KvManager) -> String {
let mnemonic = kv.kv().get(FORBIDDEN_KEY_MNEMONIC).await.expect("Issue getting mnemonic");
let pair = <sr25519::Pair as Pair>::from_phrase(
Expand Down
4 changes: 1 addition & 3 deletions crates/threshold-signature-server/src/helpers/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use tokio::time::timeout;

use crate::{
chain_api::EntropyConfig,
get_signer_and_x25519_secret,
sign_init::SignInit,
signing_client::{
protocol_execution::{Channels, ThresholdSigningService},
Expand Down Expand Up @@ -54,9 +53,8 @@ pub async fn do_signing(

let info = SignInit::new(relayer_signature_request.clone(), signing_session_info.clone());
let signing_service = ThresholdSigningService::new(state, kv_manager);
let pair_signer = &app_state.signer;
let x25519_secret_key = &app_state.x25519_secret;
let signer = pair_signer.signer();
let signer = &app_state.signer;

let account_id = AccountId32(signer.public().0);

Expand Down
42 changes: 14 additions & 28 deletions crates/threshold-signature-server/src/helpers/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,39 @@

//! Utilites relating to [crate::validator]
use bip39::{Language, Mnemonic};
use entropy_kvdb::kv_manager::KvManager;
use hkdf::Hkdf;
use sha2::Sha256;
use subxt::{
ext::sp_core::{sr25519, Pair},
tx::PairSigner,
};
use subxt::ext::sp_core::{sr25519, Pair};
use x25519_dalek::StaticSecret;
use zeroize::Zeroize;

use crate::{chain_api::EntropyConfig, user::UserErr};
use crate::user::UserErr;

/// Constants used in the derivation path
const KDF_SR25519: &[u8] = b"sr25519-threshold-account";
const KDF_X25519: &[u8] = b"X25519-keypair";

/// Returns a PairSigner for this node's threshold server.
/// The PairSigner is stored as an encrypted mnemonic in the kvdb and
/// is used to sign encrypted messages and to submit extrinsics on chain.
pub async fn get_signer(
kv: &KvManager,
) -> Result<PairSigner<EntropyConfig, sr25519::Pair>, UserErr> {
let hkdf = get_hkdf(kv).await?;
get_signer_from_hkdf(&hkdf)
}
// Returns a PairSigner for this node's threshold server.
// The PairSigner is stored as an encrypted mnemonic in the kvdb and
// is used to sign encrypted messages and to submit extrinsics on chain.
// pub async fn get_signer(
// kv: &KvManager,
// ) -> Result<PairSigner<EntropyConfig, sr25519::Pair>, UserErr> {
// let hkdf = get_hkdf(kv).await?;
// get_signer_from_hkdf(&hkdf)
// }

/// Get the PairSigner as above, and also the x25519 encryption keypair for
/// this threshold server
pub fn get_signer_and_x25519_secret(
mnemonic: &str,
) -> Result<(PairSigner<EntropyConfig, sr25519::Pair>, StaticSecret), UserErr> {
) -> Result<(sr25519::Pair, StaticSecret), UserErr> {
let hkdf = get_hkdf_from_mnemonic(mnemonic)?;
let pair_signer = get_signer_from_hkdf(&hkdf)?;
let static_secret = get_x25519_secret_from_hkdf(&hkdf)?;
Ok((pair_signer, static_secret))
}

/// Get the key derivation struct to derive secret keys from a mnemonic stored in the KVDB
async fn get_hkdf(kv: &KvManager) -> Result<Hkdf<Sha256>, UserErr> {
let _ = kv.kv().exists("MNEMONIC").await?;
let raw_m = kv.kv().get("MNEMONIC").await?;
let secret = core::str::from_utf8(&raw_m)?;
get_hkdf_from_mnemonic(secret)
}

/// Given a mnemonic, setup hkdf
fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result<Hkdf<Sha256>, UserErr> {
let mnemonic = Mnemonic::parse_in_normalized(Language::English, mnemonic)
Expand All @@ -68,15 +56,13 @@ fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result<Hkdf<Sha256>, UserErr> {
}

/// Derive signing keypair
pub fn get_signer_from_hkdf(
hkdf: &Hkdf<Sha256>,
) -> Result<PairSigner<EntropyConfig, sr25519::Pair>, UserErr> {
pub fn get_signer_from_hkdf(hkdf: &Hkdf<Sha256>) -> Result<sr25519::Pair, UserErr> {
let mut sr25519_seed = [0u8; 32];
hkdf.expand(KDF_SR25519, &mut sr25519_seed)?;
let pair = sr25519::Pair::from_seed(&sr25519_seed);
sr25519_seed.zeroize();

Ok(PairSigner::<EntropyConfig, sr25519::Pair>::new(pair))
Ok(pair)
}

/// Derive x25519 secret
Expand Down
21 changes: 11 additions & 10 deletions crates/threshold-signature-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,7 @@ use tower_http::{
use tracing::Level;
use x25519_dalek::StaticSecret;

pub use crate::helpers::{
launch,
validator::{get_signer, get_signer_and_x25519_secret},
};
pub use crate::helpers::{launch, validator::get_signer_and_x25519_secret};
use crate::{
attestation::api::{attest, get_attest},
chain_api::EntropyConfig,
Expand All @@ -205,7 +202,7 @@ use crate::{
#[derive(Clone)]
pub struct AppState {
listener_state: ListenerState,
signer: PairSigner<EntropyConfig, sr25519::Pair>,
signer: sr25519::Pair,
x25519_secret: StaticSecret,
x25519_public_key: [u8; 32],
pub configuration: Configuration,
Expand All @@ -216,28 +213,32 @@ impl AppState {
pub fn new(
configuration: Configuration,
kv_store: KvManager,
validator_name: &ValidatorName,
validator_name: &Option<ValidatorName>,
) -> Self {
let (pair, x25519_secret) = if cfg!(test) || validator_name.is_some() {
get_signer_and_x25519_secret(development_mnemonic(&validator_name))
let (signer, x25519_secret) = if cfg!(test) || validator_name.is_some() {
get_signer_and_x25519_secret(&development_mnemonic(&validator_name).to_string())
.unwrap()
} else {
let (pair, _seed) = sr25519::Pair::generate();
let x25519_secret = StaticSecret::random_from_rng(&mut OsRng);
(pair, x25519_secret)
};

let signer = PairSigner::<EntropyConfig, sr25519::Pair>::new(pair);
let x25519_public_key = x25519_dalek::PublicKey::from(&x25519_secret).to_bytes();

Self {
pair,
signer,
x25519_secret,
x25519_public_key,
listener_state: ListenerState::default(),
configuration,
kv_store,
}
}

pub fn signer(&self) -> PairSigner<EntropyConfig, sr25519::Pair> {
PairSigner::<EntropyConfig, sr25519::Pair>::new(self.signer.clone())
}
}

pub fn app(app_state: AppState) -> Router {
Expand Down
4 changes: 2 additions & 2 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, has_mnemonic, load_kv_store, setup_latest_block_number,
setup_mnemonic, setup_only, Configuration, StartupArgs, ValidatorName,
load_kv_store, setup_latest_block_number, setup_only, Configuration, StartupArgs,
ValidatorName,
},
AppState,
};
Expand Down
9 changes: 3 additions & 6 deletions crates/threshold-signature-server/src/node_info/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//
// 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::{get_signer_and_x25519_secret, node_info::errors::GetInfoError, AppState};
use crate::{node_info::errors::GetInfoError, AppState};
use axum::{extract::State, Json};
use entropy_shared::{types::HashingAlgorithm, X25519PublicKey};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -43,9 +43,6 @@ pub struct TssPublicKeys {
/// 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 }))
let tss_account = AccountId32(app_state.signer.public().0);
Ok(Json(TssPublicKeys { x25519_public_key: app_state.x25519_public_key, tss_account }))
}
11 changes: 4 additions & 7 deletions crates/threshold-signature-server/src/signing_client/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use crate::{
},
helpers::{
launch::LATEST_BLOCK_NUMBER_PROACTIVE_REFRESH, substrate::query_chain,
user::check_in_registration_group, validator::get_signer_and_x25519_secret,
user::check_in_registration_group,
},
signing_client::{
protocol_transport::{handle_socket, open_protocol_connections},
Expand All @@ -81,11 +81,8 @@ pub async fn proactive_refresh(
let ocw_data = OcwMessageProactiveRefresh::decode(&mut encoded_data.as_ref())?;
let api = get_api(&app_state.configuration.endpoint).await?;
let rpc = get_rpc(&app_state.configuration.endpoint).await?;
let (signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store)
.await
.map_err(|e| ProtocolErr::UserError(e.to_string()))?;

check_in_registration_group(&ocw_data.validators_info, signer.account_id())
check_in_registration_group(&ocw_data.validators_info, app_state.signer().account_id())
.map_err(|e| ProtocolErr::UserError(e.to_string()))?;
validate_proactive_refresh(&api, &rpc, &app_state.kv_store, &ocw_data).await?;

Expand All @@ -103,8 +100,8 @@ pub async fn proactive_refresh(

let (new_key_share, aux_info) = do_proactive_refresh(
&ocw_data.validators_info,
&signer,
&x25519_secret_key,
&app_state.signer(),
&app_state.x25519_secret,
&app_state.listener_state,
encoded_key,
deserialized_old_key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use tokio_tungstenite::connect_async;

use super::ProtocolErr;
use crate::{
get_signer_and_x25519_secret,
signing_client::{SessionId, SubscribeErr},
AppState, ListenerState, SUBSCRIBE_TIMEOUT_SECONDS,
};
Expand Down Expand Up @@ -114,12 +113,8 @@ pub async fn open_protocol_connections(

/// Handle an incoming websocket connection
pub async fn handle_socket(socket: WebSocket, app_state: AppState) -> Result<(), WsError> {
let (_signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store)
.await
.map_err(|_| WsError::SignerFromAppState)?;

let (mut encrypted_connection, serialized_signed_message) =
noise_handshake_responder(socket, &x25519_secret_key)
noise_handshake_responder(socket, &app_state.x25519_secret)
.await
.map_err(|e| WsError::EncryptedConnection(e.to_string()))?;

Expand Down
Loading

0 comments on commit 15d3bbe

Please sign in to comment.