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, Serializable};
9
10use crate::store::{SettingScope, Store, StoreError};
11use crate::{Client, ClientError};
12
13impl<AUTH> Client<AUTH> {
14    /// Stores a protocol configuration for transaction execution and note screening. The
15    /// configuration must match the commitment in the transaction reference block.
16    pub async fn add_protocol_config(&self, config: ProtocolConfig) -> Result<(), ClientError> {
17        self.store
18            .set_setting(
19                SettingScope::Client,
20                config_key(config.to_commitment()),
21                config.to_bytes(),
22            )
23            .await?;
24        Ok(())
25    }
26
27    /// Returns the stored protocol configuration for the specified commitment.
28    pub async fn get_protocol_config(
29        &self,
30        commitment: Word,
31    ) -> Result<ProtocolConfig, ClientError> {
32        Ok(load_protocol_config(self.store.as_ref(), commitment).await?)
33    }
34}
35
36fn config_key(commitment: Word) -> alloc::string::String {
37    format!("protocol_config:{commitment}")
38}
39
40pub(crate) async fn load_protocol_config(
41    store: &dyn Store,
42    commitment: Word,
43) -> Result<ProtocolConfig, StoreError> {
44    let bytes = store
45        .get_setting(SettingScope::Client, config_key(commitment))
46        .await?
47        .ok_or(StoreError::ProtocolConfigNotFound(commitment))?;
48    let config = ProtocolConfig::read_from_bytes(&bytes)?;
49    if config.to_commitment() != commitment {
50        return Err(StoreError::ProtocolConfigCommitmentMismatch(commitment));
51    }
52    Ok(config)
53}