gemachain_config_program/
lib.rs

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