iota_core/authority/
epoch_start_configuration.rs1use std::fmt;
6
7use enum_dispatch::enum_dispatch;
8use iota_config::{ExecutionCacheConfig, NodeConfig};
9use iota_types::{
10 authenticator_state::get_authenticator_state_obj_initial_shared_version,
11 base_types::SequenceNumber,
12 bridge::{get_bridge_obj_initial_shared_version, is_bridge_committee_initiated},
13 deny_list_v1::get_deny_list_obj_initial_shared_version,
14 epoch_data::EpochData,
15 error::IotaResult,
16 iota_system_state::epoch_start_iota_system_state::{
17 EpochStartSystemState, EpochStartSystemStateTrait,
18 },
19 messages_checkpoint::{CheckpointDigest, CheckpointTimestamp},
20 randomness_state::get_randomness_state_obj_initial_shared_version,
21 storage::ObjectStore,
22};
23use serde::{Deserialize, Serialize};
24
25use crate::execution_cache::{ExecutionCacheConfigType, choose_execution_cache};
26
27#[enum_dispatch]
28pub trait EpochStartConfigTrait {
29 fn epoch_digest(&self) -> CheckpointDigest;
30 fn epoch_start_state(&self) -> &EpochStartSystemState;
31 fn flags(&self) -> &[EpochFlag];
32 fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber>;
33 fn randomness_obj_initial_shared_version(&self) -> SequenceNumber;
34 fn coin_deny_list_obj_initial_shared_version(&self) -> SequenceNumber;
35 fn bridge_obj_initial_shared_version(&self) -> Option<SequenceNumber>;
36 fn bridge_committee_initiated(&self) -> bool;
37
38 fn execution_cache_type(&self) -> ExecutionCacheConfigType {
39 if self.flags().contains(&EpochFlag::WritebackCacheEnabled) {
40 ExecutionCacheConfigType::WritebackCache
41 } else {
42 ExecutionCacheConfigType::PassthroughCache
43 }
44 }
45}
46
47#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
56pub enum EpochFlag {
57 WritebackCacheEnabled = 0,
58}
59
60impl EpochFlag {
61 pub fn default_flags_for_new_epoch(config: &NodeConfig) -> Vec<Self> {
62 Self::default_flags_impl(&config.execution_cache)
63 }
64
65 pub fn default_for_no_config() -> Vec<Self> {
68 Self::default_flags_impl(&Default::default())
69 }
70
71 fn default_flags_impl(cache_config: &ExecutionCacheConfig) -> Vec<Self> {
72 let mut new_flags = vec![];
73
74 if matches!(
75 choose_execution_cache(cache_config),
76 ExecutionCacheConfigType::WritebackCache
77 ) {
78 new_flags.push(EpochFlag::WritebackCacheEnabled);
79 }
80
81 new_flags
82 }
83}
84
85impl fmt::Display for EpochFlag {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 match self {
90 EpochFlag::WritebackCacheEnabled => write!(f, "WritebackCacheEnabled"),
91 }
92 }
93}
94
95#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
97#[enum_dispatch(EpochStartConfigTrait)]
98pub enum EpochStartConfiguration {
99 V1(EpochStartConfigurationV1),
100}
101
102impl EpochStartConfiguration {
103 pub fn new(
104 system_state: EpochStartSystemState,
105 epoch_digest: CheckpointDigest,
106 object_store: &dyn ObjectStore,
107 initial_epoch_flags: Vec<EpochFlag>,
108 ) -> IotaResult<Self> {
109 let authenticator_obj_initial_shared_version =
110 get_authenticator_state_obj_initial_shared_version(object_store)?;
111 let randomness_obj_initial_shared_version =
112 get_randomness_state_obj_initial_shared_version(object_store)?;
113 let coin_deny_list_obj_initial_shared_version =
114 get_deny_list_obj_initial_shared_version(object_store)?;
115 let bridge_obj_initial_shared_version =
116 get_bridge_obj_initial_shared_version(object_store)?;
117 let bridge_committee_initiated = is_bridge_committee_initiated(object_store)?;
118 Ok(Self::V1(EpochStartConfigurationV1 {
119 system_state,
120 epoch_digest,
121 flags: initial_epoch_flags,
122 authenticator_obj_initial_shared_version,
123 randomness_obj_initial_shared_version,
124 coin_deny_list_obj_initial_shared_version,
125 bridge_obj_initial_shared_version,
126 bridge_committee_initiated,
127 }))
128 }
129
130 #[expect(unreachable_patterns)]
131 pub fn new_at_next_epoch_for_testing(&self) -> Self {
132 match self {
135 Self::V1(config) => Self::V1(EpochStartConfigurationV1 {
136 system_state: config.system_state.new_at_next_epoch_for_testing(),
137 epoch_digest: config.epoch_digest,
138 flags: config.flags.clone(),
139 authenticator_obj_initial_shared_version: config
140 .authenticator_obj_initial_shared_version,
141 randomness_obj_initial_shared_version: config.randomness_obj_initial_shared_version,
142 coin_deny_list_obj_initial_shared_version: config
143 .coin_deny_list_obj_initial_shared_version,
144 bridge_obj_initial_shared_version: config.bridge_obj_initial_shared_version,
145 bridge_committee_initiated: config.bridge_committee_initiated,
146 }),
147 _ => panic!(
148 "This function is only implemented for the latest version of EpochStartConfiguration"
149 ),
150 }
151 }
152
153 pub fn epoch_data(&self) -> EpochData {
154 EpochData::new(
155 self.epoch_start_state().epoch(),
156 self.epoch_start_state().epoch_start_timestamp_ms(),
157 self.epoch_digest(),
158 )
159 }
160
161 pub fn epoch_start_timestamp_ms(&self) -> CheckpointTimestamp {
162 self.epoch_start_state().epoch_start_timestamp_ms()
163 }
164}
165
166#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
167pub struct EpochStartConfigurationV1 {
168 system_state: EpochStartSystemState,
169 epoch_digest: CheckpointDigest,
170 flags: Vec<EpochFlag>,
171 authenticator_obj_initial_shared_version: Option<SequenceNumber>,
173 randomness_obj_initial_shared_version: SequenceNumber,
174 coin_deny_list_obj_initial_shared_version: SequenceNumber,
175 bridge_obj_initial_shared_version: Option<SequenceNumber>,
176 bridge_committee_initiated: bool,
177}
178
179impl EpochStartConfigTrait for EpochStartConfigurationV1 {
180 fn epoch_digest(&self) -> CheckpointDigest {
181 self.epoch_digest
182 }
183
184 fn epoch_start_state(&self) -> &EpochStartSystemState {
185 &self.system_state
186 }
187
188 fn flags(&self) -> &[EpochFlag] {
189 &self.flags
190 }
191
192 fn authenticator_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
193 self.authenticator_obj_initial_shared_version
194 }
195
196 fn randomness_obj_initial_shared_version(&self) -> SequenceNumber {
197 self.randomness_obj_initial_shared_version
198 }
199
200 fn coin_deny_list_obj_initial_shared_version(&self) -> SequenceNumber {
201 self.coin_deny_list_obj_initial_shared_version
202 }
203
204 fn bridge_obj_initial_shared_version(&self) -> Option<SequenceNumber> {
205 self.bridge_obj_initial_shared_version
206 }
207
208 fn bridge_committee_initiated(&self) -> bool {
209 self.bridge_committee_initiated
210 }
211}