diff --git a/CHANGELOG.md b/CHANGELOG.md index 323bb1903..f11ce08f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ At the moment this project **does not** adhere to - In [#592](https://github.com/entropyxyz/entropy-core/pull/592), the `local-devnet` chain-type was renamed to `devnet-local`. Additionally, the default chain type when none is specified is now `dev` instead of `local`. +- A user now needs to add a program config, which gets packaged with their program pointer to create program info. This changes both register and change_program_info (previously change_program_pointer). As well set_program now also takes program_type_definition. ([#593](https://github.com/entropyxyz/entropy-core/pull/593)) ### Added - Test CLI which calls the same code as in integration tests ([#417](https://github.com/entropyxyz/entropy-core/pull/417)) @@ -34,6 +35,7 @@ At the moment this project **does not** adhere to - Add ref counter to programs ([#585](https://github.com/entropyxyz/entropy-core/pull/585/)) - Add `--setup-only` flag ([#588](https://github.com/entropyxyz/entropy-core/pull/588/)) - Add --version flag and about field to TSS ([#590](https://github.com/entropyxyz/entropy-core/pull/590/)) +- Program config storage ([#593](https://github.com/entropyxyz/entropy-core/pull/593)) ### Changed - Crate name refactor ([#561](https://github.com/entropyxyz/entropy-core/pull/561)) diff --git a/crates/test-cli/src/main.rs b/crates/test-cli/src/main.rs index 6f9537e4e..b2f3da116 100644 --- a/crates/test-cli/src/main.rs +++ b/crates/test-cli/src/main.rs @@ -24,7 +24,10 @@ use std::{ use clap::{Parser, Subcommand}; use colored::Colorize; use entropy_testing_utils::{ - chain_api::entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + chain_api::{ + entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + entropy::runtime_types::pallet_relayer::pallet::ProgramInstance, + }, constants::{AUXILARY_DATA_SHOULD_SUCCEED, TEST_PROGRAM_WASM_BYTECODE}, test_client::{ derive_static_secret, get_accounts, get_api, get_rpc, register, sign, update_program, @@ -70,6 +73,8 @@ enum CliCommand { key_visibility: Visibility, /// The hash of the initial program for the account program_hashes: Vec, + /// The program configs of the initial programs for the account + program_configs: Vec>, }, /// Ask the network to sign a given message Sign { @@ -94,6 +99,8 @@ enum CliCommand { program_account_name: String, /// The path to a .wasm file containing the program (defaults to test program) program_file: Option, + /// The path to a file containing the program config (defaults to empty) + program_config_file: Option, }, /// Display a list of registered Entropy accounts Status, @@ -157,6 +164,7 @@ async fn run_command() -> anyhow::Result { program_account_name, key_visibility, program_hashes, + program_configs, } => { let signature_request_keypair: sr25519::Pair = SeedString::new(signature_request_account_name).try_into()?; @@ -176,6 +184,14 @@ async fn run_command() -> anyhow::Result { }, Visibility::Public => KeyVisibility::Public, }; + let mut programs_info = vec![]; + + for i in 0..program_hashes.len() { + programs_info.push(ProgramInstance { + program_pointer: program_hashes[i], + program_config: program_configs[i].clone(), + }); + } let (registered_info, keyshare_option) = register( &api, @@ -183,7 +199,7 @@ async fn run_command() -> anyhow::Result { signature_request_keypair.clone(), program_account, key_visibility_converted, - BoundedVec(program_hashes), + BoundedVec(programs_info), ) .await?; @@ -225,6 +241,7 @@ async fn run_command() -> anyhow::Result { signature_request_account_name, program_account_name, program_file, + program_config_file, } => { let signature_request_keypair: sr25519::Pair = SeedString::new(signature_request_account_name).try_into()?; @@ -235,9 +252,14 @@ async fn run_command() -> anyhow::Result { None => TEST_PROGRAM_WASM_BYTECODE.to_owned(), }; + let program_config = match program_config_file { + Some(file_name) => fs::read(file_name)?, + None => vec![], + }; + let program_keypair: sr25519::Pair = SeedString::new(program_account_name).try_into()?; - update_program(&api, &program_keypair, program).await?; + update_program(&api, &program_keypair, program, program_config).await?; Ok("Program updated".to_string()) }, CliCommand::Status => { diff --git a/crates/testing-utils/src/test_client/mod.rs b/crates/testing-utils/src/test_client/mod.rs index c661fa67d..11ac9fe08 100644 --- a/crates/testing-utils/src/test_client/mod.rs +++ b/crates/testing-utils/src/test_client/mod.rs @@ -36,6 +36,7 @@ use entropy_protocol::{ use entropy_tss::{ chain_api::{ entropy, entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + entropy::runtime_types::pallet_relayer::pallet::ProgramInstance, entropy::runtime_types::pallet_relayer::pallet::RegisteredInfo, EntropyConfig, }, common::{get_current_subgroup_signers, Hasher, UserSignatureRequest}, @@ -46,7 +47,7 @@ use sp_core::{crypto::AccountId32, sr25519, Bytes, Pair}; use subxt::{ backend::legacy::LegacyRpcMethods, tx::{PairSigner, Signer}, - utils::{AccountId32 as SubxtAccountId32, Static, H256}, + utils::{AccountId32 as SubxtAccountId32, Static}, Config, OnlineClient, }; use synedrion::k256::ecdsa::{RecoveryId, Signature as k256Signature, VerifyingKey}; @@ -71,7 +72,7 @@ pub async fn register( signature_request_keypair: sr25519::Pair, program_account: SubxtAccountId32, key_visibility: KeyVisibility, - program_hashes: BoundedVec, + programs_data: BoundedVec, ) -> anyhow::Result<(RegisteredInfo, Option>)> { // Check if user is already registered let account_id32: AccountId32 = signature_request_keypair.public().into(); @@ -89,7 +90,7 @@ pub async fn register( signature_request_keypair.clone(), program_account, key_visibility, - program_hashes, + programs_data, ) .await?; @@ -249,8 +250,9 @@ pub async fn update_program( api: &OnlineClient, program_modification_keypair: &sr25519::Pair, program: Vec, + program_type_definition: Vec, ) -> anyhow::Result<::Hash> { - let update_program_tx = entropy::tx().programs().set_program(program); + let update_program_tx = entropy::tx().programs().set_program(program, program_type_definition); let program_modification_account = PairSigner::::new(program_modification_keypair.clone()); @@ -273,14 +275,14 @@ pub async fn update_pointer( rpc: &LegacyRpcMethods, signature_request_account: &sr25519::Pair, pointer_modification_account: &sr25519::Pair, - program_hashes: BoundedVec<::Hash>, + program_instance: BoundedVec, ) -> anyhow::Result<()> { let block_hash = rpc.chain_get_block_hash(None).await?.ok_or_else(|| anyhow!("Error getting block hash"))?; let update_pointer_tx = entropy::tx() .relayer() - .change_program_pointer(signature_request_account.public().into(), program_hashes); + .change_program_instance(signature_request_account.public().into(), program_instance); let account_id32: AccountId32 = pointer_modification_account.public().into(); let account_id: ::AccountId = account_id32.into(); @@ -329,7 +331,7 @@ pub async fn put_register_request_on_chain( signature_request_keypair: sr25519::Pair, program_modification_account: SubxtAccountId32, key_visibility: KeyVisibility, - program_hashes: BoundedVec, + program_instance: BoundedVec, ) -> anyhow::Result<()> { let signature_request_pair_signer = PairSigner::::new(signature_request_keypair); @@ -337,7 +339,7 @@ pub async fn put_register_request_on_chain( let registering_tx = entropy::tx().relayer().register( program_modification_account, Static(key_visibility), - program_hashes, + program_instance, ); api.tx() diff --git a/crates/threshold-signature-server/entropy_metadata.scale b/crates/threshold-signature-server/entropy_metadata.scale index 24c708dd1..c47b048b8 100644 Binary files a/crates/threshold-signature-server/entropy_metadata.scale and b/crates/threshold-signature-server/entropy_metadata.scale differ diff --git a/crates/threshold-signature-server/src/helpers/tests.rs b/crates/threshold-signature-server/src/helpers/tests.rs index c7fd7c139..ff94924dd 100644 --- a/crates/threshold-signature-server/src/helpers/tests.rs +++ b/crates/threshold-signature-server/src/helpers/tests.rs @@ -185,9 +185,10 @@ pub async fn update_programs( entropy_api: &OnlineClient, program_modification_account: &sr25519::Pair, initial_program: Vec, + program_config: Vec, ) -> ::Hash { // update/set their programs - let update_program_tx = entropy::tx().programs().set_program(initial_program); + let update_program_tx = entropy::tx().programs().set_program(initial_program, program_config); let program_modification_account = PairSigner::::new(program_modification_account.clone()); diff --git a/crates/threshold-signature-server/src/helpers/user.rs b/crates/threshold-signature-server/src/helpers/user.rs index 3c24ea724..5c56f48d3 100644 --- a/crates/threshold-signature-server/src/helpers/user.rs +++ b/crates/threshold-signature-server/src/helpers/user.rs @@ -26,15 +26,15 @@ use sha1::{Digest as Sha1Digest, Sha1}; use sha2::{Digest as Sha256Digest, Sha256}; use sha3::{Digest as Sha3Digest, Keccak256, Sha3_256}; use sp_core::{sr25519, Bytes, Pair}; -use subxt::{ - backend::legacy::LegacyRpcMethods, tx::PairSigner, utils::AccountId32, Config, OnlineClient, -}; +use subxt::{backend::legacy::LegacyRpcMethods, tx::PairSigner, utils::AccountId32, OnlineClient}; use synedrion::KeyShare; use tokio::time::timeout; use x25519_dalek::PublicKey; use crate::{ - chain_api::{entropy, EntropyConfig}, + chain_api::{ + entropy, entropy::runtime_types::pallet_relayer::pallet::ProgramInstance, EntropyConfig, + }, helpers::substrate::get_program, signing_client::{protocol_transport::open_protocol_connections, Listener, ListenerState}, user::{api::UserRegistrationInfo, errors::UserErr}, @@ -174,7 +174,7 @@ pub async fn compute_hash( rpc: &LegacyRpcMethods, hashing_algorithm: &HashingAlgorithm, runtime: &mut Runtime, - program_pointers: &[::Hash], + programs_data: &[ProgramInstance], message: &[u8], ) -> Result<[u8; 32], UserErr> { match hashing_algorithm { @@ -211,7 +211,7 @@ pub async fn compute_hash( Ok(hash) }, HashingAlgorithm::Custom(i) => { - let program = get_program(api, rpc, &program_pointers[*i]).await?; + let program = get_program(api, rpc, &programs_data[*i].program_pointer).await?; runtime.custom_hash(program.as_slice(), message).map_err(|e| e.into()) }, } diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 9d8986fbf..1105ad22b 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -147,25 +147,25 @@ pub async fn sign_tx( let message = hex::decode(&user_sig_req.message)?; - if user_details.program_pointers.0.is_empty() { + if user_details.programs_data.0.is_empty() { return Err(UserErr::NoProgramPointerDefined()); } // handle aux data padding, if it is not explicit by client for ease send through None, error if incorrect length let auxilary_data_vec; if let Some(auxilary_data) = user_sig_req.clone().auxilary_data { - if auxilary_data.len() < user_details.program_pointers.0.len() { + if auxilary_data.len() < user_details.programs_data.0.len() { return Err(UserErr::MismatchAuxData); } else { auxilary_data_vec = auxilary_data; } } else { - auxilary_data_vec = vec![None; user_details.program_pointers.0.len()]; + auxilary_data_vec = vec![None; user_details.programs_data.0.len()]; } let mut runtime = Runtime::new(ProgramConfig { fuel: MAX_INSTRUCTIONS_PER_PROGRAM }); - for (i, program_pointer) in user_details.program_pointers.0.iter().enumerate() { - let program = get_program(&api, &rpc, program_pointer).await?; + for (i, program_info) in user_details.programs_data.0.iter().enumerate() { + let program = get_program(&api, &rpc, &program_info.program_pointer).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, &signature_request)?; @@ -189,7 +189,7 @@ pub async fn sign_tx( &rpc, &user_sig_req.hash, &mut runtime, - &user_details.program_pointers.0, + &user_details.programs_data.0, message.as_slice(), ) .await?; diff --git a/crates/threshold-signature-server/src/user/tests.rs b/crates/threshold-signature-server/src/user/tests.rs index 2a8799780..85c7f6a48 100644 --- a/crates/threshold-signature-server/src/user/tests.rs +++ b/crates/threshold-signature-server/src/user/tests.rs @@ -36,7 +36,10 @@ use entropy_protocol::{ }; use entropy_shared::{HashingAlgorithm, KeyVisibility, OcwMessageDkg}; use entropy_testing_utils::{ - chain_api::entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec as OtherBoundedVec, + chain_api::{ + entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec as OtherBoundedVec, + entropy::runtime_types::pallet_relayer::pallet::ProgramInstance as OtherProgramInstance, + }, constants::{ ALICE_STASH_ADDRESS, AUXILARY_DATA_SHOULD_FAIL, AUXILARY_DATA_SHOULD_SUCCEED, PREIMAGE_SHOULD_FAIL, PREIMAGE_SHOULD_SUCCEED, TEST_INFINITE_LOOP_BYTECODE, @@ -83,8 +86,9 @@ use x25519_dalek::{PublicKey, StaticSecret}; use super::UserInputPartyInfo; use crate::{ chain_api::{ - entropy, entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, get_api, - get_rpc, EntropyConfig, + entropy, entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + entropy::runtime_types::pallet_relayer::pallet::ProgramInstance, get_api, get_rpc, + EntropyConfig, }, get_signer, helpers::{ @@ -137,7 +141,8 @@ async fn test_sign_tx_no_chain() { let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); let program_hash = - update_programs(&entropy_api, &two.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await; + update_programs(&entropy_api, &two.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![]) + .await; let validators_info = vec![ ValidatorInfo { @@ -187,7 +192,10 @@ async fn test_sign_tx_no_chain() { &rpc, &one.pair(), &one.pair(), - OtherBoundedVec(vec![program_hash, program_hash]), + OtherBoundedVec(vec![ + OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, + OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, + ]), ) .await .unwrap(); @@ -415,13 +423,17 @@ async fn test_fail_signing_group() { ]; let program_hash = - update_programs(&entropy_api, &eve.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await; + update_programs(&entropy_api, &eve.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![]) + .await; update_pointer( &entropy_api, &rpc, &dave.pair(), &dave.pair(), - OtherBoundedVec(vec![program_hash]), + OtherBoundedVec(vec![OtherProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]), ) .await .unwrap(); @@ -489,8 +501,13 @@ async fn test_store_share() { .unwrap(); let original_key_shard = response_key.text().await.unwrap(); - let program_hash = - update_programs(&api, &program_manager.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await; + let program_hash = update_programs( + &api, + &program_manager.pair(), + TEST_PROGRAM_WASM_BYTECODE.to_owned(), + vec![], + ) + .await; let mut block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; let validators_info = vec![ @@ -513,7 +530,7 @@ async fn test_store_share() { &alice, alice_program.to_account_id().into(), KeyVisibility::Public, - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await; @@ -582,7 +599,7 @@ async fn test_store_share() { &alice_program, alice_program.to_account_id().into(), KeyVisibility::Public, - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await; onchain_user_request.block_number = block_number; @@ -704,14 +721,19 @@ async fn test_send_and_receive_keys() { assert_eq!(response_already_in_storage.status(), StatusCode::INTERNAL_SERVER_ERROR); assert_eq!(response_already_in_storage.text().await.unwrap(), "User already registered"); - let program_hash = - update_programs(&api, &program_manager.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await; + let program_hash = update_programs( + &api, + &program_manager.pair(), + TEST_PROGRAM_WASM_BYTECODE.to_owned(), + vec![], + ) + .await; put_register_request_on_chain( &api, &alice.clone(), alice.to_account_id().into(), KeyVisibility::Public, - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await; let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; @@ -768,7 +790,7 @@ pub async fn put_register_request_on_chain( sig_req_keyring: &Sr25519Keyring, program_modification_account: subxtAccountId32, key_visibility: KeyVisibility, - program_hashes: BoundedVec, + program_instance: BoundedVec, ) { let sig_req_account = PairSigner::::new(sig_req_keyring.pair()); @@ -776,7 +798,7 @@ pub async fn put_register_request_on_chain( let registering_tx = entropy::tx().relayer().register( program_modification_account, Static(key_visibility), - program_hashes, + program_instance, ); api.tx() @@ -808,13 +830,17 @@ async fn test_sign_tx_user_participates() { let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); let program_hash = - update_programs(&entropy_api, &two.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await; + update_programs(&entropy_api, &two.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![]) + .await; update_pointer( &entropy_api, &rpc, &one.pair(), &one.pair(), - OtherBoundedVec(vec![program_hash]), + OtherBoundedVec(vec![OtherProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]), ) .await .unwrap(); @@ -1086,8 +1112,13 @@ async fn test_register_with_private_key_visibility() { let substrate_context = test_context_stationary().await; 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 program_hash = - update_programs(&api, &program_manager.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await; + let program_hash = update_programs( + &api, + &program_manager.pair(), + TEST_PROGRAM_WASM_BYTECODE.to_owned(), + vec![], + ) + .await; let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; let one_x25519_sk = derive_static_secret(&one.pair()); @@ -1098,7 +1129,7 @@ async fn test_register_with_private_key_visibility() { &one, program_modification_account.to_account_id().into(), KeyVisibility::Private(x25519_public_key), - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await; run_to_block(&rpc, block_number + 1).await; @@ -1159,14 +1190,14 @@ async fn test_compute_hash() { let mut runtime = Runtime::default(); let program_hash = - update_programs(&api, &one.pair(), TEST_PROGRAM_CUSTOM_HASH.to_owned()).await; + update_programs(&api, &one.pair(), TEST_PROGRAM_CUSTOM_HASH.to_owned(), vec![]).await; let message_hash = compute_hash( &api, &rpc, &HashingAlgorithm::Custom(0), &mut runtime, - &[program_hash], + &vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }], PREIMAGE_SHOULD_SUCCEED, ) .await @@ -1229,13 +1260,17 @@ async fn test_fail_infinite_program() { let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); let program_hash = - update_programs(&entropy_api, &two.pair(), TEST_INFINITE_LOOP_BYTECODE.to_owned()).await; + update_programs(&entropy_api, &two.pair(), TEST_INFINITE_LOOP_BYTECODE.to_owned(), vec![]) + .await; update_pointer( &entropy_api, &rpc, &one.pair(), &one.pair(), - OtherBoundedVec(vec![program_hash]), + OtherBoundedVec(vec![OtherProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]), ) .await .unwrap(); diff --git a/crates/threshold-signature-server/tests/protocol_wasm.rs b/crates/threshold-signature-server/tests/protocol_wasm.rs index 4a1d1d515..95c35ec3e 100644 --- a/crates/threshold-signature-server/tests/protocol_wasm.rs +++ b/crates/threshold-signature-server/tests/protocol_wasm.rs @@ -27,7 +27,10 @@ use entropy_kvdb::clean_tests; use entropy_protocol::{KeyParams, ValidatorInfo}; use entropy_shared::{HashingAlgorithm, KeyVisibility, OcwMessageDkg}; use entropy_testing_utils::{ - chain_api::entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + chain_api::{ + entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + entropy::runtime_types::pallet_relayer::pallet::ProgramInstance, + }, constants::{ AUXILARY_DATA_SHOULD_SUCCEED, PREIMAGE_SHOULD_SUCCEED, TEST_PROGRAM_WASM_BYTECODE, TSS_ACCOUNTS, X25519_PUBLIC_KEYS, @@ -82,12 +85,18 @@ async fn test_wasm_sign_tx_user_participates() { let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); let program_hash = - update_program(&entropy_api, &dave.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()) + update_program(&entropy_api, &dave.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![]) .await .unwrap(); - update_pointer(&entropy_api, &rpc, &one.pair(), &one.pair(), BoundedVec(vec![program_hash])) - .await - .unwrap(); + update_pointer( + &entropy_api, + &rpc, + &one.pair(), + &one.pair(), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), + ) + .await + .unwrap(); let validators_info = vec![ ValidatorInfo { @@ -202,7 +211,9 @@ async fn test_wasm_register_with_private_key_visibility() { 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 program_hash = - update_program(&api, &dave.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()).await.unwrap(); + update_program(&api, &dave.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![]) + .await + .unwrap(); let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; @@ -214,7 +225,7 @@ async fn test_wasm_register_with_private_key_visibility() { one.pair(), program_modification_account.to_account_id().into(), KeyVisibility::Private(x25519_public_key), - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); diff --git a/crates/threshold-signature-server/tests/sign.rs b/crates/threshold-signature-server/tests/sign.rs index 111670684..dd2976f18 100644 --- a/crates/threshold-signature-server/tests/sign.rs +++ b/crates/threshold-signature-server/tests/sign.rs @@ -15,7 +15,10 @@ use entropy_kvdb::clean_tests; use entropy_testing_utils::{ - chain_api::entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + chain_api::{ + entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, + entropy::runtime_types::pallet_relayer::pallet::ProgramInstance, + }, constants::{ AUXILARY_DATA_SHOULD_SUCCEED, PREIMAGE_SHOULD_SUCCEED, TEST_PROGRAM_WASM_BYTECODE, }, @@ -47,17 +50,21 @@ async fn integration_test_sign() { 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 program_hash = - test_client::update_program(&api, &eve.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()) - .await - .unwrap(); + let program_hash = test_client::update_program( + &api, + &eve.pair(), + TEST_PROGRAM_WASM_BYTECODE.to_owned(), + vec![], + ) + .await + .unwrap(); test_client::update_pointer( &api, &rpc, &pre_registered_user.pair(), &pre_registered_user.pair(), - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); @@ -98,17 +105,21 @@ async fn integration_test_sign_private() { 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 program_hash = - test_client::update_program(&api, &dave.pair(), TEST_PROGRAM_WASM_BYTECODE.to_owned()) - .await - .unwrap(); + let program_hash = test_client::update_program( + &api, + &dave.pair(), + TEST_PROGRAM_WASM_BYTECODE.to_owned(), + vec![], + ) + .await + .unwrap(); test_client::update_pointer( &api, &rpc, &pre_registered_user.pair(), &pre_registered_user.pair(), - BoundedVec(vec![program_hash]), + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); diff --git a/pallets/programs/src/benchmarking.rs b/pallets/programs/src/benchmarking.rs index 09007cf2a..c865f26c0 100644 --- a/pallets/programs/src/benchmarking.rs +++ b/pallets/programs/src/benchmarking.rs @@ -15,7 +15,7 @@ //! Benchmarking setup for pallet-propgation -use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, vec, whitelisted_caller}; +use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, vec, whitelisted_caller, Vec}; use frame_support::{ traits::{Currency, Get}, BoundedVec, @@ -41,19 +41,25 @@ benchmarks! { set_program { let program = vec![10]; - let program_hash = T::Hashing::hash(&program); + let program_type_definition = vec![11]; + let mut hash_input: Vec = vec![]; + hash_input.extend(&program); + hash_input.extend(&program_type_definition); + + let program_hash = T::Hashing::hash(&hash_input); let program_modification_account: T::AccountId = whitelisted_caller(); let sig_req_account: T::AccountId = whitelisted_caller(); let value = CurrencyOf::::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = CurrencyOf::::make_free_balance_be(&program_modification_account, value); - }: _(RawOrigin::Signed(program_modification_account.clone()), program.clone()) + }: _(RawOrigin::Signed(program_modification_account.clone()), program.clone(), program_type_definition.clone()) verify { assert_last_event::( Event::::ProgramCreated { program_modification_account, - program_hash + program_hash, + program_type_definition }.into() ); } @@ -61,14 +67,19 @@ benchmarks! { remove_program { let p in 0..T::MaxOwnedPrograms::get(); let program = vec![10]; - let program_hash = T::Hashing::hash(&program); + let program_type_definition = vec![11]; + let mut hash_input: Vec = vec![]; + hash_input.extend(&program); + hash_input.extend(&program_type_definition); + + let program_hash = T::Hashing::hash(&hash_input); let random_program = vec![11]; let random_hash = T::Hashing::hash(&random_program); let program_modification_account: T::AccountId = whitelisted_caller(); let value = CurrencyOf::::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = CurrencyOf::::make_free_balance_be(&program_modification_account, value); - >::insert(program_hash.clone(), ProgramInfo {bytecode: program, program_modification_account: program_modification_account.clone(), ref_counter: 0u128}); + >::insert(program_hash.clone(), ProgramInfo {bytecode: program, program_type_definition, program_modification_account: program_modification_account.clone(), ref_counter: 0u128}); let mut program_hashes = vec![random_hash.clone(); p as usize]; // remove one to make room for the targetted removal program hash program_hashes.pop(); diff --git a/pallets/programs/src/lib.rs b/pallets/programs/src/lib.rs index f4dc4a358..a94599684 100644 --- a/pallets/programs/src/lib.rs +++ b/pallets/programs/src/lib.rs @@ -96,6 +96,8 @@ pub mod pallet { pub struct ProgramInfo { /// The bytecode of the program. pub bytecode: Vec, + /// The type definition of the program + pub program_type_definition: Vec, /// Owners of the program pub program_modification_account: AccountId, /// Accounts that use this program @@ -129,6 +131,9 @@ pub mod pallet { /// The new program hash. program_hash: T::Hash, + + /// The new program type definition + program_type_definition: Vec, }, /// The bytecode of a program was removed. ProgramRemoved { @@ -163,10 +168,17 @@ pub mod pallet { /// Note that the caller becomes the program-modification account. #[pallet::call_index(0)] #[pallet::weight({::WeightInfo::set_program()})] - pub fn set_program(origin: OriginFor, new_program: Vec) -> DispatchResult { + pub fn set_program( + origin: OriginFor, + new_program: Vec, + program_type_definition: Vec, + ) -> DispatchResult { let program_modification_account = ensure_signed(origin)?; - let program_hash = T::Hashing::hash(&new_program); - let new_program_length = new_program.len(); + let mut hash_input = vec![]; + hash_input.extend(&new_program); + hash_input.extend(&program_type_definition); + let program_hash = T::Hashing::hash(&hash_input); + let new_program_length = new_program.len() + program_type_definition.len(); ensure!( new_program_length as u32 <= T::MaxBytecodeLength::get(), Error::::ProgramLengthExceeded @@ -179,6 +191,7 @@ pub mod pallet { program_hash, &ProgramInfo { bytecode: new_program.clone(), + program_type_definition: program_type_definition.clone(), program_modification_account: program_modification_account.clone(), ref_counter: 0u128, }, @@ -195,6 +208,7 @@ pub mod pallet { Self::deposit_event(Event::ProgramCreated { program_modification_account, program_hash, + program_type_definition, }); Ok(()) } @@ -218,7 +232,7 @@ pub mod pallet { ensure!(old_program_info.ref_counter == 0, Error::::ProgramInUse); Self::unreserve_program_deposit( &old_program_info.program_modification_account, - old_program_info.bytecode.len(), + old_program_info.bytecode.len() + old_program_info.program_type_definition.len(), ); let mut owned_programs_length = 0; OwnedPrograms::::try_mutate( diff --git a/pallets/programs/src/tests.rs b/pallets/programs/src/tests.rs index 50e7d9986..e7b200b33 100644 --- a/pallets/programs/src/tests.rs +++ b/pallets/programs/src/tests.rs @@ -27,13 +27,19 @@ fn set_program() { new_test_ext().execute_with(|| { let program = vec![10u8, 11u8]; let program_2 = vec![12u8, 13u8]; + let program_type_definition = vec![14u8]; let too_long = vec![1u8, 2u8, 3u8, 4u8, 5u8]; - let program_hash = ::Hashing::hash(&program); + let mut hash_input: Vec = vec![]; + hash_input.extend(&program); + hash_input.extend(&program_type_definition); + + let program_hash = ::Hashing::hash(&hash_input); // can't pay deposit assert_noop!( ProgramsPallet::set_program( RuntimeOrigin::signed(PROGRAM_MODIFICATION_ACCOUNT), - program.clone() + program.clone(), + program_type_definition.clone() ), BalancesError::::InsufficientBalance ); @@ -42,10 +48,12 @@ fn set_program() { assert_ok!(ProgramsPallet::set_program( RuntimeOrigin::signed(PROGRAM_MODIFICATION_ACCOUNT), - program.clone() + program.clone(), + program_type_definition.clone() )); let program_result = ProgramInfo { bytecode: program.clone(), + program_type_definition: program_type_definition.clone(), program_modification_account: PROGRAM_MODIFICATION_ACCOUNT, ref_counter: 0u128, }; @@ -60,13 +68,14 @@ fn set_program() { "Program gets set to owner" ); // deposit taken - assert_eq!(Balances::free_balance(PROGRAM_MODIFICATION_ACCOUNT), 90, "Deposit charged"); + assert_eq!(Balances::free_balance(PROGRAM_MODIFICATION_ACCOUNT), 85, "Deposit charged"); // program is already set assert_noop!( ProgramsPallet::set_program( RuntimeOrigin::signed(PROGRAM_MODIFICATION_ACCOUNT), - program.clone() + program.clone(), + program_type_definition.clone() ), Error::::ProgramAlreadySet ); @@ -75,7 +84,8 @@ fn set_program() { assert_noop!( ProgramsPallet::set_program( RuntimeOrigin::signed(PROGRAM_MODIFICATION_ACCOUNT), - program_2.clone() + program_2.clone(), + program_type_definition.clone() ), Error::::TooManyProgramsOwned ); @@ -84,6 +94,7 @@ fn set_program() { ProgramsPallet::set_program( RuntimeOrigin::signed(PROGRAM_MODIFICATION_ACCOUNT), too_long, + program_type_definition ), Error::::ProgramLengthExceeded ); @@ -94,7 +105,11 @@ fn set_program() { fn remove_program() { new_test_ext().execute_with(|| { let program = vec![10u8, 11u8]; - let program_hash = ::Hashing::hash(&program); + let program_type_definition = vec![14u8]; + let mut hash_input: Vec = vec![]; + hash_input.extend(&program); + hash_input.extend(&program_type_definition); + let program_hash = ::Hashing::hash(&hash_input); // no program assert_noop!( @@ -109,7 +124,8 @@ fn remove_program() { Balances::make_free_balance_be(&PROGRAM_MODIFICATION_ACCOUNT, 100); assert_ok!(ProgramsPallet::set_program( RuntimeOrigin::signed(PROGRAM_MODIFICATION_ACCOUNT), - program.clone() + program.clone(), + program_type_definition.clone() )); assert_eq!( ProgramsPallet::owned_programs(PROGRAM_MODIFICATION_ACCOUNT), @@ -127,7 +143,7 @@ fn remove_program() { PROGRAM_MODIFICATION_ACCOUNT, "Program modification account gets set" ); - assert_eq!(Balances::free_balance(PROGRAM_MODIFICATION_ACCOUNT), 90, "Deposit charged"); + assert_eq!(Balances::free_balance(PROGRAM_MODIFICATION_ACCOUNT), 85, "Deposit charged"); // not authorized assert_noop!( @@ -155,11 +171,13 @@ fn remove_program_fails_ref_count() { new_test_ext().execute_with(|| { let program = vec![10u8, 11u8]; let program_hash = ::Hashing::hash(&program); + let program_type_definition = vec![14u8]; Programs::::insert( program_hash, ProgramInfo { bytecode: program, + program_type_definition, program_modification_account: PROGRAM_MODIFICATION_ACCOUNT, ref_counter: 1u128, }, diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index 601d7736e..7ae9de962 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -19,6 +19,7 @@ use codec::Encode; use entropy_shared::{KeyVisibility, ValidatorInfo}; use frame_support::{assert_ok, traits::OnInitialize, BoundedVec}; use pallet_programs::ProgramInfo; +use pallet_relayer::ProgramInstance; use pallet_staking_extension::RefreshInfo; use sp_core::offchain::{testing, OffchainDbExt, OffchainWorkerExt, TransactionPoolExt}; use sp_io::TestExternalities; @@ -78,21 +79,30 @@ fn knows_how_to_mock_several_http_calls() { System::set_block_number(3); pallet_programs::Programs::::insert( ::Hash::default(), - ProgramInfo { bytecode: vec![], program_modification_account: 1, ref_counter: 0 }, + ProgramInfo { + bytecode: vec![], + program_type_definition: vec![], + program_modification_account: 1, + ref_counter: 0, + }, ); - let program_hashes = - BoundedVec::try_from(vec![::Hash::default()]).unwrap(); + + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: ::Hash::default(), + program_config: vec![], + }]) + .unwrap(); assert_ok!(Relayer::register( RuntimeOrigin::signed(1), 2, KeyVisibility::Public, - program_hashes.clone(), + programs_info.clone(), )); assert_ok!(Relayer::register( RuntimeOrigin::signed(2), 3, KeyVisibility::Public, - program_hashes, + programs_info, )); // full send Propagation::post_dkg(4).unwrap(); diff --git a/pallets/relayer/src/benchmarking.rs b/pallets/relayer/src/benchmarking.rs index 30e78e9d9..a69a83230 100644 --- a/pallets/relayer/src/benchmarking.rs +++ b/pallets/relayer/src/benchmarking.rs @@ -73,15 +73,20 @@ benchmarks! { register { let p in 1 .. T::MaxProgramHashes::get(); let program = vec![0u8]; + let program_type_definition = vec![1u8]; let program_hash = T::Hashing::hash(&program); - let program_hashes = vec![program_hash; p as usize]; - let bounded_program_hashes = BoundedVec::try_from(program_hashes).unwrap(); - let program_modification_account: T::AccountId = whitelisted_caller(); - Programs::::insert(program_hash, ProgramInfo {bytecode: program, program_modification_account: program_modification_account.clone(), ref_counter: 0}); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }; p as usize]) + .unwrap(); + + let program_modification_account: T::AccountId = whitelisted_caller(); + Programs::::insert(program_hash, ProgramInfo {bytecode: program, program_type_definition, program_modification_account: program_modification_account.clone(), ref_counter: 0}); let sig_req_account: T::AccountId = whitelisted_caller(); let balance = ::Currency::minimum_balance() * 100u32.into(); let _ = ::Currency::make_free_balance_be(&sig_req_account, balance); - }: _(RawOrigin::Signed(sig_req_account.clone()), program_modification_account, KeyVisibility::Public, bounded_program_hashes) + }: _(RawOrigin::Signed(sig_req_account.clone()), program_modification_account, KeyVisibility::Public, programs_info) verify { assert_last_event::(Event::SignalRegister(sig_req_account.clone()).into()); assert!(Registering::::contains_key(sig_req_account)); @@ -91,16 +96,20 @@ benchmarks! { let p in 1 .. T::MaxProgramHashes::get(); let program_modification_account: T::AccountId = whitelisted_caller(); let program = vec![0u8]; + let program_type_definition = vec![1u8]; let program_hash = T::Hashing::hash(&program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); - Programs::::insert(program_hash, ProgramInfo {bytecode: program, program_modification_account: program_modification_account.clone(), ref_counter: 1}); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]).unwrap(); + Programs::::insert(program_hash, ProgramInfo {bytecode: program, program_type_definition, program_modification_account: program_modification_account.clone(), ref_counter: 1}); let sig_req_account: T::AccountId = whitelisted_caller(); let balance = ::Currency::minimum_balance() * 100u32.into(); let _ = ::Currency::make_free_balance_be(&sig_req_account, balance); >::insert(&sig_req_account, RegisteringDetails:: { program_modification_account: sig_req_account.clone(), confirmations: vec![], - program_pointers: program_hashes, + programs_data: programs_info, key_visibility: KeyVisibility::Public, verifying_key: Some(BoundedVec::default()) }); @@ -109,42 +118,55 @@ benchmarks! { assert_last_event::(Event::RegistrationCancelled(sig_req_account.clone()).into()); } - change_program_pointer { + change_program_instance { let n in 1 .. T::MaxProgramHashes::get(); let o in 1 .. T::MaxProgramHashes::get(); + let program_modification_account: T::AccountId = whitelisted_caller(); let program = vec![0u8]; + let program_type_definition = vec![1u8]; let program_hash = T::Hashing::hash(&program); - let program_hashes = vec![program_hash; o as usize]; - let bounded_program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }; o as usize]) + .unwrap(); let new_program = vec![1u8]; let new_program_hash = T::Hashing::hash(&new_program); - let new_program_hashes = vec![new_program_hash; n as usize]; - let new_bounded_program_hashes = BoundedVec::try_from(new_program_hashes).unwrap(); - let sig_req_account: T::AccountId = whitelisted_caller(); - Programs::::insert(program_hash, ProgramInfo {bytecode: program, program_modification_account: program_modification_account.clone(), ref_counter: 0}); - Programs::::insert(new_program_hash, ProgramInfo {bytecode: new_program, program_modification_account: program_modification_account.clone(), ref_counter: o as u128}); + let new_programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: new_program_hash, + program_config: vec![], + }; n as usize]) + .unwrap(); + let sig_req_account: T::AccountId = whitelisted_caller(); + Programs::::insert(program_hash, ProgramInfo {bytecode: program, program_type_definition: program_type_definition.clone(), program_modification_account: program_modification_account.clone(), ref_counter: 0}); + Programs::::insert(new_program_hash, ProgramInfo {bytecode: new_program, program_type_definition, program_modification_account: program_modification_account.clone(), ref_counter: o as u128}); let balance = ::Currency::minimum_balance() * 100u32.into(); let _ = ::Currency::make_free_balance_be(&sig_req_account, balance); >::insert( &sig_req_account, RegisteredInfo { program_modification_account: sig_req_account.clone(), - program_pointers: bounded_program_hashes, + programs_data: programs_info, verifying_key: BoundedVec::default(), key_visibility: KeyVisibility::Public, }, ); - }: _(RawOrigin::Signed(sig_req_account.clone()), sig_req_account.clone(), new_bounded_program_hashes.clone()) + }: _(RawOrigin::Signed(sig_req_account.clone()), sig_req_account.clone(), new_programs_info.clone()) verify { - assert_last_event::(Event::ProgramPointerChanged(sig_req_account.clone(), new_bounded_program_hashes).into()); + assert_last_event::(Event::ProgramInfoChanged(sig_req_account.clone(), new_programs_info).into()); } confirm_register_registering { let c in 0 .. SIG_PARTIES as u32; let program = vec![0u8]; + let program_type_definition = vec![1u8]; + let program_hash = T::Hashing::hash(&program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]).unwrap(); let sig_req_account: T::AccountId = whitelisted_caller(); let validator_account: T::AccountId = whitelisted_caller(); let threshold_account: T::AccountId = whitelisted_caller(); @@ -158,7 +180,7 @@ benchmarks! { >::insert(&sig_req_account, RegisteringDetails:: { program_modification_account: sig_req_account.clone(), confirmations: vec![], - program_pointers: program_hashes, + programs_data: programs_info, key_visibility: KeyVisibility::Public, verifying_key: None }); @@ -172,9 +194,13 @@ benchmarks! { confirm_register_failed_registering { let c in 0 .. SIG_PARTIES as u32; let program = vec![0u8]; - let program_hash = T::Hashing::hash(&program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let program_type_definition = vec![1u8]; + let program_hash = T::Hashing::hash(&program); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]).unwrap(); let sig_req_account: T::AccountId = whitelisted_caller(); let validator_account: T::AccountId = whitelisted_caller(); let threshold_account: T::AccountId = whitelisted_caller(); @@ -190,7 +216,7 @@ benchmarks! { >::insert(&sig_req_account, RegisteringDetails:: { program_modification_account: sig_req_account.clone(), confirmations: confirmation, - program_pointers: program_hashes, + programs_data: programs_info, key_visibility: KeyVisibility::Public, verifying_key: Some(BoundedVec::default()) }); @@ -205,8 +231,12 @@ benchmarks! { confirm_register_registered { let c in 0 .. SIG_PARTIES as u32; let program = vec![0u8]; + let program_type_definition = vec![1u8]; let program_hash = T::Hashing::hash(&program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]).unwrap(); let sig_req_account: T::AccountId = whitelisted_caller(); let validator_account: T::AccountId = whitelisted_caller(); let threshold_account: T::AccountId = whitelisted_caller(); @@ -221,7 +251,7 @@ confirm_register_registered { >::insert(&sig_req_account, RegisteringDetails:: { program_modification_account: sig_req_account.clone(), confirmations: confirmation, - program_pointers: program_hashes, + programs_data: programs_info, key_visibility: KeyVisibility::Public, verifying_key: None }); diff --git a/pallets/relayer/src/lib.rs b/pallets/relayer/src/lib.rs index 05b9730ae..bb4ef605e 100644 --- a/pallets/relayer/src/lib.rs +++ b/pallets/relayer/src/lib.rs @@ -88,12 +88,19 @@ pub mod pallet { } pub type ProgramPointers = BoundedVec; + #[derive(Clone, Encode, Decode, Eq, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct ProgramInstance { + pub program_pointer: T::Hash, + pub program_config: Vec, + } + #[derive(Clone, Encode, Decode, Eq, PartialEqNoBound, RuntimeDebug, TypeInfo)] #[scale_info(skip_type_params(T))] pub struct RegisteringDetails { pub program_modification_account: T::AccountId, pub confirmations: Vec, - pub program_pointers: BoundedVec, + pub programs_data: BoundedVec, T::MaxProgramHashes>, pub key_visibility: KeyVisibility, pub verifying_key: Option>>, } @@ -104,7 +111,7 @@ pub mod pallet { pub key_visibility: KeyVisibility, // TODO better type pub verifying_key: BoundedVec>, - pub program_pointers: BoundedVec, + pub programs_data: BoundedVec, T::MaxProgramHashes>, pub program_modification_account: T::AccountId, } @@ -131,7 +138,7 @@ pub mod pallet { RegisteredInfo { key_visibility, verifying_key: BoundedVec::default(), - program_pointers: BoundedVec::default(), + programs_data: BoundedVec::default(), program_modification_account: account_info.0.clone(), }, ); @@ -173,8 +180,8 @@ pub mod pallet { FailedRegistration(T::AccountId), /// An account cancelled their registration RegistrationCancelled(T::AccountId), - /// An account hash changed their program pointers [who, new_program_pointers] - ProgramPointerChanged(T::AccountId, ProgramPointers), + /// An account hash changed their program info [who, new_program_instance] + ProgramInfoChanged(T::AccountId, BoundedVec, T::MaxProgramHashes>), /// An account has been registered. [who, block_number, failures] ConfirmedDone(T::AccountId, BlockNumberFor, Vec), } @@ -216,7 +223,7 @@ pub mod pallet { origin: OriginFor, program_modification_account: T::AccountId, key_visibility: KeyVisibility, - program_pointers: ProgramPointers, + programs_data: BoundedVec, T::MaxProgramHashes>, ) -> DispatchResultWithPostInfo { let sig_req_account = ensure_signed(origin)?; @@ -226,12 +233,12 @@ pub mod pallet { !Registering::::contains_key(&sig_req_account), Error::::AlreadySubmitted ); - ensure!(!program_pointers.is_empty(), Error::::NoProgramSet); + ensure!(!programs_data.is_empty(), Error::::NoProgramSet); let block_number = >::block_number(); // Change program ref counter - for program_pointer in &program_pointers { + for program_instance in &programs_data { pallet_programs::Programs::::try_mutate( - program_pointer, + program_instance.program_pointer, |maybe_program_info| { if let Some(program_info) = maybe_program_info { program_info.ref_counter = program_info.ref_counter.saturating_add(1); @@ -254,18 +261,14 @@ pub mod pallet { RegisteringDetails:: { program_modification_account, confirmations: vec![], - program_pointers: program_pointers.clone(), + programs_data: programs_data.clone(), key_visibility, verifying_key: None, }, ); - - // TODO add dkg creators for dkg and prep offchain worker for dkg - // also maybe need a second storage slot to delete after worker message has been sent - Self::deposit_event(Event::SignalRegister(sig_req_account)); - Ok(Some(::WeightInfo::register(program_pointers.len() as u32)).into()) + Ok(Some(::WeightInfo::register(programs_data.len() as u32)).into()) } /// Allows a user to remove themselves from registering state if it has been longer than prune block @@ -276,14 +279,17 @@ pub mod pallet { pub fn prune_registration(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; let registering_info = Self::registering(&who).ok_or(Error::::NotRegistering)?; - for program_pointer in ®istering_info.program_pointers { - pallet_programs::Programs::::mutate(program_pointer, |maybe_program_info| { - if let Some(program_info) = maybe_program_info { - program_info.ref_counter = program_info.ref_counter.saturating_sub(1); - } - }); + for program_instance in ®istering_info.programs_data { + pallet_programs::Programs::::mutate( + program_instance.program_pointer, + |maybe_program_info| { + if let Some(program_info) = maybe_program_info { + program_info.ref_counter = program_info.ref_counter.saturating_sub(1); + } + }, + ); } - let program_length = registering_info.program_pointers.len(); + let program_length = registering_info.programs_data.len(); Registering::::remove(&who); Self::deposit_event(Event::RegistrationCancelled(who)); Ok(Some(::WeightInfo::register(program_length as u32)).into()) @@ -292,19 +298,19 @@ pub mod pallet { /// Allows a user's program modification account to change their program pointer #[pallet::call_index(2)] #[pallet::weight({ - ::WeightInfo::change_program_pointer(::MaxProgramHashes::get(), ::MaxProgramHashes::get()) + ::WeightInfo::change_program_instance(::MaxProgramHashes::get(), ::MaxProgramHashes::get()) })] - pub fn change_program_pointer( + pub fn change_program_instance( origin: OriginFor, sig_request_account: T::AccountId, - new_program_pointers: ProgramPointers, + new_program_instance: BoundedVec, T::MaxProgramHashes>, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - ensure!(!new_program_pointers.is_empty(), Error::::NoProgramSet); + ensure!(!new_program_instance.is_empty(), Error::::NoProgramSet); // change program ref counter - for program_pointer in &new_program_pointers { + for program_instance in &new_program_instance { pallet_programs::Programs::::try_mutate( - program_pointer, + program_instance.program_pointer, |maybe_program_info| { if let Some(program_info) = maybe_program_info { program_info.ref_counter = program_info.ref_counter.saturating_add(1); @@ -316,7 +322,7 @@ pub mod pallet { )?; } let mut old_programs_length = 0; - let program_pointers = + let programs_data = Registered::::try_mutate(&sig_request_account, |maybe_registered_details| { if let Some(registerd_details) = maybe_registered_details { ensure!( @@ -324,9 +330,9 @@ pub mod pallet { Error::::NotAuthorized ); // decrement ref counter of not used programs - for program_pointer in ®isterd_details.program_pointers { + for program_instance in ®isterd_details.programs_data { pallet_programs::Programs::::mutate( - program_pointer, + program_instance.program_pointer, |maybe_program_info| { if let Some(program_info) = maybe_program_info { program_info.ref_counter = @@ -335,16 +341,16 @@ pub mod pallet { }, ); } - old_programs_length = registerd_details.program_pointers.len(); - registerd_details.program_pointers = new_program_pointers.clone(); - Ok(new_program_pointers) + old_programs_length = registerd_details.programs_data.len(); + registerd_details.programs_data = new_program_instance.clone(); + Ok(new_program_instance) } else { Err(Error::::NotRegistered) } })?; - Self::deposit_event(Event::ProgramPointerChanged(who, program_pointers.clone())); - Ok(Some(::WeightInfo::change_program_pointer( - program_pointers.len() as u32, + Self::deposit_event(Event::ProgramInfoChanged(who, programs_data.clone())); + Ok(Some(::WeightInfo::change_program_instance( + programs_data.len() as u32, old_programs_length as u32, )) .into()) @@ -414,7 +420,7 @@ pub mod pallet { RegisteredInfo { key_visibility: registering_info.key_visibility, verifying_key, - program_pointers: registering_info.program_pointers, + programs_data: registering_info.programs_data, program_modification_account: registering_info.program_modification_account, }, ); diff --git a/pallets/relayer/src/tests.rs b/pallets/relayer/src/tests.rs index a535dfca0..1c32c6083 100644 --- a/pallets/relayer/src/tests.rs +++ b/pallets/relayer/src/tests.rs @@ -30,7 +30,8 @@ use sp_runtime::{ use crate as pallet_relayer; use crate::{ - mock::*, Error, Registered, RegisteredInfo, RegisteringDetails, ValidateConfirmRegistered, + mock::*, Error, ProgramInstance, Registered, RegisteredInfo, RegisteringDetails, + ValidateConfirmRegistered, }; #[test] @@ -72,11 +73,16 @@ fn it_registers_a_user() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -86,7 +92,7 @@ fn it_registers_a_user() { RuntimeOrigin::signed(1), 2 as ::AccountId, KeyVisibility::Public, - program_hashes, + programs_info, )); assert_eq!(Relayer::dkg(0), vec![1u64.encode()]); assert_eq!( @@ -115,11 +121,16 @@ fn it_confirms_registers_a_user() { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -129,7 +140,7 @@ fn it_confirms_registers_a_user() { RuntimeOrigin::signed(1), 2 as ::AccountId, KeyVisibility::Private([0; 32]), - program_hashes.clone(), + programs_info.clone(), )); assert_noop!( @@ -165,7 +176,7 @@ fn it_confirms_registers_a_user() { let registering_info = RegisteringDetails:: { confirmations: vec![0], - program_pointers: program_hashes.clone(), + programs_data: programs_info.clone(), key_visibility: KeyVisibility::Private([0; 32]), verifying_key: Some(expected_verifying_key.clone()), program_modification_account: 2, @@ -186,7 +197,7 @@ fn it_confirms_registers_a_user() { RegisteredInfo { key_visibility: KeyVisibility::Private([0; 32]), verifying_key: expected_verifying_key, - program_pointers: program_hashes, + programs_data: programs_info.clone(), program_modification_account: 2 } ); @@ -198,12 +209,17 @@ fn it_changes_a_program_pointer() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 1, }, @@ -211,11 +227,20 @@ fn it_changes_a_program_pointer() { let new_program = vec![10]; let new_program_hash = ::Hashing::hash(&new_program); - let new_program_hashes = BoundedVec::try_from(vec![new_program_hash]).unwrap(); + let new_programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: new_program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( new_program_hash, - ProgramInfo { bytecode: new_program, program_modification_account: 1, ref_counter: 1 }, + ProgramInfo { + bytecode: new_program, + program_type_definition: empty_program.clone(), + program_modification_account: 1, + ref_counter: 1, + }, ); let expected_verifying_key = BoundedVec::default(); @@ -223,19 +248,19 @@ fn it_changes_a_program_pointer() { let mut registered_info = RegisteredInfo { key_visibility: KeyVisibility::Public, verifying_key: expected_verifying_key, - program_pointers: program_hashes, + programs_data: programs_info, program_modification_account: 2, }; Registered::::insert(1, ®istered_info); assert_eq!(Relayer::registered(1).unwrap(), registered_info); - assert_ok!(Relayer::change_program_pointer( + assert_ok!(Relayer::change_program_instance( RuntimeOrigin::signed(2), 1, - new_program_hashes.clone(), + new_programs_info.clone(), )); - registered_info.program_pointers = new_program_hashes; + registered_info.programs_data = new_programs_info; assert_eq!(Relayer::registered(1).unwrap(), registered_info); assert_eq!( pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, @@ -251,20 +276,22 @@ fn it_changes_a_program_pointer() { let unreigistered_program = vec![13]; let unreigistered_program_hash = ::Hashing::hash(&unreigistered_program); - let unreigistered_program_hashes = - BoundedVec::try_from(vec![new_program_hash, unreigistered_program_hash]).unwrap(); - + let unregistered_programs_info = BoundedVec::try_from(vec![ + ProgramInstance { program_pointer: new_program_hash, program_config: vec![] }, + ProgramInstance { program_pointer: unreigistered_program_hash, program_config: vec![] }, + ]) + .unwrap(); assert_noop!( - Relayer::change_program_pointer( + Relayer::change_program_instance( RuntimeOrigin::signed(2), 1, - unreigistered_program_hashes.clone(), + unregistered_programs_info.clone(), ), Error::::NoProgramSet ); assert_noop!( - Relayer::change_program_pointer( + Relayer::change_program_instance( RuntimeOrigin::signed(2), 1, BoundedVec::try_from(vec![]).unwrap(), @@ -279,12 +306,17 @@ fn it_fails_on_non_matching_verifying_keys() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -296,7 +328,7 @@ fn it_fails_on_non_matching_verifying_keys() { RuntimeOrigin::signed(1), 2 as ::AccountId, KeyVisibility::Private([0; 32]), - program_hashes, + programs_info, )); pallet_staking_extension::ThresholdToStash::::insert(1, 1); pallet_staking_extension::ThresholdToStash::::insert(2, 2); @@ -327,12 +359,17 @@ fn it_doesnt_allow_double_registering() { // register a user let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -342,7 +379,7 @@ fn it_doesnt_allow_double_registering() { RuntimeOrigin::signed(1), 2, KeyVisibility::Permissioned, - program_hashes.clone(), + programs_info.clone(), )); // error if they try to submit another request, even with a different program key @@ -351,7 +388,7 @@ fn it_doesnt_allow_double_registering() { RuntimeOrigin::signed(1), 2, KeyVisibility::Permissioned, - program_hashes + programs_info ), Error::::AlreadySubmitted ); @@ -364,14 +401,18 @@ fn it_fails_no_program() { // register a user let non_existing_program = vec![10]; let program_hash = ::Hashing::hash(&non_existing_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); assert_noop!( Relayer::register( RuntimeOrigin::signed(1), 2, KeyVisibility::Permissioned, - program_hashes + programs_info ), Error::::NoProgramSet ); @@ -398,12 +439,17 @@ fn it_tests_prune_registration() { new_test_ext().execute_with(|| { let inital_program = vec![10]; let program_hash = ::Hashing::hash(&inital_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: inital_program, + bytecode: inital_program.clone(), + program_type_definition: inital_program.clone(), program_modification_account: 1, ref_counter: 1, }, @@ -415,7 +461,7 @@ fn it_tests_prune_registration() { RuntimeOrigin::signed(1), 2, KeyVisibility::Permissioned, - program_hashes, + programs_info, )); assert_eq!( pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, @@ -437,12 +483,17 @@ fn it_provides_free_txs_confirm_done() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -453,7 +504,7 @@ fn it_provides_free_txs_confirm_done() { RuntimeOrigin::signed(5), 2 as ::AccountId, KeyVisibility::Public, - program_hashes, + programs_info, )); let p = ValidateConfirmRegistered::::new(); let c = RuntimeCall::Relayer(RelayerCall::confirm_register { @@ -511,12 +562,17 @@ fn it_provides_free_txs_confirm_done_fails_3() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -527,7 +583,7 @@ fn it_provides_free_txs_confirm_done_fails_3() { RuntimeOrigin::signed(5), 2 as ::AccountId, KeyVisibility::Public, - program_hashes, + programs_info, )); assert_ok!(Relayer::confirm_register( @@ -555,12 +611,17 @@ fn it_provides_free_txs_confirm_done_fails_4() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -571,7 +632,7 @@ fn it_provides_free_txs_confirm_done_fails_4() { RuntimeOrigin::signed(5), 2 as ::AccountId, KeyVisibility::Public, - program_hashes, + programs_info, )); let p = ValidateConfirmRegistered::::new(); let c = RuntimeCall::Relayer(RelayerCall::confirm_register { @@ -592,12 +653,17 @@ fn it_provides_free_txs_confirm_done_fails_5() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); - let program_hashes = BoundedVec::try_from(vec![program_hash]).unwrap(); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); pallet_programs::Programs::::insert( program_hash, ProgramInfo { - bytecode: empty_program, + bytecode: empty_program.clone(), + program_type_definition: empty_program.clone(), program_modification_account: 1, ref_counter: 0, }, @@ -608,7 +674,7 @@ fn it_provides_free_txs_confirm_done_fails_5() { RuntimeOrigin::signed(5), 2 as ::AccountId, KeyVisibility::Public, - program_hashes, + programs_info, )); let p = ValidateConfirmRegistered::::new(); let c = RuntimeCall::Relayer(RelayerCall::confirm_register { diff --git a/pallets/relayer/src/weights.rs b/pallets/relayer/src/weights.rs index 0d870e0e8..67dfa3b65 100644 --- a/pallets/relayer/src/weights.rs +++ b/pallets/relayer/src/weights.rs @@ -53,7 +53,7 @@ use core::marker::PhantomData; pub trait WeightInfo { fn register(p: u32) -> Weight; fn prune_registration(p: u32) -> Weight; - fn change_program_pointer(n: u32, o:u32) -> Weight; + fn change_program_instance(n: u32, o:u32) -> Weight; fn confirm_register_registering(c: u32, ) -> Weight; fn confirm_register_failed_registering(c: u32, ) -> Weight; fn confirm_register_registered(c: u32, ) -> Weight; @@ -104,7 +104,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Relayer::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `n` is `[1, 5]`. /// The range of component `o` is `[1, 5]`. - fn change_program_pointer(n: u32, _o: u32, ) -> Weight { + fn change_program_instance(n: u32, _o: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `633` // Estimated: `6573` @@ -217,7 +217,7 @@ impl WeightInfo for () { /// Proof: `Relayer::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `n` is `[1, 5]`. /// The range of component `o` is `[1, 5]`. - fn change_program_pointer(n: u32, _o: u32, ) -> Weight { + fn change_program_instance(n: u32, _o: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `633` // Estimated: `6573` diff --git a/pallets/transaction-pause/src/tests.rs b/pallets/transaction-pause/src/tests.rs index 97e75d9d7..0a26aca31 100644 --- a/pallets/transaction-pause/src/tests.rs +++ b/pallets/transaction-pause/src/tests.rs @@ -135,6 +135,7 @@ fn paused_transaction_filter_work() { let whitelist_address_call = &mock::RuntimeCall::ProgramsPallet(pallet_programs::Call::set_program { new_program: vec![], + program_type_definition: vec![], }); assert!(!PausedTransactionFilter::::contains(BALANCE_TRANSFER)); assert!(!PausedTransactionFilter::::contains(whitelist_address_call)); diff --git a/runtime/src/weights/pallet_relayer.rs b/runtime/src/weights/pallet_relayer.rs index 2ddecf194..e8929a2ad 100644 --- a/runtime/src/weights/pallet_relayer.rs +++ b/runtime/src/weights/pallet_relayer.rs @@ -87,7 +87,7 @@ impl pallet_relayer::WeightInfo for WeightInfo { /// Proof: `Relayer::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `n` is `[1, 5]`. /// The range of component `o` is `[1, 5]`. - fn change_program_pointer(n: u32, _o: u32, ) -> Weight { + fn change_program_instance(n: u32, _o: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `633` // Estimated: `6573`