Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
ameba23 committed Dec 11, 2024
2 parents 8cad165 + 6d3351e commit b31180e
Show file tree
Hide file tree
Showing 15 changed files with 188 additions and 123 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ runtime
- 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))
- Add TDX test network chainspec ([#1204](https://github.com/entropyxyz/entropy-core/pull/1204))
- Test CLI command to retrieve quote and change endpoint / TSS account in one command ([#1198](https://github.com/entropyxyz/entropy-core/pull/1198))

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

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

2 changes: 1 addition & 1 deletion crates/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ serde ={ version="1.0", default-features=false, features=["derive"] }
entropy-shared={ version="0.3.0", path="../shared", default-features=false }
subxt ={ version="0.35.3", default-features=false, features=["jsonrpsee"] }
num ="0.4.3"
thiserror ="2.0.4"
thiserror ="2.0.6"
futures ="0.3"
sp-core ={ version="31.0.0", default-features=false, features=["full_crypto", "serde"] }
tracing ="0.1.41"
Expand Down
110 changes: 88 additions & 22 deletions crates/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@
//! Used in integration tests and for the test-cli
pub use crate::{
chain_api::{get_api, get_rpc},
errors::ClientError,
errors::{ClientError, SubstrateError},
};
use anyhow::anyhow;
pub use entropy_protocol::{sign_and_encrypt::EncryptedSignedMessage, KeyParams};
pub use entropy_shared::{HashingAlgorithm, QuoteContext};
use parity_scale_codec::Decode;
use rand::Rng;
use std::str::FromStr;
pub use synedrion::KeyShare;

use crate::{
Expand All @@ -39,7 +38,7 @@ use crate::{
EntropyConfig,
},
client::entropy::staking_extension::events::{EndpointChanged, ThresholdAccountChanged},
substrate::{get_registered_details, submit_transaction_with_pair},
substrate::{get_registered_details, query_chain, submit_transaction_with_pair},
user::{
self, get_all_signers_from_chain, get_validators_not_signer_for_relay, UserSignatureRequest,
},
Expand All @@ -48,7 +47,6 @@ use crate::{

use base64::prelude::{Engine, BASE64_STANDARD};
use entropy_protocol::RecoverableSignature;
use entropy_shared::HashingAlgorithm;
use futures::stream::StreamExt;
use sp_core::{
sr25519::{self, Signature},
Expand Down Expand Up @@ -338,50 +336,90 @@ pub async fn put_register_request_on_chain(
registered_event
}

/// Changes the endpoint of a validator
/// Changes the endpoint of a validator, retrieving a TDX quote from the new endpoint internally
pub async fn get_quote_and_change_endpoint(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
validator_keypair: sr25519::Pair,
new_endpoint: String,
) -> Result<EndpointChanged, ClientError> {
let quote = get_tdx_quote(&new_endpoint, QuoteContext::ChangeEndpoint).await?;
change_endpoint(api, rpc, validator_keypair, new_endpoint, quote).await
}

/// Changes the endpoint of a validator, with a TDX quote given as an argument
pub async fn change_endpoint(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
user_keypair: sr25519::Pair,
new_endpoint: String,
quote: Vec<u8>,
) -> anyhow::Result<EndpointChanged> {
) -> Result<EndpointChanged, ClientError> {
let change_endpoint_tx =
entropy::tx().staking_extension().change_endpoint(new_endpoint.into(), quote);
let in_block =
submit_transaction_with_pair(api, rpc, &user_keypair, &change_endpoint_tx, None).await?;
let result_event = in_block
.find_first::<entropy::staking_extension::events::EndpointChanged>()?
.ok_or(anyhow!("Error with transaction"))?;
.ok_or(SubstrateError::NoEvent)?;
Ok(result_event)
}

/// Changes the threshold account info of a validator, retrieving a TDX quote from the new endpoint internally
pub async fn get_quote_and_change_threshold_accounts(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
validator_keypair: sr25519::Pair,
new_tss_account: SubxtAccountId32,
new_x25519_public_key: [u8; 32],
new_pck_certificate_chain: Vec<Vec<u8>>,
) -> Result<ThresholdAccountChanged, ClientError> {
let quote = get_tdx_quote_with_validator_id(
api,
rpc,
&SubxtAccountId32(validator_keypair.public().0),
QuoteContext::ChangeThresholdAccounts,
)
.await?;
change_threshold_accounts(
api,
rpc,
validator_keypair,
new_tss_account,
new_x25519_public_key,
new_pck_certificate_chain,
quote,
)
.await
}

/// Changes the threshold account info of a validator
pub async fn change_threshold_accounts(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
user_keypair: sr25519::Pair,
new_tss_account: String,
new_x25519_public_key: String,
validator_keypair: sr25519::Pair,
new_tss_account: SubxtAccountId32,
new_x25519_public_key: [u8; 32],
new_pck_certificate_chain: Vec<Vec<u8>>,
quote: Vec<u8>,
) -> anyhow::Result<ThresholdAccountChanged> {
let tss_account = SubxtAccountId32::from_str(&new_tss_account)?;
let x25519_public_key = hex::decode(new_x25519_public_key)?
.try_into()
.map_err(|_| anyhow!("X25519 pub key needs to be 32 bytes"))?;
) -> Result<ThresholdAccountChanged, ClientError> {
let change_threshold_accounts = entropy::tx().staking_extension().change_threshold_accounts(
tss_account,
x25519_public_key,
new_tss_account,
new_x25519_public_key,
new_pck_certificate_chain,
quote,
);
let in_block =
submit_transaction_with_pair(api, rpc, &user_keypair, &change_threshold_accounts, None)
.await?;
let in_block = submit_transaction_with_pair(
api,
rpc,
&validator_keypair,
&change_threshold_accounts,
None,
)
.await?;
let result_event = in_block
.find_first::<entropy::staking_extension::events::ThresholdAccountChanged>()?
.ok_or(anyhow!("Error with transaction"))?;
.ok_or(SubstrateError::NoEvent)?;
Ok(result_event)
}

Expand Down Expand Up @@ -463,3 +501,31 @@ pub async fn get_oracle_headings(
}
Ok(headings)
}

/// Retrieve a TDX quote using the currently configured endpoint associated with the given validator
/// ID
pub async fn get_tdx_quote_with_validator_id(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
validator_stash: &SubxtAccountId32,
quote_context: QuoteContext,
) -> Result<Vec<u8>, ClientError> {
let query = entropy::storage().staking_extension().threshold_servers(validator_stash);
let server_info = query_chain(api, rpc, query, None).await?.ok_or(ClientError::NoServerInfo)?;

let tss_endpoint = std::str::from_utf8(&server_info.endpoint)?;
get_tdx_quote(tss_endpoint, quote_context).await
}

/// Retrieve a TDX quote with a given socket address
pub async fn get_tdx_quote(
tss_endpoint: &str,
quote_context: QuoteContext,
) -> Result<Vec<u8>, ClientError> {
let response =
reqwest::get(format!("http://{}/attest?context={}", tss_endpoint, quote_context)).await?;
if response.status() != reqwest::StatusCode::OK {
return Err(ClientError::QuoteGet(response.text().await?));
}
Ok(response.bytes().await?.to_vec())
}
4 changes: 4 additions & 0 deletions crates/client/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,8 @@ pub enum ClientError {
Codec(#[from] parity_scale_codec::Error),
#[error("Attestation request: {0}")]
AttestationRequest(#[from] AttestationRequestError),
#[error("Unable to get TDX quote: {0}")]
QuoteGet(String),
#[error("Unable to get info for TSS server from chain")]
NoServerInfo,
}
4 changes: 2 additions & 2 deletions crates/client/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ async fn test_change_threshold_accounts() {
&api,
&rpc,
one.into(),
tss_public_key.to_string(),
hex::encode(*x25519_public_key.as_bytes()),
tss_public_key.into(),
*x25519_public_key.as_bytes(),
pck_certificate_chain,
quote,
)
Expand Down
2 changes: 1 addition & 1 deletion crates/kvdb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ edition ='2021'
# Common
rand ={ version="0.8", default-features=false }
serde ={ version="1.0", features=["derive"] }
thiserror="2.0.4"
thiserror="2.0.6"
hex ="0.4.3"

# Substrate
Expand Down
2 changes: 1 addition & 1 deletion crates/protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ x25519-dalek ={ version="2.0.1", features=["static_secrets"] }
futures ="0.3"
hex ="0.4.3"
blake2 ="0.10.4"
thiserror ="2.0.4"
thiserror ="2.0.6"
snow ="0.9.6"
getrandom ={ version="0.2", features=["js"] }
rand_core ={ version="0.6.4", features=["getrandom"] }
Expand Down
12 changes: 12 additions & 0 deletions crates/shared/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ pub enum QuoteContext {
ChangeThresholdAccounts,
}

#[cfg(feature = "std")]
impl std::fmt::Display for QuoteContext {
/// Custom display implementation so that it can be used to build a query string
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
QuoteContext::Validate => write!(f, "validate"),
QuoteContext::ChangeEndpoint => write!(f, "change_endpoint"),
QuoteContext::ChangeThresholdAccounts => write!(f, "change_threshold_accounts"),
}
}
}

/// A trait for types which can handle attestation requests.
#[cfg(not(feature = "wasm"))]
pub trait AttestationHandler<AccountId> {
Expand Down
2 changes: 1 addition & 1 deletion crates/test-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ x25519-dalek ="2.0.1"
sp-runtime ={ version="32.0.0", default-features=false }
entropy-shared={ version="0.3.0", path="../shared" }
serde_json ="1.0.133"
serde ={ version="1.0.215", features=["derive"] }
serde ={ version="1.0.216", features=["derive"] }
reqwest ="0.12.9"
Loading

0 comments on commit b31180e

Please sign in to comment.