@@ -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
190362impl 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
325531impl 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 >
420693where
421694 S : ObjectStore + ?Sized ,
422695{
0 commit comments