solana_config_program/
lib.rs

1#![allow(clippy::integer_arithmetic)]
2pub mod config_instruction;
3pub mod config_processor;
4pub mod date_instruction;
5
6pub use solana_sdk::config::program::id;
7use {
8    bincode::{deserialize, serialize, serialized_size},
9    serde_derive::{Deserialize, Serialize},
10    solana_sdk::{
11        account::{Account, AccountSharedData},
12        pubkey::Pubkey,
13        short_vec,
14        stake::config::Config as StakeConfig,
15    },
16};
17
18pub trait ConfigState: serde::Serialize + Default {
19    /// Maximum space that the serialized representation will require
20    fn max_space() -> u64;
21}
22
23// TODO move ConfigState into `solana_program` to implement trait locally
24impl ConfigState for StakeConfig {
25    fn max_space() -> u64 {
26        serialized_size(&StakeConfig::default()).unwrap()
27    }
28}
29
30/// A collection of keys to be stored in Config account data.
31#[derive(Debug, Default, Deserialize, Serialize)]
32pub struct ConfigKeys {
33    // Each key tuple comprises a unique `Pubkey` identifier,
34    // and `bool` whether that key is a signer of the data
35    #[serde(with = "short_vec")]
36    pub keys: Vec<(Pubkey, bool)>,
37}
38
39impl ConfigKeys {
40    pub fn serialized_size(keys: Vec<(Pubkey, bool)>) -> u64 {
41        serialized_size(&ConfigKeys { keys }).unwrap()
42    }
43}
44
45pub fn get_config_data(bytes: &[u8]) -> Result<&[u8], bincode::Error> {
46    deserialize::<ConfigKeys>(bytes)
47        .and_then(|keys| serialized_size(&keys))
48        .map(|offset| &bytes[offset as usize..])
49}
50
51// utility for pre-made Accounts
52pub fn create_config_account<T: ConfigState>(
53    keys: Vec<(Pubkey, bool)>,
54    config_data: &T,
55    lamports: u64,
56) -> AccountSharedData {
57    let mut data = serialize(&ConfigKeys { keys }).unwrap();
58    data.extend_from_slice(&serialize(config_data).unwrap());
59    AccountSharedData::from(Account {
60        lamports,
61        data,
62        owner: id(),
63        ..Account::default()
64    })
65}