diem_types/on_chain_config/
mod.rs1use crate::{account_address::AccountAddress, event::EventKey};
9use anyhow::{format_err, Result};
10use serde::de::DeserializeOwned;
11use std::{collections::HashMap, fmt, sync::Arc};
12
13mod validator_set;
14
15pub use self::validator_set::ValidatorSet;
16
17#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
18pub struct ConfigID(&'static str, &'static str);
19
20impl fmt::Display for ConfigID {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 write!(
23 f,
24 "OnChain config ID [address: {}, identifier: {}]",
25 self.0, self.1
26 )
27 }
28}
29
30pub const ON_CHAIN_CONFIG_REGISTRY: &[ConfigID] = &[ValidatorSet::CONFIG_ID];
33
34#[derive(Clone, Debug, PartialEq)]
35pub struct OnChainConfigPayload {
36 epoch: u64,
37 configs: Arc<HashMap<ConfigID, Vec<u8>>>,
38}
39
40impl OnChainConfigPayload {
41 pub fn new(epoch: u64, configs: Arc<HashMap<ConfigID, Vec<u8>>>) -> Self {
42 Self { epoch, configs }
43 }
44
45 pub fn epoch(&self) -> u64 { self.epoch }
46
47 pub fn get<T: OnChainConfig>(&self) -> Result<T> {
48 let bytes = self.configs.get(&T::CONFIG_ID).ok_or_else(|| {
49 format_err!("[on-chain cfg] config not in payload")
50 })?;
51 T::deserialize_into_config(bytes)
52 }
53
54 pub fn configs(&self) -> &HashMap<ConfigID, Vec<u8>> { &self.configs }
55}
56
57impl fmt::Display for OnChainConfigPayload {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 let mut config_ids = "".to_string();
60 for id in self.configs.keys() {
61 config_ids += &id.to_string();
62 }
63 write!(
64 f,
65 "OnChainConfigPayload [epoch: {}, configs: {}]",
66 self.epoch, config_ids
67 )
68 }
69}
70
71pub trait OnChainConfig: Send + Sync + DeserializeOwned {
74 const ADDRESS: &'static str = "0xA550C18";
75 const IDENTIFIER: &'static str;
76 const CONFIG_ID: ConfigID = ConfigID(Self::ADDRESS, Self::IDENTIFIER);
77
78 fn deserialize_default_impl(bytes: &[u8]) -> Result<Self> {
79 bcs::from_bytes::<Self>(&bytes).map_err(|e| {
80 format_err!(
81 "[on-chain config] Failed to deserialize into config: {}",
82 e
83 )
84 })
85 }
86
87 fn deserialize_into_config(bytes: &[u8]) -> Result<Self> {
88 Self::deserialize_default_impl(bytes)
89 }
90}
91
92pub fn config_address() -> AccountAddress {
93 AccountAddress::from_hex_literal("0xA550C18")
94 .expect("failed to get address")
95}
96
97pub fn new_epoch_event_key() -> EventKey {
98 EventKey::new_from_address(&config_address(), 4)
99}