Update config program to accommodate multiple signers (#4946)
* Update config program to accommodate multiple signers * Update install CLI * Remove account_type u32; add handling for unsigned keys in list * ConfigKeys doc
This commit is contained in:
@@ -1,26 +1,56 @@
|
||||
use crate::id;
|
||||
use crate::ConfigState;
|
||||
use bincode::serialize;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use solana_sdk::instruction::{AccountMeta, Instruction};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::short_vec;
|
||||
use solana_sdk::system_instruction;
|
||||
|
||||
/// A collection of keys to be stored in Config account data.
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
pub struct ConfigKeys {
|
||||
// Each key tuple comprises a unique `Pubkey` identifier,
|
||||
// and `bool` whether that key is a signer of the data
|
||||
#[serde(with = "short_vec")]
|
||||
pub keys: Vec<(Pubkey, bool)>,
|
||||
}
|
||||
|
||||
impl ConfigKeys {
|
||||
pub fn serialized_size(keys: Vec<(Pubkey, bool)>) -> usize {
|
||||
serialize(&ConfigKeys { keys })
|
||||
.unwrap_or_else(|_| vec![])
|
||||
.len()
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new, empty configuration account
|
||||
pub fn create_account<T: ConfigState>(
|
||||
from_account_pubkey: &Pubkey,
|
||||
config_account_pubkey: &Pubkey,
|
||||
lamports: u64,
|
||||
keys: Vec<(Pubkey, bool)>,
|
||||
) -> Instruction {
|
||||
let space = T::max_space() + ConfigKeys::serialized_size(keys) as u64;
|
||||
system_instruction::create_account(
|
||||
from_account_pubkey,
|
||||
config_account_pubkey,
|
||||
lamports,
|
||||
T::max_space(),
|
||||
space,
|
||||
&id(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Store new data in a configuration account
|
||||
pub fn store<T: ConfigState>(config_account_pubkey: &Pubkey, data: &T) -> Instruction {
|
||||
let account_metas = vec![AccountMeta::new(*config_account_pubkey, true)];
|
||||
Instruction::new(id(), data, account_metas)
|
||||
pub fn store<T: ConfigState>(
|
||||
config_account_pubkey: &Pubkey,
|
||||
keys: Vec<(Pubkey, bool)>,
|
||||
data: &T,
|
||||
) -> Instruction {
|
||||
let mut account_metas = vec![AccountMeta::new(*config_account_pubkey, true)];
|
||||
for (signer_pubkey, _) in keys.iter().filter(|(_, is_signer)| *is_signer) {
|
||||
account_metas.push(AccountMeta::new(*signer_pubkey, true));
|
||||
}
|
||||
let account_data = (ConfigKeys { keys }, data);
|
||||
Instruction::new(id(), &account_data, account_metas)
|
||||
}
|
||||
|
Reference in New Issue
Block a user