Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change program_modification_account to deployer #604

Merged
merged 9 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ At the moment this project **does not** adhere to
`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))
- Changed program_type_definition to configuration_interface. ([#597](https://github.com/entropyxyz/entropy-core/pull/597))
- Changed program_modification_account in programs_info of programs pallet to deployer. ([#604](https://github.com/entropyxyz/entropy-core/pull/604))

### Added
- Test CLI which calls the same code as in integration tests ([#417](https://github.com/entropyxyz/entropy-core/pull/417))
Expand All @@ -50,6 +51,7 @@ At the moment this project **does not** adhere to
- Additive aux data ([#577](https://github.com/entropyxyz/entropy-core/pull/577))
- Refactor Rust-based chain specs ([#592](https://github.com/entropyxyz/entropy-core/pull/592))
- Fix test CLI for additive program pointers and update / refactor tests ([#591](https://github.com/entropyxyz/entropy-core/pull/591))
- Change `program_modification_account` to `program_deploy_key` ([#604](https://github.com/entropyxyz/entropy-core/pull/604))

### Fixed
- Fix inconsistency between interactive and file based passwords ([#589](https://github.com/entropyxyz/entropy-core/pull/589))
Expand Down
2 changes: 1 addition & 1 deletion crates/test-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ async fn run_command() -> anyhow::Result<String> {
println!(
"{} {} {:>11} {:>14} {}",
hash,
program_info.program_modification_account,
program_info.deployer,
program_info.ref_counter,
program_info.bytecode.len(),
!program_info.configuration_interface.is_empty(),
Expand Down
27 changes: 11 additions & 16 deletions crates/testing-utils/src/test_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,22 +248,21 @@ pub async fn sign(
skip_all,
fields(
signature_request_account,
program_modification_account = ?program_modification_keypair.public(),
deployer = ?deployerpair.public(),
)
)]
pub async fn store_program(
api: &OnlineClient<EntropyConfig>,
program_modification_keypair: &sr25519::Pair,
deployerpair: &sr25519::Pair,
program: Vec<u8>,
configuration_interface: Vec<u8>,
) -> anyhow::Result<<EntropyConfig as Config>::Hash> {
let update_program_tx = entropy::tx().programs().set_program(program, configuration_interface);
let program_modification_account =
PairSigner::<EntropyConfig, sr25519::Pair>::new(program_modification_keypair.clone());
let deployer = PairSigner::<EntropyConfig, sr25519::Pair>::new(deployerpair.clone());

let in_block = api
.tx()
.sign_and_submit_then_watch_default(&update_program_tx, &program_modification_account)
.sign_and_submit_then_watch_default(&update_program_tx, &deployer)
.await?
.wait_for_in_block()
.await?
Expand All @@ -279,7 +278,7 @@ pub async fn update_programs(
entropy_api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
signature_request_account: &sr25519::Pair,
pointer_modification_account: &sr25519::Pair,
deployer: &sr25519::Pair,
program_instance: BoundedVec<ProgramInstance>,
) -> anyhow::Result<()> {
let block_hash =
Expand All @@ -289,22 +288,21 @@ pub async fn update_programs(
.relayer()
.change_program_instance(signature_request_account.public().into(), program_instance);

let account_id32: AccountId32 = pointer_modification_account.public().into();
let account_id32: AccountId32 = deployer.public().into();
let account_id: <EntropyConfig as Config>::AccountId = account_id32.into();

let nonce_call = entropy::apis().account_nonce_api().account_nonce(account_id.clone());
let nonce = entropy_api.runtime_api().at(block_hash).call(nonce_call).await?;

let pointer_modification_account =
PairSigner::<EntropyConfig, sr25519::Pair>::new(pointer_modification_account.clone());
let deployer = PairSigner::<EntropyConfig, sr25519::Pair>::new(deployer.clone());

let partial_tx = entropy_api.tx().create_partial_signed_with_nonce(
&update_pointer_tx,
nonce.into(),
Default::default(),
)?;
let signer_payload = partial_tx.signer_payload();
let signature = pointer_modification_account.sign(&signer_payload);
let signature = deployer.sign(&signer_payload);

let tx = partial_tx.sign_with_address_and_signature(&account_id.into(), &signature);

Expand Down Expand Up @@ -357,7 +355,7 @@ pub async fn put_register_request_on_chain(
api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
signature_request_keypair: sr25519::Pair,
program_modification_account: SubxtAccountId32,
deployer: SubxtAccountId32,
key_visibility: KeyVisibility,
program_instance: BoundedVec<ProgramInstance>,
) -> anyhow::Result<()> {
Expand All @@ -367,11 +365,8 @@ pub async fn put_register_request_on_chain(
let signature_request_pair_signer =
PairSigner::<EntropyConfig, sp_core::sr25519::Pair>::new(signature_request_keypair);

let registering_tx = entropy::tx().relayer().register(
program_modification_account,
Static(key_visibility),
program_instance,
);
let registering_tx =
entropy::tx().relayer().register(deployer, Static(key_visibility), program_instance);

let block_hash =
rpc.chain_get_block_hash(None).await?.ok_or_else(|| anyhow!("Error getting block hash"))?;
Expand Down
Binary file modified crates/threshold-signature-server/entropy_metadata.scale
Binary file not shown.
9 changes: 4 additions & 5 deletions crates/threshold-signature-server/src/helpers/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,16 +184,15 @@ pub async fn spawn_testing_validators(
pub async fn remove_program(
entropy_api: &OnlineClient<EntropyConfig>,
rpc: &LegacyRpcMethods<EntropyConfig>,
program_modification_account: &sr25519::Pair,
deployer: &sr25519::Pair,
program_hash: <EntropyConfig as Config>::Hash,
) {
// update/set their programs
let remove_program_tx = entropy::tx().programs().remove_program(program_hash);
let account_id32: AccountId32 = program_modification_account.public().into();
let account_id32: AccountId32 = deployer.public().into();
let account_id: <EntropyConfig as Config>::AccountId = account_id32.into();

let program_modification_account =
PairSigner::<EntropyConfig, sr25519::Pair>::new(program_modification_account.clone());
let deployer = PairSigner::<EntropyConfig, sr25519::Pair>::new(deployer.clone());

let block_hash = rpc.chain_get_block_hash(None).await.unwrap().unwrap();
let nonce_call = entropy::apis().account_nonce_api().account_nonce(account_id.clone());
Expand All @@ -203,7 +202,7 @@ pub async fn remove_program(
.create_partial_signed_with_nonce(&remove_program_tx, nonce.into(), Default::default())
.unwrap();
let signer_payload = partial_tx.signer_payload();
let signature = program_modification_account.sign(&signer_payload);
let signature = deployer.sign(&signer_payload);

let tx = partial_tx.sign_with_address_and_signature(&account_id.into(), &signature);
tx.submit_and_watch()
Expand Down
20 changes: 10 additions & 10 deletions pallets/programs/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ benchmarks! {
hash_input.extend(&configuration_interface);

let program_hash = T::Hashing::hash(&hash_input);
let program_modification_account: T::AccountId = whitelisted_caller();
let deployer: T::AccountId = whitelisted_caller();
let sig_req_account: T::AccountId = whitelisted_caller();

let value = CurrencyOf::<T>::minimum_balance().saturating_mul(1_000_000_000u32.into());
let _ = CurrencyOf::<T>::make_free_balance_be(&program_modification_account, value);
let _ = CurrencyOf::<T>::make_free_balance_be(&deployer, value);

}: _(RawOrigin::Signed(program_modification_account.clone()), program.clone(), configuration_interface.clone())
}: _(RawOrigin::Signed(deployer.clone()), program.clone(), configuration_interface.clone())
verify {
assert_last_event::<T>(
Event::<T>::ProgramCreated {
program_modification_account,
deployer,
program_hash,
configuration_interface
}.into()
Expand All @@ -76,23 +76,23 @@ benchmarks! {
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 deployer: T::AccountId = whitelisted_caller();

let value = CurrencyOf::<T>::minimum_balance().saturating_mul(1_000_000_000u32.into());
let _ = CurrencyOf::<T>::make_free_balance_be(&program_modification_account, value);
<Programs<T>>::insert(program_hash.clone(), ProgramInfo {bytecode: program, configuration_interface, program_modification_account: program_modification_account.clone(), ref_counter: 0u128});
let _ = CurrencyOf::<T>::make_free_balance_be(&deployer, value);
<Programs<T>>::insert(program_hash.clone(), ProgramInfo {bytecode: program, configuration_interface, deployer: deployer.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();
program_hashes.push(program_hash);

let bounded_program_hashes: BoundedVec<T::Hash, T::MaxOwnedPrograms> = BoundedVec::try_from(program_hashes).unwrap();
<OwnedPrograms<T>>::insert(program_modification_account.clone(), bounded_program_hashes);
}: _(RawOrigin::Signed(program_modification_account.clone()), program_hash.clone())
<OwnedPrograms<T>>::insert(deployer.clone(), bounded_program_hashes);
}: _(RawOrigin::Signed(deployer.clone()), program_hash.clone())
verify {
assert_last_event::<T>(
Event::<T>::ProgramRemoved {
program_modification_account,
deployer,
old_program_hash: program_hash
}.into()
);
Expand Down
56 changes: 25 additions & 31 deletions pallets/programs/src/lib.rs
HCastano marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
//!
//! ## Overview
//!
//! This pallet stores the WebAssembly (Wasm) program bytecode on-chain and allows users to change
//! it as required.
//! This pallet stores the WebAssembly (Wasm) program bytecode on-chain at the hash of the program code and interface
//!
//! A program is a piece of logic which is run by the network when a signing operation is requested.
//! The succesful execution of a program indicates to validators on the network that they should
Expand All @@ -32,8 +31,8 @@
//!
//! #### Public
//!
//! `update_program` - Allows a program-modification account to change the program associated with
//! a particular signature-request account.
//! `set_program` - Allows a deployer account to create a program.
//! `remove_program` - Allows a deployer to remove a program if not in use.

#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet::*;
Expand Down Expand Up @@ -90,20 +89,21 @@ pub mod pallet {
#[pallet::without_storage_info]
pub struct Pallet<T>(_);

/// Information on the program, the bytecode and the account allowed to modify it
/// Information on the program
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)]
pub struct ProgramInfo<AccountId> {
/// The bytecode of the program.
pub bytecode: Vec<u8>,
/// The type definition of the program
pub configuration_interface: Vec<u8>,
/// Owners of the program
pub program_modification_account: AccountId,
/// Deployer of the program
pub deployer: AccountId,
/// Accounts that use this program
pub ref_counter: u128,
}

/// Stores the program bytecode for a given signature-request account.
/// Stores the program info for a given program hash.
/// A program hash is a combination of the bytecode and configuration_interface
#[pallet::storage]
#[pallet::getter(fn programs)]
pub type Programs<T: Config> =
Expand All @@ -125,8 +125,8 @@ pub mod pallet {
pub enum Event<T: Config> {
/// The bytecode of a program was created.
ProgramCreated {
/// The program modification account which updated the program.
program_modification_account: T::AccountId,
/// The deployer account which created the program.
deployer: T::AccountId,

/// The new program hash.
program_hash: T::Hash,
Expand All @@ -136,8 +136,8 @@ pub mod pallet {
},
/// The bytecode of a program was removed.
ProgramRemoved {
/// The program modification account which removed the program.
program_modification_account: T::AccountId,
/// The depoyer account which removed the program.
deployer: T::AccountId,

/// The hash of the removed program.
old_program_hash: T::Hash,
Expand All @@ -162,17 +162,17 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Sets the program and uses hash as key.
/// Sets the program and uses hash of program and configuration_interface as key.
///
/// Note that the caller becomes the program-modification account.
/// Note that the caller becomes the deployer account.
#[pallet::call_index(0)]
#[pallet::weight({<T as Config>::WeightInfo::set_program()})]
pub fn set_program(
origin: OriginFor<T>,
new_program: Vec<u8>,
configuration_interface: Vec<u8>,
) -> DispatchResult {
let program_modification_account = ensure_signed(origin)?;
let deployer = ensure_signed(origin)?;
let mut hash_input = vec![];
hash_input.extend(&new_program);
hash_input.extend(&configuration_interface);
Expand All @@ -184,19 +184,19 @@ pub mod pallet {
);
ensure!(!Programs::<T>::contains_key(program_hash), Error::<T>::ProgramAlreadySet);

Self::reserve_program_deposit(&program_modification_account, new_program_length)?;
Self::reserve_program_deposit(&deployer, new_program_length)?;

Programs::<T>::insert(
program_hash,
&ProgramInfo {
bytecode: new_program.clone(),
configuration_interface: configuration_interface.clone(),
program_modification_account: program_modification_account.clone(),
deployer: deployer.clone(),
ref_counter: 0u128,
},
);
OwnedPrograms::<T>::try_mutate(
&program_modification_account,
&deployer,
|owned_programs| -> Result<(), DispatchError> {
owned_programs
.try_push(program_hash)
Expand All @@ -205,7 +205,7 @@ pub mod pallet {
},
)?;
Self::deposit_event(Event::ProgramCreated {
program_modification_account,
deployer,
program_hash,
configuration_interface,
});
Expand All @@ -214,28 +214,25 @@ pub mod pallet {

/// Removes a program at a specific hash
///
/// Caller must be the program modification account for said program.
/// Caller must be the deployer account for said program.
#[pallet::call_index(1)]
#[pallet::weight({<T as Config>::WeightInfo::remove_program( <T as Config>::MaxOwnedPrograms::get())})]
pub fn remove_program(
origin: OriginFor<T>,
program_hash: T::Hash,
) -> DispatchResultWithPostInfo {
let program_modification_account = ensure_signed(origin)?;
let deployer = ensure_signed(origin)?;
let old_program_info =
Self::programs(program_hash).ok_or(Error::<T>::NoProgramDefined)?;
ensure!(
old_program_info.program_modification_account == program_modification_account,
Error::<T>::NotAuthorized
);
ensure!(old_program_info.deployer == deployer, Error::<T>::NotAuthorized);
ensure!(old_program_info.ref_counter == 0, Error::<T>::ProgramInUse);
Self::unreserve_program_deposit(
&old_program_info.program_modification_account,
&old_program_info.deployer,
old_program_info.bytecode.len() + old_program_info.configuration_interface.len(),
);
let mut owned_programs_length = 0;
OwnedPrograms::<T>::try_mutate(
&program_modification_account,
&deployer,
|owned_programs| -> Result<(), DispatchError> {
owned_programs_length = owned_programs.len();
let pos = owned_programs
Expand All @@ -247,10 +244,7 @@ pub mod pallet {
},
)?;
Programs::<T>::remove(program_hash);
Self::deposit_event(Event::ProgramRemoved {
program_modification_account,
old_program_hash: program_hash,
});
Self::deposit_event(Event::ProgramRemoved { deployer, old_program_hash: program_hash });
Ok(Some(<T as Config>::WeightInfo::remove_program(owned_programs_length as u32)).into())
}
}
Expand Down
6 changes: 3 additions & 3 deletions pallets/programs/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn set_program() {
let program_result = ProgramInfo {
bytecode: program.clone(),
configuration_interface: configuration_interface.clone(),
program_modification_account: PROGRAM_MODIFICATION_ACCOUNT,
deployer: PROGRAM_MODIFICATION_ACCOUNT,
ref_counter: 0u128,
};
assert_eq!(
Expand Down Expand Up @@ -139,7 +139,7 @@ fn remove_program() {
"Program bytecode gets set"
);
assert_eq!(
ProgramsPallet::programs(program_hash).unwrap().program_modification_account,
ProgramsPallet::programs(program_hash).unwrap().deployer,
PROGRAM_MODIFICATION_ACCOUNT,
"Program modification account gets set"
);
Expand Down Expand Up @@ -178,7 +178,7 @@ fn remove_program_fails_ref_count() {
ProgramInfo {
bytecode: program,
configuration_interface,
program_modification_account: PROGRAM_MODIFICATION_ACCOUNT,
deployer: PROGRAM_MODIFICATION_ACCOUNT,
ref_counter: 1u128,
},
);
Expand Down
2 changes: 1 addition & 1 deletion pallets/propagation/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn knows_how_to_mock_several_http_calls() {
ProgramInfo {
bytecode: vec![],
configuration_interface: vec![],
program_modification_account: 1,
deployer: 1,
ref_counter: 0,
},
);
Expand Down
Loading