2019-03-14 07:55:41 -07:00
|
|
|
use crate::id;
|
|
|
|
use crate::ConfigState;
|
2019-07-08 16:33:56 -07:00
|
|
|
use bincode::serialize;
|
|
|
|
use serde_derive::{Deserialize, Serialize};
|
2019-03-23 20:12:27 -07:00
|
|
|
use solana_sdk::instruction::{AccountMeta, Instruction};
|
2019-03-14 07:55:41 -07:00
|
|
|
use solana_sdk::pubkey::Pubkey;
|
2019-07-08 16:33:56 -07:00
|
|
|
use solana_sdk::short_vec;
|
2019-04-03 08:45:57 -07:00
|
|
|
use solana_sdk::system_instruction;
|
2019-03-14 07:55:41 -07:00
|
|
|
|
2019-07-08 16:33:56 -07:00
|
|
|
/// 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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-03 08:45:57 -07:00
|
|
|
/// Create a new, empty configuration account
|
|
|
|
pub fn create_account<T: ConfigState>(
|
|
|
|
from_account_pubkey: &Pubkey,
|
|
|
|
config_account_pubkey: &Pubkey,
|
|
|
|
lamports: u64,
|
2019-07-08 16:33:56 -07:00
|
|
|
keys: Vec<(Pubkey, bool)>,
|
2019-04-03 08:45:57 -07:00
|
|
|
) -> Instruction {
|
2019-07-08 16:33:56 -07:00
|
|
|
let space = T::max_space() + ConfigKeys::serialized_size(keys) as u64;
|
2019-04-03 08:45:57 -07:00
|
|
|
system_instruction::create_account(
|
|
|
|
from_account_pubkey,
|
|
|
|
config_account_pubkey,
|
|
|
|
lamports,
|
2019-07-08 16:33:56 -07:00
|
|
|
space,
|
2019-04-03 08:45:57 -07:00
|
|
|
&id(),
|
|
|
|
)
|
|
|
|
}
|
2019-03-14 07:55:41 -07:00
|
|
|
|
2019-04-03 08:45:57 -07:00
|
|
|
/// Store new data in a configuration account
|
2019-07-08 16:33:56 -07:00
|
|
|
pub fn store<T: ConfigState>(
|
|
|
|
config_account_pubkey: &Pubkey,
|
2019-07-09 12:37:18 -07:00
|
|
|
is_config_signer: bool,
|
2019-07-08 16:33:56 -07:00
|
|
|
keys: Vec<(Pubkey, bool)>,
|
|
|
|
data: &T,
|
|
|
|
) -> Instruction {
|
2019-07-09 12:37:18 -07:00
|
|
|
let mut account_metas = vec![AccountMeta::new(*config_account_pubkey, is_config_signer)];
|
2019-07-08 16:33:56 -07:00
|
|
|
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)
|
2019-03-14 07:55:41 -07:00
|
|
|
}
|