Skip to content

Commit

Permalink
Allow different versions for programs (#1250)
Browse files Browse the repository at this point in the history
* Allow different versions for programs

* docs

* break up evaluation
  • Loading branch information
JesseAbram authored Jan 15, 2025
1 parent 67dc926 commit 1db72e7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ runtime
- Use context, not block number in TDX quote input data ([#1179](https://github.com/entropyxyz/entropy-core/pull/1179))
- Allow offchain worker requests to all TSS nodes in entropy-tss test environment ([#1147](https://github.com/entropyxyz/entropy-core/pull/1147))
- Extract PCK certificate chain from quotes ([#1209](https://github.com/entropyxyz/entropy-core/pull/1209))
- Allow different versions for programs ([#1250](https://github.com/entropyxyz/entropy-core/pull/1250))

### Fixed

Expand Down
52 changes: 48 additions & 4 deletions crates/threshold-signature-server/src/helpers/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//! Utilities relating to the user
use std::time::Duration;

use entropy_programs_runtime::Runtime;
use entropy_programs_runtime::{Config as ProgramConfig, Runtime, SignatureRequest};
use entropy_protocol::{
execute_protocol::{execute_dkg, Channels},
KeyShareWithAuxInfo, Listener, SessionId, ValidatorInfo,
Expand All @@ -32,7 +32,12 @@ use tokio::time::timeout;
use x25519_dalek::StaticSecret;

use crate::{
chain_api::{entropy::runtime_types::pallet_registry::pallet::ProgramInstance, EntropyConfig},
chain_api::{
entropy::runtime_types::{
pallet_programs::pallet::ProgramInfo, pallet_registry::pallet::ProgramInstance,
},
EntropyConfig,
},
helpers::substrate::get_program,
signing_client::{protocol_transport::open_protocol_connections, ListenerState},
user::errors::UserErr,
Expand Down Expand Up @@ -114,7 +119,7 @@ pub async fn compute_hash(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
hashing_algorithm: &HashingAlgorithm,
runtime: &mut Runtime,
fuel: u64,
programs_data: &[ProgramInstance],
message: &[u8],
) -> Result<[u8; 32], UserErr> {
Expand Down Expand Up @@ -154,8 +159,47 @@ pub async fn compute_hash(
HashingAlgorithm::Blake2_256 => Ok(blake2_256(message)),
HashingAlgorithm::Custom(i) => {
let program_info = get_program(api, rpc, &programs_data[*i].program_pointer).await?;
runtime.custom_hash(program_info.bytecode.as_slice(), message).map_err(|e| e.into())
evaluate_custom_hash(fuel, program_info, message)
},
_ => Err(UserErr::UnknownHashingAlgorithm),
}
}

/// Gets a runtime and evaluates a program for a specific runtime version.
pub fn evaluate_program(
fuel: u64,
program_info: ProgramInfo,
signature_request: SignatureRequest,
program_config: Vec<u8>,
oracle_data: Vec<Vec<u8>>,
) -> Result<(), UserErr> {
match program_info.version_number {
0 => {
let mut runtime = Runtime::new(ProgramConfig { fuel });
runtime
.evaluate(
&program_info.bytecode,
&signature_request,
Some(&program_config),
Some(&oracle_data),
)
.map_err(|e| e.into())
},
_ => Err(UserErr::ProgramVersion),
}
}

/// Gets a runtime and evaluates a custom hash for a specific runtime version.
pub fn evaluate_custom_hash(
fuel: u64,
program_info: ProgramInfo,
message: &[u8],
) -> Result<[u8; 32], UserErr> {
match program_info.version_number {
0 => {
let mut runtime = Runtime::new(ProgramConfig { fuel });
runtime.custom_hash(program_info.bytecode.as_slice(), message).map_err(|e| e.into())
},
_ => Err(UserErr::ProgramVersion),
}
}
30 changes: 15 additions & 15 deletions crates/threshold-signature-server/src/user/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use axum::{
use base64::prelude::{Engine, BASE64_STANDARD};
use entropy_client::substrate::get_registered_details;
use entropy_kvdb::kv_manager::{helpers::serialize as key_serialize, KvManager};
use entropy_programs_runtime::{Config as ProgramConfig, Runtime, SignatureRequest};
use entropy_programs_runtime::SignatureRequest;
use entropy_protocol::SigningSessionInfo;
use entropy_shared::{HashingAlgorithm, OcwMessageDkg, NETWORK_PARENT_KEY};
use futures::{channel::mpsc, future::join_all, StreamExt};
Expand All @@ -50,7 +50,7 @@ use crate::{
get_oracle_data, get_program, get_signers_from_chain, get_validators_info, query_chain,
submit_transaction,
},
user::{check_in_registration_group, compute_hash, do_dkg},
user::{check_in_registration_group, compute_hash, do_dkg, evaluate_program},
validator::get_signer_and_x25519_secret,
},
validation::{check_stale, EncryptedSignedMessage},
Expand Down Expand Up @@ -302,7 +302,7 @@ pub async fn sign_tx(
.ok_or_else(|| UserErr::OptionUnwrapError("Error Getting Block Number".to_string()))?
.number;

let (mut runtime, user_details, message) = pre_sign_checks(
let (fuel, user_details, message) = pre_sign_checks(
&api,
&rpc,
relayer_sig_request.user_signature_request.clone(),
Expand All @@ -315,7 +315,7 @@ pub async fn sign_tx(
&api,
&rpc,
&relayer_sig_request.user_signature_request.hash,
&mut runtime,
fuel,
&user_details.programs_data.0,
message.as_slice(),
)
Expand Down Expand Up @@ -649,7 +649,7 @@ pub async fn pre_sign_checks(
user_sig_req: UserSignatureRequest,
block_number: u32,
string_verifying_key: String,
) -> Result<(Runtime, RegisteredInfo, Vec<u8>), UserErr> {
) -> Result<(u64, RegisteredInfo, Vec<u8>), UserErr> {
check_stale(user_sig_req.block_number, block_number).await?;

// Probably impossible but block signing from parent key anyways
Expand Down Expand Up @@ -685,20 +685,20 @@ pub async fn pre_sign_checks(
.await?
.ok_or_else(|| UserErr::ChainFetch("Max instructions per program error"))?;

let mut runtime = Runtime::new(ProgramConfig { fuel });

for (i, program_data) in user_details.programs_data.0.iter().enumerate() {
let program_info = get_program(api, rpc, &program_data.program_pointer).await?;
let oracle_data = get_oracle_data(api, rpc, program_info.oracle_data_pointers.0).await?;
let oracle_data =
get_oracle_data(api, rpc, program_info.oracle_data_pointers.0.clone()).await?;
let auxilary_data = auxilary_data_vec[i].as_ref().map(hex::decode).transpose()?;
let signature_request = SignatureRequest { message: message.clone(), auxilary_data };
runtime.evaluate(
&program_info.bytecode,
&signature_request,
Some(&program_data.program_config),
Some(&oracle_data),
)?;
evaluate_program(
fuel,
program_info,
signature_request,
program_data.program_config.clone(),
oracle_data,
)?
}

Ok((runtime, user_details, message))
Ok((fuel, user_details, message))
}
2 changes: 2 additions & 0 deletions crates/threshold-signature-server/src/user/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ pub enum UserErr {
TooFewSigners,
#[error("Non signer sent from relayer")]
IncorrectSigner,
#[error("Program Version not supported")]
ProgramVersion,
}

impl From<hkdf::InvalidLength> for UserErr {
Expand Down
4 changes: 1 addition & 3 deletions crates/threshold-signature-server/src/user/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use entropy_client::{
user::{get_all_signers_from_chain, UserSignatureRequest},
};
use entropy_kvdb::clean_tests;
use entropy_programs_runtime::Runtime;
use entropy_protocol::{
decode_verifying_key,
protocol_transport::{noise::noise_handshake_initiator, SubscribeMessage},
Expand Down Expand Up @@ -931,7 +930,6 @@ async fn test_compute_hash() {
let api = get_api(&substrate_context.node_proc.ws_url).await.unwrap();
let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap();

let mut runtime = Runtime::default();
let program_hash = test_client::store_program(
&api,
&rpc,
Expand All @@ -949,7 +947,7 @@ async fn test_compute_hash() {
&api,
&rpc,
&HashingAlgorithm::Custom(0),
&mut runtime,
10000000u64,
&vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }],
PREIMAGE_SHOULD_SUCCEED,
)
Expand Down

0 comments on commit 1db72e7

Please sign in to comment.