Skip to main content

miden_client/
protocol_config.rs

1//! Stores protocol configurations by their block header commitments.
2
3use alloc::format;
4
5use miden_protocol::Word;
6pub use miden_protocol::errors::ProtocolConfigError;
7pub use miden_protocol::protocol_config::{NextProtocolConfig, ProtocolConfig};
8use miden_protocol::utils::serde::Deserializable;
9#[cfg(feature = "testing")]
10use miden_protocol::utils::serde::Serializable;
11
12use crate::store::{SettingScope, Store, StoreError};
13use crate::{Client, ClientError};
14
15impl<AUTH> Client<AUTH> {
16    /// Stores a protocol configuration for transaction execution and note screening, skipping the
17    /// sync that normally delivers it.
18    ///
19    /// A client that reaches a node gets its configurations from [`Client::sync_state`]. This is
20    /// for a client that cannot sync, such as one backed by a mock chain.
21    #[cfg(feature = "testing")]
22    pub async fn seed_protocol_config(&self, config: ProtocolConfig) -> Result<(), ClientError> {
23        self.store
24            .set_setting(
25                SettingScope::Client,
26                protocol_config_setting_key(config.to_commitment()),
27                config.to_bytes(),
28            )
29            .await?;
30        Ok(())
31    }
32
33    /// Returns the stored protocol configuration for the specified commitment.
34    pub async fn get_protocol_config(
35        &self,
36        commitment: Word,
37    ) -> Result<ProtocolConfig, ClientError> {
38        Ok(load_protocol_config(self.store.as_ref(), commitment).await?)
39    }
40}
41
42/// Returns the settings key that holds the protocol configuration for `commitment`.
43///
44/// A [`Store`] implementation needs this key to persist a configuration a sync returned.
45pub fn protocol_config_setting_key(commitment: Word) -> alloc::string::String {
46    format!("protocol_config:{commitment}")
47}
48
49pub(crate) async fn load_protocol_config(
50    store: &dyn Store,
51    commitment: Word,
52) -> Result<ProtocolConfig, StoreError> {
53    let bytes = store
54        .get_setting(SettingScope::Client, protocol_config_setting_key(commitment))
55        .await?
56        .ok_or(StoreError::ProtocolConfigNotFound(commitment))?;
57    let config = ProtocolConfig::read_from_bytes(&bytes)?;
58    if config.to_commitment() != commitment {
59        return Err(StoreError::ProtocolConfigCommitmentMismatch(commitment));
60    }
61    Ok(config)
62}