Skip to content

Commit 3d65d4a

Browse files
committed
make IotaSystemStateSummary an enum
1 parent dc3e9a5 commit 3d65d4a

File tree

3 files changed

+289
-14
lines changed

3 files changed

+289
-14
lines changed

crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use super::{
1111
AdvanceEpochParams, IotaSystemStateTrait,
1212
epoch_start_iota_system_state::EpochStartValidatorInfoV1,
1313
get_validators_from_table_vec,
14-
iota_system_state_summary::{IotaSystemStateSummary, IotaValidatorSummary},
14+
iota_system_state_summary::{
15+
IotaSystemStateSummary, IotaSystemStateSummaryV1, IotaValidatorSummary,
16+
},
1517
};
1618
use crate::{
1719
balance::Balance,
@@ -631,7 +633,7 @@ impl IotaSystemStateTrait for IotaSystemStateV1 {
631633
epoch_start_timestamp_ms,
632634
extra_fields: _,
633635
} = self;
634-
IotaSystemStateSummary {
636+
IotaSystemStateSummary::V1(IotaSystemStateSummaryV1 {
635637
epoch,
636638
protocol_version,
637639
system_state_version,
@@ -645,8 +647,6 @@ impl IotaSystemStateTrait for IotaSystemStateV1 {
645647
safe_mode,
646648
safe_mode_storage_charges: safe_mode_storage_charges.value(),
647649
safe_mode_computation_charges: safe_mode_computation_rewards.value(),
648-
// all computation charges are burned in state v1.
649-
safe_mode_computation_charges_burned: safe_mode_computation_rewards.value(),
650650
safe_mode_storage_rebates,
651651
safe_mode_non_refundable_storage_fee,
652652
epoch_start_timestamp_ms,
@@ -679,7 +679,7 @@ impl IotaSystemStateTrait for IotaSystemStateV1 {
679679
validator_low_stake_threshold,
680680
validator_very_low_stake_threshold,
681681
validator_low_stake_grace_period,
682-
}
682+
})
683683
}
684684
}
685685

crates/iota-types/src/iota_system_state/iota_system_state_inner_v2.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use super::{
1010
epoch_start_iota_system_state::EpochStartValidatorInfoV1,
1111
get_validators_from_table_vec,
1212
iota_system_state_inner_v1::{StorageFundV1, SystemParametersV1, ValidatorSetV1, ValidatorV1},
13-
iota_system_state_summary::{IotaSystemStateSummary, IotaValidatorSummary},
13+
iota_system_state_summary::{
14+
IotaSystemStateSummary, IotaSystemStateSummaryV2, IotaValidatorSummary,
15+
},
1416
};
1517
use crate::{
1618
balance::Balance,
@@ -229,7 +231,7 @@ impl IotaSystemStateTrait for IotaSystemStateV2 {
229231
epoch_start_timestamp_ms,
230232
extra_fields: _,
231233
} = self;
232-
IotaSystemStateSummary {
234+
IotaSystemStateSummary::V2(IotaSystemStateSummaryV2 {
233235
epoch,
234236
protocol_version,
235237
system_state_version,
@@ -276,6 +278,6 @@ impl IotaSystemStateTrait for IotaSystemStateV2 {
276278
validator_low_stake_threshold,
277279
validator_very_low_stake_threshold,
278280
validator_low_stake_grace_period,
279-
}
281+
})
280282
}
281283
}

crates/iota-types/src/iota_system_state/iota_system_state_summary.rs

Lines changed: 279 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,186 @@ use crate::{
2020
storage::ObjectStore,
2121
};
2222

23-
/// This is the JSON-RPC type for the IOTA system state object.
24-
/// It flattens all fields to make them top-level fields such that it as minimum
25-
/// dependencies to the internal data structures of the IOTA system state type.
23+
/// This is the JSON-RPC type for IOTA system state objects.
24+
/// It is an enum type that can represent either V1 or V2 system state objects.
25+
pub enum IotaSystemStateSummary {
26+
V1(IotaSystemStateSummaryV1),
27+
V2(IotaSystemStateSummaryV2),
28+
}
29+
30+
/// This is the JSON-RPC type for the
31+
/// [`IotaSystemStateV1`](super::iota_system_state_inner_v1::IotaSystemStateV1)
32+
/// object. It flattens all fields to make them top-level fields such that it as
33+
/// minimum dependencies to the internal data structures of the IOTA system
34+
/// state type.
35+
#[serde_as]
36+
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
37+
#[serde(rename_all = "camelCase")]
38+
pub struct IotaSystemStateSummaryV1 {
39+
/// The current epoch ID, starting from 0.
40+
#[schemars(with = "BigInt<u64>")]
41+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
42+
pub epoch: u64,
43+
/// The current protocol version, starting from 1.
44+
#[schemars(with = "BigInt<u64>")]
45+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
46+
pub protocol_version: u64,
47+
/// The current version of the system state data structure type.
48+
#[schemars(with = "BigInt<u64>")]
49+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
50+
pub system_state_version: u64,
51+
/// The current IOTA supply.
52+
#[schemars(with = "BigInt<u64>")]
53+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
54+
pub iota_total_supply: u64,
55+
/// The `TreasuryCap<IOTA>` object ID.
56+
pub iota_treasury_cap_id: ObjectID,
57+
/// The storage rebates of all the objects on-chain stored in the storage
58+
/// fund.
59+
#[schemars(with = "BigInt<u64>")]
60+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
61+
pub storage_fund_total_object_storage_rebates: u64,
62+
/// The non-refundable portion of the storage fund coming from
63+
/// non-refundable storage rebates and any leftover
64+
/// staking rewards.
65+
#[schemars(with = "BigInt<u64>")]
66+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
67+
pub storage_fund_non_refundable_balance: u64,
68+
/// The reference gas price for the current epoch.
69+
#[schemars(with = "BigInt<u64>")]
70+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
71+
pub reference_gas_price: u64,
72+
/// Whether the system is running in a downgraded safe mode due to a
73+
/// non-recoverable bug. This is set whenever we failed to execute
74+
/// advance_epoch, and ended up executing advance_epoch_safe_mode.
75+
/// It can be reset once we are able to successfully execute advance_epoch.
76+
pub safe_mode: bool,
77+
/// Amount of storage charges accumulated (and not yet distributed) during
78+
/// safe mode.
79+
#[schemars(with = "BigInt<u64>")]
80+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
81+
pub safe_mode_storage_charges: u64,
82+
/// Amount of computation charges accumulated (and not yet distributed)
83+
/// during safe mode.
84+
#[schemars(with = "BigInt<u64>")]
85+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
86+
pub safe_mode_computation_charges: u64,
87+
/// Amount of storage rebates accumulated (and not yet burned) during safe
88+
/// mode.
89+
#[schemars(with = "BigInt<u64>")]
90+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
91+
pub safe_mode_storage_rebates: u64,
92+
/// Amount of non-refundable storage fee accumulated during safe mode.
93+
#[schemars(with = "BigInt<u64>")]
94+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
95+
pub safe_mode_non_refundable_storage_fee: u64,
96+
/// Unix timestamp of the current epoch start
97+
#[schemars(with = "BigInt<u64>")]
98+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
99+
pub epoch_start_timestamp_ms: u64,
100+
101+
// System parameters
102+
/// The duration of an epoch, in milliseconds.
103+
#[schemars(with = "BigInt<u64>")]
104+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
105+
pub epoch_duration_ms: u64,
106+
107+
/// Minimum number of active validators at any moment.
108+
/// We do not allow the number of validators in any epoch to go under this.
109+
#[schemars(with = "BigInt<u64>")]
110+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
111+
pub min_validator_count: u64,
112+
113+
/// Maximum number of active validators at any moment.
114+
/// We do not allow the number of validators in any epoch to go above this.
115+
#[schemars(with = "BigInt<u64>")]
116+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
117+
pub max_validator_count: u64,
118+
119+
/// Lower-bound on the amount of stake required to become a validator.
120+
#[schemars(with = "BigInt<u64>")]
121+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
122+
pub min_validator_joining_stake: u64,
123+
124+
/// Validators with stake amount below `validator_low_stake_threshold` are
125+
/// considered to have low stake and will be escorted out of the
126+
/// validator set after being below this threshold for more than
127+
/// `validator_low_stake_grace_period` number of epochs.
128+
#[schemars(with = "BigInt<u64>")]
129+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
130+
pub validator_low_stake_threshold: u64,
131+
132+
/// Validators with stake below `validator_very_low_stake_threshold` will be
133+
/// removed immediately at epoch change, no grace period.
134+
#[schemars(with = "BigInt<u64>")]
135+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
136+
pub validator_very_low_stake_threshold: u64,
137+
138+
/// A validator can have stake below `validator_low_stake_threshold`
139+
/// for this many epochs before being kicked out.
140+
#[schemars(with = "BigInt<u64>")]
141+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
142+
pub validator_low_stake_grace_period: u64,
143+
144+
// Validator set
145+
/// Total amount of stake from all active validators at the beginning of the
146+
/// epoch.
147+
#[schemars(with = "BigInt<u64>")]
148+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
149+
pub total_stake: u64,
150+
/// The list of active validators in the current epoch.
151+
pub active_validators: Vec<IotaValidatorSummary>,
152+
/// ID of the object that contains the list of new validators that will join
153+
/// at the end of the epoch.
154+
pub pending_active_validators_id: ObjectID,
155+
/// Number of new validators that will join at the end of the epoch.
156+
#[schemars(with = "BigInt<u64>")]
157+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
158+
pub pending_active_validators_size: u64,
159+
/// Removal requests from the validators. Each element is an index
160+
/// pointing to `active_validators`.
161+
#[schemars(with = "Vec<BigInt<u64>>")]
162+
#[serde_as(as = "Vec<Readable<BigInt<u64>, _>>")]
163+
pub pending_removals: Vec<u64>,
164+
/// ID of the object that maps from staking pool's ID to the iota address of
165+
/// a validator.
166+
pub staking_pool_mappings_id: ObjectID,
167+
/// Number of staking pool mappings.
168+
#[schemars(with = "BigInt<u64>")]
169+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
170+
pub staking_pool_mappings_size: u64,
171+
/// ID of the object that maps from a staking pool ID to the inactive
172+
/// validator that has that pool as its staking pool.
173+
pub inactive_pools_id: ObjectID,
174+
/// Number of inactive staking pools.
175+
#[schemars(with = "BigInt<u64>")]
176+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
177+
pub inactive_pools_size: u64,
178+
/// ID of the object that stores preactive validators, mapping their
179+
/// addresses to their `Validator` structs.
180+
pub validator_candidates_id: ObjectID,
181+
/// Number of preactive validators.
182+
#[schemars(with = "BigInt<u64>")]
183+
#[serde_as(as = "Readable<BigInt<u64>, _>")]
184+
pub validator_candidates_size: u64,
185+
/// Map storing the number of epochs for which each validator has been below
186+
/// the low stake threshold.
187+
#[schemars(with = "Vec<(IotaAddress, BigInt<u64>)>")]
188+
#[serde_as(as = "Vec<(_, Readable<BigInt<u64>, _>)>")]
189+
pub at_risk_validators: Vec<(IotaAddress, u64)>,
190+
/// A map storing the records of validator reporting each other.
191+
pub validator_report_records: Vec<(IotaAddress, Vec<IotaAddress>)>,
192+
}
26193

194+
/// This is the JSON-RPC type for the
195+
/// [`IotaSystemStateV2`](super::iota_system_state_inner_v2::IotaSystemStateV1)
196+
/// object. It flattens all fields to make them top-level fields such that it as
197+
/// minimum dependencies to the internal data structures of the IOTA system
198+
/// state type.
27199
#[serde_as]
28200
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
29201
#[serde(rename_all = "camelCase")]
30-
pub struct IotaSystemStateSummary {
202+
pub struct IotaSystemStateSummaryV2 {
31203
/// The current epoch ID, starting from 0.
32204
#[schemars(with = "BigInt<u64>")]
33205
#[serde_as(as = "Readable<BigInt<u64>, _>")]
@@ -188,6 +360,40 @@ pub struct IotaSystemStateSummary {
188360
}
189361

190362
impl IotaSystemStateSummary {
363+
pub fn get_iota_committee_for_benchmarking(&self) -> CommitteeWithNetworkMetadata {
364+
match self {
365+
Self::V1(v1) => v1.get_iota_committee_for_benchmarking(),
366+
Self::V2(v2) => v2.get_iota_committee_for_benchmarking(),
367+
}
368+
}
369+
}
370+
371+
impl IotaSystemStateSummaryV1 {
372+
pub fn get_iota_committee_for_benchmarking(&self) -> CommitteeWithNetworkMetadata {
373+
let validators = self
374+
.active_validators
375+
.iter()
376+
.map(|validator| {
377+
let name = AuthorityName::from_bytes(&validator.authority_pubkey_bytes).unwrap();
378+
(
379+
name,
380+
(
381+
validator.voting_power,
382+
NetworkMetadata {
383+
network_address: Multiaddr::try_from(validator.net_address.clone())
384+
.unwrap(),
385+
primary_address: Multiaddr::try_from(validator.primary_address.clone())
386+
.unwrap(),
387+
},
388+
),
389+
)
390+
})
391+
.collect();
392+
CommitteeWithNetworkMetadata::new(self.epoch, validators)
393+
}
394+
}
395+
396+
impl IotaSystemStateSummaryV2 {
191397
pub fn get_iota_committee_for_benchmarking(&self) -> CommitteeWithNetworkMetadata {
192398
let validators = self
193399
.active_validators
@@ -324,7 +530,7 @@ pub struct IotaValidatorSummary {
324530

325531
impl Default for IotaSystemStateSummary {
326532
fn default() -> Self {
327-
Self {
533+
Self::V2(IotaSystemStateSummaryV2 {
328534
epoch: 0,
329535
protocol_version: 1,
330536
system_state_version: 1,
@@ -360,7 +566,7 @@ impl Default for IotaSystemStateSummary {
360566
validator_candidates_size: 0,
361567
at_risk_validators: vec![],
362568
validator_report_records: vec![],
363-
}
569+
})
364570
}
365571
}
366572

@@ -417,6 +623,73 @@ pub fn get_validator_by_pool_id<S>(
417623
system_state_summary: &IotaSystemStateSummary,
418624
pool_id: ObjectID,
419625
) -> Result<IotaValidatorSummary, IotaError>
626+
where
627+
S: ObjectStore + ?Sized,
628+
{
629+
match system_state_summary {
630+
IotaSystemStateSummary::V1(summary) => {
631+
get_validator_by_pool_id_v1(object_store, system_state, summary, pool_id)
632+
}
633+
IotaSystemStateSummary::V2(summary) => {
634+
get_validator_by_pool_id_v2(object_store, system_state, summary, pool_id)
635+
}
636+
}
637+
}
638+
639+
fn get_validator_by_pool_id_v1<S>(
640+
object_store: &S,
641+
system_state: &IotaSystemState,
642+
system_state_summary: &IotaSystemStateSummaryV1,
643+
pool_id: ObjectID,
644+
) -> Result<IotaValidatorSummary, IotaError>
645+
where
646+
S: ObjectStore + ?Sized,
647+
{
648+
// First try to find in active validator set.
649+
let active_validator = system_state_summary
650+
.active_validators
651+
.iter()
652+
.find(|v| v.staking_pool_id == pool_id);
653+
if let Some(active) = active_validator {
654+
return Ok(active.clone());
655+
}
656+
// Then try to find in pending active validator set.
657+
let pending_active_validators = system_state.get_pending_active_validators(object_store)?;
658+
let pending_active = pending_active_validators
659+
.iter()
660+
.find(|v| v.staking_pool_id == pool_id);
661+
if let Some(pending) = pending_active {
662+
return Ok(pending.clone());
663+
}
664+
// After that try to find in inactive pools.
665+
let inactive_table_id = system_state_summary.inactive_pools_id;
666+
if let Ok(inactive) =
667+
get_validator_from_table(&object_store, inactive_table_id, &ID::new(pool_id))
668+
{
669+
return Ok(inactive);
670+
}
671+
// Finally look up the candidates pool.
672+
let candidate_address: IotaAddress = get_dynamic_field_from_store(
673+
&object_store,
674+
system_state_summary.staking_pool_mappings_id,
675+
&ID::new(pool_id),
676+
)
677+
.map_err(|err| {
678+
IotaError::IotaSystemStateRead(format!(
679+
"Failed to load candidate address from pool mappings: {:?}",
680+
err
681+
))
682+
})?;
683+
let candidate_table_id = system_state_summary.validator_candidates_id;
684+
get_validator_from_table(&object_store, candidate_table_id, &candidate_address)
685+
}
686+
687+
fn get_validator_by_pool_id_v2<S>(
688+
object_store: &S,
689+
system_state: &IotaSystemState,
690+
system_state_summary: &IotaSystemStateSummaryV2,
691+
pool_id: ObjectID,
692+
) -> Result<IotaValidatorSummary, IotaError>
420693
where
421694
S: ObjectStore + ?Sized,
422695
{

0 commit comments

Comments
 (0)