iota_protocol_config/
lib.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::{
6    cell::RefCell,
7    cmp::min,
8    sync::atomic::{AtomicBool, Ordering},
9};
10
11use clap::*;
12use iota_protocol_config_macros::{
13    ProtocolConfigAccessors, ProtocolConfigFeatureFlagsGetters, ProtocolConfigOverride,
14};
15use move_vm_config::verifier::VerifierConfig;
16use serde::{Deserialize, Serialize};
17use serde_with::skip_serializing_none;
18use tracing::{info, warn};
19
20/// The minimum and maximum protocol versions supported by this build.
21const MIN_PROTOCOL_VERSION: u64 = 1;
22pub const MAX_PROTOCOL_VERSION: u64 = 25;
23
24/// Protocol version that IIP8 took effect.
25pub const PROTOCOL_VERSION_IIP8: u64 = 20;
26// Record history of protocol version allocations here:
27//
28// Version 1:  Original version.
29// Version 2:  Don't redistribute slashed staking rewards, fix computation of
30//             SystemEpochInfoEventV1.
31// Version 3:  Set the `relocate_event_module` to be true so that the module
32//             that is associated as the "sending module" for an event is
33//             relocated by linkage.
34//             Add `Clock` based unlock to `Timelock` objects.
35// Version 4:  Introduce the `max_type_to_layout_nodes` config that sets the
36//             maximal nodes which are allowed when converting to a type layout.
37// Version 5:  Introduce fixed protocol-defined base fee, IotaSystemStateV2 and
38//             SystemEpochInfoEventV2.
39//             Disallow adding new modules in `deps-only` packages.
40//             Improve gas/wall time efficiency of some Move stdlib vector
41//             functions.
42//             Add new gas model version to update charging of functions.
43//             Enable proper conversion of certain type argument errors in the
44//             execution layer.
45// Version 6:  Bound size of values created in the adapter.
46// Version 7:  Improve handling of stake withdrawal from candidate validators.
47// Version 8:  Variants as type nodes.
48//             Enable smart ancestor selection for testnet.
49//             Enable probing for accepted rounds in round prober for testnet.
50//             Switch to distributed vote scoring in consensus in testnet.
51//             Enable zstd compression for consensus tonic network in testnet.
52//             Enable consensus garbage collection for testnet
53//             Enable the new consensus commit rule for testnet.
54//             Enable min_free_execution_slot for the shared object congestion
55//             tracker in devnet.
56// Version 9:  Disable smart ancestor selection for the testnet.
57//             Enable zstd compression for consensus tonic network in mainnet.
58//             Enable passkey auth in multisig for devnet.
59//             Remove the iota-bridge from the framework.
60// Version 10: Enable min_free_execution_slot for the shared object congestion
61//             tracker in all networks.
62//             Increase the committee size to 80 on all networks.
63//             Enable round prober in consensus for mainnet.
64//             Enable probing for accepted rounds in round prober for mainnet.
65//             Switch to distributed vote scoring in consensus for mainnet.
66//             Enable the new consensus commit rule for mainnet.
67//             Enable consensus garbage collection for mainnet with GC depth set
68//             to 60 rounds.
69//             Enable batching in synchronizer for testnet
70//             Enable the gas price feedback mechanism in devnet.
71//             Enable Identifier input validation.
72//             Removes unnecessary child object mutations
73//             Add additional signature checks
74//             Add additional linkage checks
75// Version 11: Framework fix regarding candidate validator commission rate.
76// Version 12: Enable the gas price feedback mechanism in all networks.
77//             Enable the normalization of PTB arguments.
78// Version 13: Introduce logic to allow the committee to be selected from a set
79//             of eligible active validators.
80//             Enable processing and tracking AuthorityCapabilitiesV1 from
81//             non-committee validators in the devnet.
82// Version 14: Switches the consensus protocol to Starfish in devnet.
83//             Enable median-based commit timestamp calculation in consensus,
84//             and enforce checkpoint timestamp monotonicity for testnet.
85//             Enable batched block sync for mainnet.
86//             Enable selecting committee only from active validators that
87//             support the next epoch's version and issued valid
88//             AuthorityCapabilities notification in testnet.
89// Version 15: Enable shared object transaction bursts of 10 times average load
90//             on devnet.
91// Version 16: Enable selecting committee only from active validators that
92//             support the next epoch's version and issued valid
93//             AuthorityCapabilities notification.
94//             Enable committing transactions only for traversed headers in
95//             Starfish.
96// Version 17: Increase the committee size to 100 on all networks.
97// Version 18: Enable passkey authentication support in testnet.
98// Version 19: Enable congestion limit overshoot in the gas price feedback
99//             mechanism on devnet.
100//             Enable a separate gas price feedback mechanism for transactions
101//             using randomness on devnet.
102//             Allow metadata bytes indexed with a dedicated key in compiled
103//             Move modules in devnet.
104//             Enable publishing package metadata v1 along with the package in
105//             devnet.
106//             Enable Move-based account authentication in devnet.
107//             Increase the base cost for transfer receive object in devnet.
108//             Switch consensus protocol to Starfish in testnet.
109//             Enable passkey authentication support in mainnet.
110//             Change epoch transaction will contain validator scores.
111//             Enable validator scoring on testnet and enable adjustment of
112//             validator rewards based on scores on Devnet.
113// Version 20: Supports the calculation of validator scores while still passing
114//             a default score value to the advance_epoch call. Enables this
115//             decoupling on Testnet; Devnet and Mainnet behavior remain the
116//             same.
117//             Introduce Dynamic Minimum Commission (IIP-8) on all networks.
118// Version 21: Enable overshoot of 100 in congestion control on testnet.
119//             Enable congestion limit overshoot in the gas price feedback
120//             mechanism on testnet.
121//             Enable a separate gas price feedback mechanism for transactions
122//             using randomness on testnet.
123//             Enable fast commit syncer for faster recovery in devnet.
124//             Add auth_context_tx native functions costs.
125//             Reduce max_auth_gas in Devnet.
126// Version 22: Enable overshoot of 100 in congestion control on all networks.
127//             Enable congestion limit overshoot in the gas price feedback
128//             mechanism on all networks.
129//             Enable a separate gas price feedback mechanism for transactions
130//             using randomness on all networks.
131//             Enable Move-based account authentication in testnet.
132//             Enable fast commit syncer for faster recovery on testnet.
133// Version 23: Enable Move native context (TxContext via native functions) in
134//             all networks. TxContext fields are read via native functions
135//             instead of being deserialized from a BCS-encoded struct.
136//             Enables sponsor, rgp, gas_price, and gas_budget to be exposed to
137//             Move.
138// Version 24: Switch consensus protocol to Starfish in all networks.
139//             Enable Move-based sponsor account authentication in devnet.
140//             Add AuthContext native functions cost for reading tx_data_bytes.
141//             Enable additional borrow checks.
142// Version 25: Deprecate zkLogin related parameters since zkLogin is no longer
143//             supported.
144#[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
145pub struct ProtocolVersion(u64);
146
147impl ProtocolVersion {
148    // The minimum and maximum protocol version supported by this binary.
149    // Counterintuitively, this constant may change over time as support for old
150    // protocol versions is removed from the source. This ensures that when a
151    // new network (such as a testnet) is created, its genesis committee will
152    // use a protocol version that is actually supported by the binary.
153    pub const MIN: Self = Self(MIN_PROTOCOL_VERSION);
154
155    pub const MAX: Self = Self(MAX_PROTOCOL_VERSION);
156
157    #[cfg(not(msim))]
158    const MAX_ALLOWED: Self = Self::MAX;
159
160    // We create one additional "fake" version in simulator builds so that we can
161    // test upgrades.
162    #[cfg(msim)]
163    pub const MAX_ALLOWED: Self = Self(MAX_PROTOCOL_VERSION + 1);
164
165    pub fn new(v: u64) -> Self {
166        Self(v)
167    }
168
169    pub const fn as_u64(&self) -> u64 {
170        self.0
171    }
172
173    // For serde deserialization - we don't define a Default impl because there
174    // isn't a single universally appropriate default value.
175    pub fn max() -> Self {
176        Self::MAX
177    }
178}
179
180impl From<u64> for ProtocolVersion {
181    fn from(v: u64) -> Self {
182        Self::new(v)
183    }
184}
185
186impl std::ops::Sub<u64> for ProtocolVersion {
187    type Output = Self;
188    fn sub(self, rhs: u64) -> Self::Output {
189        Self::new(self.0 - rhs)
190    }
191}
192
193impl std::ops::Add<u64> for ProtocolVersion {
194    type Output = Self;
195    fn add(self, rhs: u64) -> Self::Output {
196        Self::new(self.0 + rhs)
197    }
198}
199
200#[derive(
201    Clone, Serialize, Deserialize, Debug, PartialEq, Copy, PartialOrd, Ord, Eq, ValueEnum, Default,
202)]
203pub enum Chain {
204    Mainnet,
205    Testnet,
206    #[default]
207    Unknown,
208}
209
210impl Chain {
211    pub fn as_str(self) -> &'static str {
212        match self {
213            Chain::Mainnet => "mainnet",
214            Chain::Testnet => "testnet",
215            Chain::Unknown => "unknown",
216        }
217    }
218}
219
220pub struct Error(pub String);
221
222// TODO: There are quite a few non boolean values in the feature flags. We
223// should move them out.
224/// Records on/off feature flags that may vary at each protocol version.
225#[derive(Default, Clone, Serialize, Deserialize, Debug, ProtocolConfigFeatureFlagsGetters)]
226struct FeatureFlags {
227    // Add feature flags here, e.g.:
228    // new_protocol_feature: bool,
229
230    // Disables unnecessary invariant check in the Move VM when swapping the value out of a local
231    // This flag is used to provide the correct MoveVM configuration for clients.
232    #[serde(skip_serializing_if = "is_true")]
233    disable_invariant_violation_check_in_swap_loc: bool,
234
235    // If true, checks no extra bytes in a compiled module
236    // This flag is used to provide the correct MoveVM configuration for clients.
237    #[serde(skip_serializing_if = "is_true")]
238    no_extraneous_module_bytes: bool,
239
240    // How we order transactions coming out of consensus before sending to execution.
241    #[serde(skip_serializing_if = "ConsensusTransactionOrdering::is_none")]
242    consensus_transaction_ordering: ConsensusTransactionOrdering,
243
244    // If true, use the hardened OTW check
245    // This flag is used to provide the correct MoveVM configuration for clients.
246    #[serde(skip_serializing_if = "is_true")]
247    hardened_otw_check: bool,
248
249    // Enable the poseidon hash function
250    #[serde(skip_serializing_if = "is_false")]
251    enable_poseidon: bool,
252
253    // Enable native function for msm.
254    #[serde(skip_serializing_if = "is_false")]
255    enable_group_ops_native_function_msm: bool,
256
257    // Controls the behavior of per object congestion control in consensus handler.
258    #[serde(skip_serializing_if = "PerObjectCongestionControlMode::is_none")]
259    per_object_congestion_control_mode: PerObjectCongestionControlMode,
260
261    // The consensus protocol to be used for the epoch.
262    #[serde(skip_serializing_if = "ConsensusChoice::is_mysticeti")]
263    consensus_choice: ConsensusChoice,
264
265    // Consensus network to use.
266    #[serde(skip_serializing_if = "ConsensusNetwork::is_tonic")]
267    consensus_network: ConsensusNetwork,
268
269    // Set the upper bound allowed for max_epoch in zklogin signature.
270    #[deprecated]
271    #[serde(skip_serializing_if = "Option::is_none")]
272    zklogin_max_epoch_upper_bound_delta: Option<u64>,
273
274    // Enable VDF
275    #[serde(skip_serializing_if = "is_false")]
276    enable_vdf: bool,
277
278    // Enable passkey auth (SIP-9)
279    #[serde(skip_serializing_if = "is_false")]
280    passkey_auth: bool,
281
282    // Rethrow type layout errors during serialization instead of trying to convert them.
283    // This flag is used to provide the correct MoveVM configuration for clients.
284    #[serde(skip_serializing_if = "is_true")]
285    rethrow_serialization_type_layout_errors: bool,
286
287    // Makes the event's sending module version-aware.
288    #[serde(skip_serializing_if = "is_false")]
289    relocate_event_module: bool,
290
291    // Enable a protocol-defined base gas price for all transactions.
292    #[serde(skip_serializing_if = "is_false")]
293    protocol_defined_base_fee: bool,
294
295    // Enable uncompressed group elements in BLS123-81 G1
296    #[serde(skip_serializing_if = "is_false")]
297    uncompressed_g1_group_elements: bool,
298
299    // Disallow adding new modules in `deps-only` packages.
300    #[serde(skip_serializing_if = "is_false")]
301    disallow_new_modules_in_deps_only_packages: bool,
302
303    // Enable v2 native charging for natives.
304    #[serde(skip_serializing_if = "is_false")]
305    native_charging_v2: bool,
306
307    // Properly convert certain type argument errors in the execution layer.
308    #[serde(skip_serializing_if = "is_false")]
309    convert_type_argument_error: bool,
310
311    // Probe rounds received by peers from every authority.
312    #[serde(skip_serializing_if = "is_false")]
313    consensus_round_prober: bool,
314
315    // Use distributed vote leader scoring strategy in consensus.
316    #[serde(skip_serializing_if = "is_false")]
317    consensus_distributed_vote_scoring_strategy: bool,
318
319    // Enables the new logic for collecting the subdag in the consensus linearizer. The new logic
320    // does not stop the recursion at the highest committed round for each authority, but
321    // allows to commit uncommitted blocks up to gc round (excluded) for that authority.
322    #[serde(skip_serializing_if = "is_false")]
323    consensus_linearize_subdag_v2: bool,
324
325    // Variants count as nodes
326    #[serde(skip_serializing_if = "is_false")]
327    variant_nodes: bool,
328
329    // Use smart ancestor selection in consensus.
330    #[serde(skip_serializing_if = "is_false")]
331    consensus_smart_ancestor_selection: bool,
332
333    // Probe accepted rounds in round prober.
334    #[serde(skip_serializing_if = "is_false")]
335    consensus_round_prober_probe_accepted_rounds: bool,
336
337    // If true, enable zstd compression for consensus tonic network.
338    #[serde(skip_serializing_if = "is_false")]
339    consensus_zstd_compression: bool,
340
341    // Use the minimum free execution slot to schedule execution of a transaction in the shared
342    // object congestion tracker.
343    #[serde(skip_serializing_if = "is_false")]
344    congestion_control_min_free_execution_slot: bool,
345
346    // If true, multisig containing passkey sig is accepted.
347    #[serde(skip_serializing_if = "is_false")]
348    accept_passkey_in_multisig: bool,
349
350    // If true, enabled batched block sync in consensus.
351    #[serde(skip_serializing_if = "is_false")]
352    consensus_batched_block_sync: bool,
353
354    // To enable/disable the gas price feedback mechanism used for transactions
355    // cancelled due to shared object congestion
356    #[serde(skip_serializing_if = "is_false")]
357    congestion_control_gas_price_feedback_mechanism: bool,
358
359    // Validate identifier inputs separately
360    #[serde(skip_serializing_if = "is_false")]
361    validate_identifier_inputs: bool,
362
363    // If true, enables the optimizations for child object mutations, removing unnecessary
364    // mutations
365    #[serde(skip_serializing_if = "is_false")]
366    minimize_child_object_mutations: bool,
367
368    // If true enable additional linkage checks.
369    #[serde(skip_serializing_if = "is_false")]
370    dependency_linkage_error: bool,
371
372    // If true enable additional multisig checks.
373    #[serde(skip_serializing_if = "is_false")]
374    additional_multisig_checks: bool,
375
376    // If true, enables the normalization of PTB arguments but does not yet enable splatting
377    // `Result`s of length not equal to 1
378    #[serde(skip_serializing_if = "is_false")]
379    normalize_ptb_arguments: bool,
380
381    // If true, use ChangeEpochV3 for epoch change to pass an additional eligible_active_validators
382    // parameter to IotaSystem's advance_epoch call. This should only be enabled when on-chain
383    // IotaSystem objects are updated as well.
384    #[serde(skip_serializing_if = "is_false")]
385    select_committee_from_eligible_validators: bool,
386
387    // If true, non-committee active validators will sign and send AuthorityCapabilitiesV1 to the
388    // committee. Once the committee reaches consensus over the AuthorityCapabilitiesV1, it is
389    // recorded and possible to use in the committee selection if
390    // select_validators_supporting_next_epoch_version is enabled. This flag does not change the
391    // way that eligible_validators vector is created - still all active validators are used for
392    // selecting the committee.
393    #[serde(skip_serializing_if = "is_false")]
394    track_non_committee_eligible_validators: bool,
395
396    // The committee be selected from active_validators who support the next protocol version AND
397    // have issued a correct AuthorityCapabilities notification. This flag should only be enabled
398    // if both select_committee_from_eligible_validators and
399    // track_non_committee_eligible_validators are enabled. If this is disabled, then all
400    // active validators are used for selecting the committee (default behavior).
401    #[serde(skip_serializing_if = "is_false")]
402    select_committee_supporting_next_epoch_version: bool,
403
404    // If true, then it (1) will not enforce monotonicity checks for a block's ancestors, (2)
405    // calculates the commit's timestamp based on the weighted by stake median timestamp of the
406    // leader's ancestors, and (3) enforces checkpoint timestamps are non-decreasing.
407    #[serde(skip_serializing_if = "is_false")]
408    consensus_median_timestamp_with_checkpoint_enforcement: bool,
409
410    // If true, then transactions are committed only for traversed headers
411    #[serde(skip_serializing_if = "is_false")]
412    consensus_commit_transactions_only_for_traversed_headers: bool,
413
414    // To enable/disable congestion limit overshoot in the gas price feedback mechanism.
415    #[serde(skip_serializing_if = "is_false")]
416    congestion_limit_overshoot_in_gas_price_feedback_mechanism: bool,
417
418    // To enable/disable a separate gas price feedback mechanism for transactions using
419    // randomness.
420    #[serde(skip_serializing_if = "is_false")]
421    separate_gas_price_feedback_mechanism_for_randomness: bool,
422
423    // If true, it allows metadata bytes indexed with a dedicated key in a compiled module.
424    // This flag is used to provide the correct MoveVM configuration for clients.
425    #[serde(skip_serializing_if = "is_false")]
426    metadata_in_module_bytes: bool,
427
428    // If true, enables publishing package metadata v1 along with the package.
429    #[serde(skip_serializing_if = "is_false")]
430    publish_package_metadata: bool,
431
432    // If true, enables the authentication of account using Move code.
433    #[serde(skip_serializing_if = "is_false")]
434    enable_move_authentication: bool,
435
436    // If true, enables the authentication of a sponsor account using Move code.
437    #[serde(skip_serializing_if = "is_false")]
438    enable_move_authentication_for_sponsor: bool,
439
440    // If true, the change epoch transaction will contain validator scores.
441    #[serde(skip_serializing_if = "is_false")]
442    pass_validator_scores_to_advance_epoch: bool,
443
444    // If true, enables calculation of validator scores.
445    #[serde(skip_serializing_if = "is_false")]
446    calculate_validator_scores: bool,
447
448    // If true, validators will use the committee's score to adjust rewards.
449    #[serde(skip_serializing_if = "is_false")]
450    adjust_rewards_by_score: bool,
451
452    // If true, the change epoch transaction will contain the locally calculated validator scores.
453    // If false, a default score (MAX_SCORE) is passed
454    #[serde(skip_serializing_if = "is_false")]
455    pass_calculated_validator_scores_to_advance_epoch: bool,
456
457    // If true, enables the fast commit syncer in Starfish consensus for faster recovery
458    // from large commit gaps. Also controls whether TransactionRef is used in commits
459    // instead of BlockRef, and enables the associated gRPC endpoints for fetching
460    // commits and transactions.
461    #[serde(skip_serializing_if = "is_false")]
462    consensus_fast_commit_sync: bool,
463
464    // If true, enable `TxContext` Move API to go native.
465    #[serde(skip_serializing_if = "is_false")]
466    move_native_tx_context: bool,
467
468    // If true, perform additional borrow checks
469    #[serde(skip_serializing_if = "is_false")]
470    additional_borrow_checks: bool,
471}
472
473fn is_true(b: &bool) -> bool {
474    *b
475}
476
477fn is_false(b: &bool) -> bool {
478    !b
479}
480
481/// Ordering mechanism for transactions in one consensus output.
482#[derive(Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
483pub enum ConsensusTransactionOrdering {
484    /// No ordering. Transactions are processed in the order they appear in the
485    /// consensus output.
486    #[default]
487    None,
488    /// Order transactions by gas price, highest first.
489    ByGasPrice,
490}
491
492impl ConsensusTransactionOrdering {
493    pub fn is_none(&self) -> bool {
494        matches!(self, ConsensusTransactionOrdering::None)
495    }
496}
497
498// The config for per object congestion control in consensus handler.
499#[derive(Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
500pub enum PerObjectCongestionControlMode {
501    #[default]
502    None, // No congestion control.
503    TotalGasBudget, // Use txn gas budget as execution cost.
504    TotalTxCount,   // Use total txn count as execution cost.
505}
506
507impl PerObjectCongestionControlMode {
508    pub fn is_none(&self) -> bool {
509        matches!(self, PerObjectCongestionControlMode::None)
510    }
511}
512
513// Configuration options for consensus algorithm.
514#[derive(Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
515pub enum ConsensusChoice {
516    #[default]
517    Mysticeti,
518    Starfish,
519}
520
521impl ConsensusChoice {
522    pub fn is_mysticeti(&self) -> bool {
523        matches!(self, ConsensusChoice::Mysticeti)
524    }
525    pub fn is_starfish(&self) -> bool {
526        matches!(self, ConsensusChoice::Starfish)
527    }
528}
529
530// Configuration options for consensus network.
531#[derive(Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
532pub enum ConsensusNetwork {
533    #[default]
534    Tonic,
535}
536
537impl ConsensusNetwork {
538    pub fn is_tonic(&self) -> bool {
539        matches!(self, ConsensusNetwork::Tonic)
540    }
541}
542
543/// Constants that change the behavior of the protocol.
544///
545/// The value of each constant here must be fixed for a given protocol version.
546/// To change the value of a constant, advance the protocol version, and add
547/// support for it in `get_for_version` under the new version number.
548/// (below).
549///
550/// To add a new field to this struct, use the following procedure:
551/// - Advance the protocol version.
552/// - Add the field as a private `Option<T>` to the struct.
553/// - Initialize the field to `None` in prior protocol versions.
554/// - Initialize the field to `Some(val)` for your new protocol version.
555/// - Add a public getter that simply unwraps the field.
556/// - Two public getters of the form `field(&self) -> field_type` and
557///   `field_as_option(&self) -> Option<field_type>` will be automatically
558///   generated for you.
559/// Example for a field: `new_constant: Option<u64>`
560/// ```rust,ignore
561///      pub fn new_constant(&self) -> u64 {
562///         self.new_constant.expect(Self::CONSTANT_ERR_MSG)
563///     }
564///      pub fn new_constant_as_option(&self) -> Option<u64> {
565///         self.new_constant.expect(Self::CONSTANT_ERR_MSG)
566///     }
567/// ```
568/// With `pub fn new_constant(&self) -> u64`, if the constant is accessed in a
569/// protocol version in which it is not defined, the validator will crash.
570/// (Crashing is necessary because this type of error would almost always result
571/// in forking if not prevented here). If you don't want the validator to crash,
572/// you can use the `pub fn new_constant_as_option(&self) -> Option<u64>`
573/// getter, which will return `None` if the field is not defined at that
574/// version.
575/// - If you want a customized getter, you can add a method in the impl.
576#[skip_serializing_none]
577#[derive(Clone, Serialize, Debug, ProtocolConfigAccessors, ProtocolConfigOverride)]
578pub struct ProtocolConfig {
579    pub version: ProtocolVersion,
580
581    feature_flags: FeatureFlags,
582
583    // ==== Transaction input limits ====
584
585    //
586    /// Maximum serialized size of a transaction (in bytes).
587    max_tx_size_bytes: Option<u64>,
588
589    /// Maximum number of input objects to a transaction. Enforced by the
590    /// transaction input checker
591    max_input_objects: Option<u64>,
592
593    /// Max size of objects a transaction can write to disk after completion.
594    /// Enforce by the IOTA adapter. This is the sum of the serialized size
595    /// of all objects written to disk. The max size of individual objects
596    /// on the other hand is `max_move_object_size`.
597    max_size_written_objects: Option<u64>,
598    /// Max size of objects a system transaction can write to disk after
599    /// completion. Enforce by the IOTA adapter. Similar to
600    /// `max_size_written_objects` but for system transactions.
601    max_size_written_objects_system_tx: Option<u64>,
602
603    /// Maximum size of serialized transaction effects.
604    max_serialized_tx_effects_size_bytes: Option<u64>,
605
606    /// Maximum size of serialized transaction effects for system transactions.
607    max_serialized_tx_effects_size_bytes_system_tx: Option<u64>,
608
609    /// Maximum number of gas payment objects for a transaction.
610    max_gas_payment_objects: Option<u32>,
611
612    /// Maximum number of modules in a Publish transaction.
613    max_modules_in_publish: Option<u32>,
614
615    /// Maximum number of transitive dependencies in a package when publishing.
616    max_package_dependencies: Option<u32>,
617
618    /// Maximum number of arguments in a move call or a
619    /// ProgrammableTransaction's TransferObjects command.
620    max_arguments: Option<u32>,
621
622    /// Maximum number of total type arguments, computed recursively.
623    max_type_arguments: Option<u32>,
624
625    /// Maximum depth of an individual type argument.
626    max_type_argument_depth: Option<u32>,
627
628    /// Maximum size of a Pure CallArg.
629    max_pure_argument_size: Option<u32>,
630
631    /// Maximum number of Commands in a ProgrammableTransaction.
632    max_programmable_tx_commands: Option<u32>,
633
634    // ==== Move VM, Move bytecode verifier, and execution limits ===
635
636    //
637    /// Maximum Move bytecode version the VM understands. All older versions are
638    /// accepted.
639    move_binary_format_version: Option<u32>,
640    min_move_binary_format_version: Option<u32>,
641
642    /// Configuration controlling binary tables size.
643    binary_module_handles: Option<u16>,
644    binary_struct_handles: Option<u16>,
645    binary_function_handles: Option<u16>,
646    binary_function_instantiations: Option<u16>,
647    binary_signatures: Option<u16>,
648    binary_constant_pool: Option<u16>,
649    binary_identifiers: Option<u16>,
650    binary_address_identifiers: Option<u16>,
651    binary_struct_defs: Option<u16>,
652    binary_struct_def_instantiations: Option<u16>,
653    binary_function_defs: Option<u16>,
654    binary_field_handles: Option<u16>,
655    binary_field_instantiations: Option<u16>,
656    binary_friend_decls: Option<u16>,
657    binary_enum_defs: Option<u16>,
658    binary_enum_def_instantiations: Option<u16>,
659    binary_variant_handles: Option<u16>,
660    binary_variant_instantiation_handles: Option<u16>,
661
662    /// Maximum size of the `contents` part of an object, in bytes. Enforced by
663    /// the IOTA adapter when effects are produced.
664    max_move_object_size: Option<u64>,
665
666    // TODO: Option<increase to 500 KB. currently, publishing a package > 500 KB exceeds the max
667    // computation gas cost
668    /// Maximum size of a Move package object, in bytes. Enforced by the IOTA
669    /// adapter at the end of a publish transaction.
670    max_move_package_size: Option<u64>,
671
672    /// Max number of publish or upgrade commands allowed in a programmable
673    /// transaction block.
674    max_publish_or_upgrade_per_ptb: Option<u64>,
675
676    /// Maximum gas budget in NANOS that a transaction can use.
677    max_tx_gas: Option<u64>,
678
679    /// Maximum gas budget in NANOS that a authentication transaction can use.
680    max_auth_gas: Option<u64>,
681
682    /// Maximum amount of the proposed gas price in NANOS (defined in the
683    /// transaction).
684    max_gas_price: Option<u64>,
685
686    /// The max computation bucket for gas. This is the max that can be charged
687    /// for computation.
688    max_gas_computation_bucket: Option<u64>,
689
690    // Define the value used to round up computation gas charges
691    gas_rounding_step: Option<u64>,
692
693    /// Maximum number of nested loops. Enforced by the Move bytecode verifier.
694    max_loop_depth: Option<u64>,
695
696    /// Maximum number of type arguments that can be bound to generic type
697    /// parameters. Enforced by the Move bytecode verifier.
698    max_generic_instantiation_length: Option<u64>,
699
700    /// Maximum number of parameters that a Move function can have. Enforced by
701    /// the Move bytecode verifier.
702    max_function_parameters: Option<u64>,
703
704    /// Maximum number of basic blocks that a Move function can have. Enforced
705    /// by the Move bytecode verifier.
706    max_basic_blocks: Option<u64>,
707
708    /// Maximum stack size value. Enforced by the Move bytecode verifier.
709    max_value_stack_size: Option<u64>,
710
711    /// Maximum number of "type nodes", a metric for how big a SignatureToken
712    /// will be when expanded into a fully qualified type. Enforced by the Move
713    /// bytecode verifier.
714    max_type_nodes: Option<u64>,
715
716    /// Maximum number of push instructions in one function. Enforced by the
717    /// Move bytecode verifier.
718    max_push_size: Option<u64>,
719
720    /// Maximum number of struct definitions in a module. Enforced by the Move
721    /// bytecode verifier.
722    max_struct_definitions: Option<u64>,
723
724    /// Maximum number of function definitions in a module. Enforced by the Move
725    /// bytecode verifier.
726    max_function_definitions: Option<u64>,
727
728    /// Maximum number of fields allowed in a struct definition. Enforced by the
729    /// Move bytecode verifier.
730    max_fields_in_struct: Option<u64>,
731
732    /// Maximum dependency depth. Enforced by the Move linker when loading
733    /// dependent modules.
734    max_dependency_depth: Option<u64>,
735
736    /// Maximum number of Move events that a single transaction can emit.
737    /// Enforced by the VM during execution.
738    max_num_event_emit: Option<u64>,
739
740    /// Maximum number of new IDs that a single transaction can create. Enforced
741    /// by the VM during execution.
742    max_num_new_move_object_ids: Option<u64>,
743
744    /// Maximum number of new IDs that a single system transaction can create.
745    /// Enforced by the VM during execution.
746    max_num_new_move_object_ids_system_tx: Option<u64>,
747
748    /// Maximum number of IDs that a single transaction can delete. Enforced by
749    /// the VM during execution.
750    max_num_deleted_move_object_ids: Option<u64>,
751
752    /// Maximum number of IDs that a single system transaction can delete.
753    /// Enforced by the VM during execution.
754    max_num_deleted_move_object_ids_system_tx: Option<u64>,
755
756    /// Maximum number of IDs that a single transaction can transfer. Enforced
757    /// by the VM during execution.
758    max_num_transferred_move_object_ids: Option<u64>,
759
760    /// Maximum number of IDs that a single system transaction can transfer.
761    /// Enforced by the VM during execution.
762    max_num_transferred_move_object_ids_system_tx: Option<u64>,
763
764    /// Maximum size of a Move user event. Enforced by the VM during execution.
765    max_event_emit_size: Option<u64>,
766
767    /// Maximum size of a Move user event. Enforced by the VM during execution.
768    max_event_emit_size_total: Option<u64>,
769
770    /// Maximum length of a vector in Move. Enforced by the VM during execution,
771    /// and for constants, by the verifier.
772    max_move_vector_len: Option<u64>,
773
774    /// Maximum length of an `Identifier` in Move. Enforced by the bytecode
775    /// verifier at signing.
776    max_move_identifier_len: Option<u64>,
777
778    /// Maximum depth of a Move value within the VM.
779    max_move_value_depth: Option<u64>,
780
781    /// Maximum number of variants in an enum. Enforced by the bytecode verifier
782    /// at signing.
783    max_move_enum_variants: Option<u64>,
784
785    /// Maximum number of back edges in Move function. Enforced by the bytecode
786    /// verifier at signing.
787    max_back_edges_per_function: Option<u64>,
788
789    /// Maximum number of back edges in Move module. Enforced by the bytecode
790    /// verifier at signing.
791    max_back_edges_per_module: Option<u64>,
792
793    /// Maximum number of meter `ticks` spent verifying a Move function.
794    /// Enforced by the bytecode verifier at signing.
795    max_verifier_meter_ticks_per_function: Option<u64>,
796
797    /// Maximum number of meter `ticks` spent verifying a Move function.
798    /// Enforced by the bytecode verifier at signing.
799    max_meter_ticks_per_module: Option<u64>,
800
801    /// Maximum number of meter `ticks` spent verifying a Move package. Enforced
802    /// by the bytecode verifier at signing.
803    max_meter_ticks_per_package: Option<u64>,
804
805    // === Object runtime internal operation limits ====
806    // These affect dynamic fields
807
808    //
809    /// Maximum number of cached objects in the object runtime ObjectStore.
810    /// Enforced by object runtime during execution
811    object_runtime_max_num_cached_objects: Option<u64>,
812
813    /// Maximum number of cached objects in the object runtime ObjectStore in
814    /// system transaction. Enforced by object runtime during execution
815    object_runtime_max_num_cached_objects_system_tx: Option<u64>,
816
817    /// Maximum number of stored objects accessed by object runtime ObjectStore.
818    /// Enforced by object runtime during execution
819    object_runtime_max_num_store_entries: Option<u64>,
820
821    /// Maximum number of stored objects accessed by object runtime ObjectStore
822    /// in system transaction. Enforced by object runtime during execution
823    object_runtime_max_num_store_entries_system_tx: Option<u64>,
824
825    // === Execution gas costs ====
826
827    //
828    /// Base cost for any IOTA transaction
829    base_tx_cost_fixed: Option<u64>,
830
831    /// Additional cost for a transaction that publishes a package
832    /// i.e., the base cost of such a transaction is base_tx_cost_fixed +
833    /// package_publish_cost_fixed
834    package_publish_cost_fixed: Option<u64>,
835
836    /// Cost per byte of a Move call transaction
837    /// i.e., the cost of such a transaction is base_cost +
838    /// (base_tx_cost_per_byte * size)
839    base_tx_cost_per_byte: Option<u64>,
840
841    /// Cost per byte for a transaction that publishes a package
842    package_publish_cost_per_byte: Option<u64>,
843
844    // Per-byte cost of reading an object during transaction execution
845    obj_access_cost_read_per_byte: Option<u64>,
846
847    // Per-byte cost of writing an object during transaction execution
848    obj_access_cost_mutate_per_byte: Option<u64>,
849
850    // Per-byte cost of deleting an object during transaction execution
851    obj_access_cost_delete_per_byte: Option<u64>,
852
853    /// Per-byte cost charged for each input object to a transaction.
854    /// Meant to approximate the cost of checking locks for each object
855    // TODO: Option<I'm not sure that this cost makes sense. Checking locks is "free"
856    // in the sense that an invalid tx that can never be committed/pay gas can
857    // force validators to check an arbitrary number of locks. If those checks are
858    // "free" for invalid transactions, why charge for them in valid transactions
859    // TODO: Option<if we keep this, I think we probably want it to be a fixed cost rather
860    // than a per-byte cost. checking an object lock should not require loading an
861    // entire object, just consulting an ID -> tx digest map
862    obj_access_cost_verify_per_byte: Option<u64>,
863
864    // Maximal nodes which are allowed when converting to a type layout.
865    max_type_to_layout_nodes: Option<u64>,
866
867    // Maximal size in bytes that a PTB value can be
868    max_ptb_value_size: Option<u64>,
869
870    // === Gas version. gas model ===
871
872    //
873    /// Gas model version, what code we are using to charge gas
874    gas_model_version: Option<u64>,
875
876    // === Storage gas costs ===
877
878    //
879    /// Per-byte cost of storing an object in the IOTA global object store. Some
880    /// of this cost may be refundable if the object is later freed
881    obj_data_cost_refundable: Option<u64>,
882
883    // Per-byte cost of storing an object in the IOTA transaction log (e.g., in
884    // CertifiedTransactionEffects) This depends on the size of various fields including the
885    // effects TODO: Option<I don't fully understand this^ and more details would be useful
886    obj_metadata_cost_non_refundable: Option<u64>,
887
888    // === Tokenomics ===
889
890    // TODO: Option<this should be changed to u64.
891    /// Sender of a txn that touches an object will get this percent of the
892    /// storage rebate back. In basis point.
893    storage_rebate_rate: Option<u64>,
894
895    /// The share of rewards that will be slashed and redistributed is 50%.
896    /// In basis point.
897    reward_slashing_rate: Option<u64>,
898
899    /// Unit storage gas price, Nanos per internal gas unit.
900    storage_gas_price: Option<u64>,
901
902    // Base gas price for computation gas, nanos per computation unit.
903    base_gas_price: Option<u64>,
904
905    /// The number of tokens minted as a validator subsidy per epoch.
906    validator_target_reward: Option<u64>,
907
908    // === Core Protocol ===
909
910    //
911    /// Max number of transactions per checkpoint.
912    /// Note that this is a protocol constant and not a config as validators
913    /// must have this set to the same value, otherwise they *will* fork.
914    max_transactions_per_checkpoint: Option<u64>,
915
916    /// Max size of a checkpoint in bytes.
917    /// Note that this is a protocol constant and not a config as validators
918    /// must have this set to the same value, otherwise they *will* fork.
919    max_checkpoint_size_bytes: Option<u64>,
920
921    /// A protocol upgrade always requires 2f+1 stake to agree. We support a
922    /// buffer of additional stake (as a fraction of f, expressed in basis
923    /// points) that is required before an upgrade can happen automatically.
924    /// 10000bps would indicate that complete unanimity is required (all
925    /// 3f+1 must vote), while 0bps would indicate that 2f+1 is sufficient.
926    buffer_stake_for_protocol_upgrade_bps: Option<u64>,
927
928    // === Native Function Costs ===
929
930    // `address` module
931    // Cost params for the Move native function `address::from_bytes(bytes: vector<u8>)`
932    address_from_bytes_cost_base: Option<u64>,
933    // Cost params for the Move native function `address::to_u256(address): u256`
934    address_to_u256_cost_base: Option<u64>,
935    // Cost params for the Move native function `address::from_u256(u256): address`
936    address_from_u256_cost_base: Option<u64>,
937
938    // `config` module
939    // Cost params for the Move native function `read_setting_impl<Name: copy + drop + store,
940    // SettingValue: key + store, SettingDataValue: store, Value: copy + drop + store,
941    // >(config: address, name: address, current_epoch: u64): Option<Value>`
942    config_read_setting_impl_cost_base: Option<u64>,
943    config_read_setting_impl_cost_per_byte: Option<u64>,
944
945    // `dynamic_field` module
946    // Cost params for the Move native function `hash_type_and_key<K: copy + drop + store>(parent:
947    // address, k: K): address`
948    dynamic_field_hash_type_and_key_cost_base: Option<u64>,
949    dynamic_field_hash_type_and_key_type_cost_per_byte: Option<u64>,
950    dynamic_field_hash_type_and_key_value_cost_per_byte: Option<u64>,
951    dynamic_field_hash_type_and_key_type_tag_cost_per_byte: Option<u64>,
952    // Cost params for the Move native function `add_child_object<Child: key>(parent: address,
953    // child: Child)`
954    dynamic_field_add_child_object_cost_base: Option<u64>,
955    dynamic_field_add_child_object_type_cost_per_byte: Option<u64>,
956    dynamic_field_add_child_object_value_cost_per_byte: Option<u64>,
957    dynamic_field_add_child_object_struct_tag_cost_per_byte: Option<u64>,
958    // Cost params for the Move native function `borrow_child_object_mut<Child: key>(parent: &mut
959    // UID, id: address): &mut Child`
960    dynamic_field_borrow_child_object_cost_base: Option<u64>,
961    dynamic_field_borrow_child_object_child_ref_cost_per_byte: Option<u64>,
962    dynamic_field_borrow_child_object_type_cost_per_byte: Option<u64>,
963    // Cost params for the Move native function `remove_child_object<Child: key>(parent: address,
964    // id: address): Child`
965    dynamic_field_remove_child_object_cost_base: Option<u64>,
966    dynamic_field_remove_child_object_child_cost_per_byte: Option<u64>,
967    dynamic_field_remove_child_object_type_cost_per_byte: Option<u64>,
968    // Cost params for the Move native function `has_child_object(parent: address, id: address):
969    // bool`
970    dynamic_field_has_child_object_cost_base: Option<u64>,
971    // Cost params for the Move native function `has_child_object_with_ty<Child: key>(parent:
972    // address, id: address): bool`
973    dynamic_field_has_child_object_with_ty_cost_base: Option<u64>,
974    dynamic_field_has_child_object_with_ty_type_cost_per_byte: Option<u64>,
975    dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: Option<u64>,
976
977    // `event` module
978    // Cost params for the Move native function `event::emit<T: copy + drop>(event: T)`
979    event_emit_cost_base: Option<u64>,
980    event_emit_value_size_derivation_cost_per_byte: Option<u64>,
981    event_emit_tag_size_derivation_cost_per_byte: Option<u64>,
982    event_emit_output_cost_per_byte: Option<u64>,
983
984    //  `object` module
985    // Cost params for the Move native function `borrow_uid<T: key>(obj: &T): &UID`
986    object_borrow_uid_cost_base: Option<u64>,
987    // Cost params for the Move native function `delete_impl(id: address)`
988    object_delete_impl_cost_base: Option<u64>,
989    // Cost params for the Move native function `record_new_uid(id: address)`
990    object_record_new_uid_cost_base: Option<u64>,
991
992    // Transfer
993    // Cost params for the Move native function `transfer_impl<T: key>(obj: T, recipient: address)`
994    transfer_transfer_internal_cost_base: Option<u64>,
995    // Cost params for the Move native function `freeze_object<T: key>(obj: T)`
996    transfer_freeze_object_cost_base: Option<u64>,
997    // Cost params for the Move native function `share_object<T: key>(obj: T)`
998    transfer_share_object_cost_base: Option<u64>,
999    // Cost params for the Move native function
1000    // `receive_object<T: key>(p: &mut UID, recv: Receiving<T>T)`
1001    transfer_receive_object_cost_base: Option<u64>,
1002
1003    // TxContext
1004    // Cost params for the Move native function `transfer_impl<T: key>(obj: T, recipient: address)`
1005    tx_context_derive_id_cost_base: Option<u64>,
1006    tx_context_fresh_id_cost_base: Option<u64>,
1007    tx_context_sender_cost_base: Option<u64>,
1008    tx_context_digest_cost_base: Option<u64>,
1009    tx_context_epoch_cost_base: Option<u64>,
1010    tx_context_epoch_timestamp_ms_cost_base: Option<u64>,
1011    tx_context_sponsor_cost_base: Option<u64>,
1012    tx_context_rgp_cost_base: Option<u64>,
1013    tx_context_gas_price_cost_base: Option<u64>,
1014    tx_context_gas_budget_cost_base: Option<u64>,
1015    tx_context_ids_created_cost_base: Option<u64>,
1016    tx_context_replace_cost_base: Option<u64>,
1017
1018    // Types
1019    // Cost params for the Move native function `is_one_time_witness<T: drop>(_: &T): bool`
1020    types_is_one_time_witness_cost_base: Option<u64>,
1021    types_is_one_time_witness_type_tag_cost_per_byte: Option<u64>,
1022    types_is_one_time_witness_type_cost_per_byte: Option<u64>,
1023
1024    // Validator
1025    // Cost params for the Move native function `validate_metadata_bcs(metadata: vector<u8>)`
1026    validator_validate_metadata_cost_base: Option<u64>,
1027    validator_validate_metadata_data_cost_per_byte: Option<u64>,
1028
1029    // Crypto natives
1030    crypto_invalid_arguments_cost: Option<u64>,
1031    // bls12381::bls12381_min_sig_verify
1032    bls12381_bls12381_min_sig_verify_cost_base: Option<u64>,
1033    bls12381_bls12381_min_sig_verify_msg_cost_per_byte: Option<u64>,
1034    bls12381_bls12381_min_sig_verify_msg_cost_per_block: Option<u64>,
1035
1036    // bls12381::bls12381_min_pk_verify
1037    bls12381_bls12381_min_pk_verify_cost_base: Option<u64>,
1038    bls12381_bls12381_min_pk_verify_msg_cost_per_byte: Option<u64>,
1039    bls12381_bls12381_min_pk_verify_msg_cost_per_block: Option<u64>,
1040
1041    // ecdsa_k1::ecrecover
1042    ecdsa_k1_ecrecover_keccak256_cost_base: Option<u64>,
1043    ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: Option<u64>,
1044    ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: Option<u64>,
1045    ecdsa_k1_ecrecover_sha256_cost_base: Option<u64>,
1046    ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: Option<u64>,
1047    ecdsa_k1_ecrecover_sha256_msg_cost_per_block: Option<u64>,
1048
1049    // ecdsa_k1::decompress_pubkey
1050    ecdsa_k1_decompress_pubkey_cost_base: Option<u64>,
1051
1052    // ecdsa_k1::secp256k1_verify
1053    ecdsa_k1_secp256k1_verify_keccak256_cost_base: Option<u64>,
1054    ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: Option<u64>,
1055    ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: Option<u64>,
1056    ecdsa_k1_secp256k1_verify_sha256_cost_base: Option<u64>,
1057    ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: Option<u64>,
1058    ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: Option<u64>,
1059
1060    // ecdsa_r1::ecrecover
1061    ecdsa_r1_ecrecover_keccak256_cost_base: Option<u64>,
1062    ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: Option<u64>,
1063    ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: Option<u64>,
1064    ecdsa_r1_ecrecover_sha256_cost_base: Option<u64>,
1065    ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: Option<u64>,
1066    ecdsa_r1_ecrecover_sha256_msg_cost_per_block: Option<u64>,
1067
1068    // ecdsa_r1::secp256k1_verify
1069    ecdsa_r1_secp256r1_verify_keccak256_cost_base: Option<u64>,
1070    ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: Option<u64>,
1071    ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: Option<u64>,
1072    ecdsa_r1_secp256r1_verify_sha256_cost_base: Option<u64>,
1073    ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: Option<u64>,
1074    ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: Option<u64>,
1075
1076    // ecvrf::verify
1077    ecvrf_ecvrf_verify_cost_base: Option<u64>,
1078    ecvrf_ecvrf_verify_alpha_string_cost_per_byte: Option<u64>,
1079    ecvrf_ecvrf_verify_alpha_string_cost_per_block: Option<u64>,
1080
1081    // ed25519
1082    ed25519_ed25519_verify_cost_base: Option<u64>,
1083    ed25519_ed25519_verify_msg_cost_per_byte: Option<u64>,
1084    ed25519_ed25519_verify_msg_cost_per_block: Option<u64>,
1085
1086    // groth16::prepare_verifying_key
1087    groth16_prepare_verifying_key_bls12381_cost_base: Option<u64>,
1088    groth16_prepare_verifying_key_bn254_cost_base: Option<u64>,
1089
1090    // groth16::verify_groth16_proof_internal
1091    groth16_verify_groth16_proof_internal_bls12381_cost_base: Option<u64>,
1092    groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: Option<u64>,
1093    groth16_verify_groth16_proof_internal_bn254_cost_base: Option<u64>,
1094    groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: Option<u64>,
1095    groth16_verify_groth16_proof_internal_public_input_cost_per_byte: Option<u64>,
1096
1097    // hash::blake2b256
1098    hash_blake2b256_cost_base: Option<u64>,
1099    hash_blake2b256_data_cost_per_byte: Option<u64>,
1100    hash_blake2b256_data_cost_per_block: Option<u64>,
1101
1102    // hash::keccak256
1103    hash_keccak256_cost_base: Option<u64>,
1104    hash_keccak256_data_cost_per_byte: Option<u64>,
1105    hash_keccak256_data_cost_per_block: Option<u64>,
1106
1107    // poseidon::poseidon_bn254
1108    poseidon_bn254_cost_base: Option<u64>,
1109    poseidon_bn254_cost_per_block: Option<u64>,
1110
1111    // group_ops
1112    group_ops_bls12381_decode_scalar_cost: Option<u64>,
1113    group_ops_bls12381_decode_g1_cost: Option<u64>,
1114    group_ops_bls12381_decode_g2_cost: Option<u64>,
1115    group_ops_bls12381_decode_gt_cost: Option<u64>,
1116    group_ops_bls12381_scalar_add_cost: Option<u64>,
1117    group_ops_bls12381_g1_add_cost: Option<u64>,
1118    group_ops_bls12381_g2_add_cost: Option<u64>,
1119    group_ops_bls12381_gt_add_cost: Option<u64>,
1120    group_ops_bls12381_scalar_sub_cost: Option<u64>,
1121    group_ops_bls12381_g1_sub_cost: Option<u64>,
1122    group_ops_bls12381_g2_sub_cost: Option<u64>,
1123    group_ops_bls12381_gt_sub_cost: Option<u64>,
1124    group_ops_bls12381_scalar_mul_cost: Option<u64>,
1125    group_ops_bls12381_g1_mul_cost: Option<u64>,
1126    group_ops_bls12381_g2_mul_cost: Option<u64>,
1127    group_ops_bls12381_gt_mul_cost: Option<u64>,
1128    group_ops_bls12381_scalar_div_cost: Option<u64>,
1129    group_ops_bls12381_g1_div_cost: Option<u64>,
1130    group_ops_bls12381_g2_div_cost: Option<u64>,
1131    group_ops_bls12381_gt_div_cost: Option<u64>,
1132    group_ops_bls12381_g1_hash_to_base_cost: Option<u64>,
1133    group_ops_bls12381_g2_hash_to_base_cost: Option<u64>,
1134    group_ops_bls12381_g1_hash_to_cost_per_byte: Option<u64>,
1135    group_ops_bls12381_g2_hash_to_cost_per_byte: Option<u64>,
1136    group_ops_bls12381_g1_msm_base_cost: Option<u64>,
1137    group_ops_bls12381_g2_msm_base_cost: Option<u64>,
1138    group_ops_bls12381_g1_msm_base_cost_per_input: Option<u64>,
1139    group_ops_bls12381_g2_msm_base_cost_per_input: Option<u64>,
1140    group_ops_bls12381_msm_max_len: Option<u32>,
1141    group_ops_bls12381_pairing_cost: Option<u64>,
1142    group_ops_bls12381_g1_to_uncompressed_g1_cost: Option<u64>,
1143    group_ops_bls12381_uncompressed_g1_to_g1_cost: Option<u64>,
1144    group_ops_bls12381_uncompressed_g1_sum_base_cost: Option<u64>,
1145    group_ops_bls12381_uncompressed_g1_sum_cost_per_term: Option<u64>,
1146    group_ops_bls12381_uncompressed_g1_sum_max_terms: Option<u64>,
1147
1148    // hmac::hmac_sha3_256
1149    hmac_hmac_sha3_256_cost_base: Option<u64>,
1150    hmac_hmac_sha3_256_input_cost_per_byte: Option<u64>,
1151    hmac_hmac_sha3_256_input_cost_per_block: Option<u64>,
1152
1153    // zklogin::check_zklogin_id
1154    #[deprecated]
1155    check_zklogin_id_cost_base: Option<u64>,
1156    // zklogin::check_zklogin_issuer
1157    #[deprecated]
1158    check_zklogin_issuer_cost_base: Option<u64>,
1159
1160    vdf_verify_vdf_cost: Option<u64>,
1161    vdf_hash_to_input_cost: Option<u64>,
1162
1163    // Stdlib costs
1164    bcs_per_byte_serialized_cost: Option<u64>,
1165    bcs_legacy_min_output_size_cost: Option<u64>,
1166    bcs_failure_cost: Option<u64>,
1167
1168    hash_sha2_256_base_cost: Option<u64>,
1169    hash_sha2_256_per_byte_cost: Option<u64>,
1170    hash_sha2_256_legacy_min_input_len_cost: Option<u64>,
1171    hash_sha3_256_base_cost: Option<u64>,
1172    hash_sha3_256_per_byte_cost: Option<u64>,
1173    hash_sha3_256_legacy_min_input_len_cost: Option<u64>,
1174    type_name_get_base_cost: Option<u64>,
1175    type_name_get_per_byte_cost: Option<u64>,
1176
1177    string_check_utf8_base_cost: Option<u64>,
1178    string_check_utf8_per_byte_cost: Option<u64>,
1179    string_is_char_boundary_base_cost: Option<u64>,
1180    string_sub_string_base_cost: Option<u64>,
1181    string_sub_string_per_byte_cost: Option<u64>,
1182    string_index_of_base_cost: Option<u64>,
1183    string_index_of_per_byte_pattern_cost: Option<u64>,
1184    string_index_of_per_byte_searched_cost: Option<u64>,
1185
1186    vector_empty_base_cost: Option<u64>,
1187    vector_length_base_cost: Option<u64>,
1188    vector_push_back_base_cost: Option<u64>,
1189    vector_push_back_legacy_per_abstract_memory_unit_cost: Option<u64>,
1190    vector_borrow_base_cost: Option<u64>,
1191    vector_pop_back_base_cost: Option<u64>,
1192    vector_destroy_empty_base_cost: Option<u64>,
1193    vector_swap_base_cost: Option<u64>,
1194    debug_print_base_cost: Option<u64>,
1195    debug_print_stack_trace_base_cost: Option<u64>,
1196
1197    // === Execution Version ===
1198    execution_version: Option<u64>,
1199
1200    // Dictates the threshold (percentage of stake) that is used to calculate the "bad" nodes to be
1201    // swapped when creating the consensus schedule. The values should be of the range [0 - 33].
1202    // Anything above 33 (f) will not be allowed.
1203    consensus_bad_nodes_stake_threshold: Option<u64>,
1204
1205    #[deprecated]
1206    max_jwk_votes_per_validator_per_epoch: Option<u64>,
1207    // The maximum age of a JWK in epochs before it is removed from the AuthenticatorState object.
1208    // Applied at the end of an epoch as a delta from the new epoch value, so setting this to 1
1209    // will cause the new epoch to start with JWKs from the previous epoch still valid.
1210    #[deprecated]
1211    max_age_of_jwk_in_epochs: Option<u64>,
1212
1213    // === random beacon ===
1214    /// Maximum allowed precision loss when reducing voting weights for the
1215    /// random beacon protocol.
1216    random_beacon_reduction_allowed_delta: Option<u16>,
1217
1218    /// Minimum number of shares below which voting weights will not be reduced
1219    /// for the random beacon protocol.
1220    random_beacon_reduction_lower_bound: Option<u32>,
1221
1222    /// Consensus Round after which DKG should be aborted and randomness
1223    /// disabled for the epoch, if it hasn't already completed.
1224    random_beacon_dkg_timeout_round: Option<u32>,
1225
1226    /// Minimum interval between consecutive rounds of generated randomness.
1227    random_beacon_min_round_interval_ms: Option<u64>,
1228
1229    /// Version of the random beacon DKG protocol.
1230    /// 0 was deprecated (and currently not supported), 1 is the default
1231    /// version.
1232    random_beacon_dkg_version: Option<u64>,
1233
1234    /// The maximum serialized transaction size (in bytes) accepted by
1235    /// consensus. `consensus_max_transaction_size_bytes` should include
1236    /// space for additional metadata, on top of the `max_tx_size_bytes`
1237    /// value.
1238    consensus_max_transaction_size_bytes: Option<u64>,
1239    /// The maximum size of transactions included in a consensus block.
1240    consensus_max_transactions_in_block_bytes: Option<u64>,
1241    /// The maximum number of transactions included in a consensus block.
1242    consensus_max_num_transactions_in_block: Option<u64>,
1243
1244    /// The max number of consensus rounds a transaction can be deferred due to
1245    /// shared object congestion. Transactions will be cancelled after this
1246    /// many rounds.
1247    max_deferral_rounds_for_congestion_control: Option<u64>,
1248
1249    /// Minimum interval of commit timestamps between consecutive checkpoints.
1250    min_checkpoint_interval_ms: Option<u64>,
1251
1252    /// Version number to use for version_specific_data in `CheckpointSummary`.
1253    checkpoint_summary_version_specific_data: Option<u64>,
1254
1255    /// The max number of transactions that can be included in a single Soft
1256    /// Bundle.
1257    max_soft_bundle_size: Option<u64>,
1258
1259    /// Deprecated because of bridge removal.
1260    /// Whether to try to form bridge committee
1261    // Note: this is not a feature flag because we want to distinguish between
1262    // `None` and `Some(false)`, as committee was already finalized on Testnet.
1263    bridge_should_try_to_finalize_committee: Option<bool>,
1264
1265    /// The max accumulated txn execution cost per object in a mysticeti commit.
1266    /// Transactions in a commit will be deferred once their touch shared
1267    /// objects hit this limit. Note that if
1268    /// `max_congestion_limit_overshoot_per_commit` is set, this may be overshot
1269    /// within a single commit, but the limit will be enforced in the long run.
1270    max_accumulated_txn_cost_per_object_in_mysticeti_commit: Option<u64>,
1271
1272    /// Maximum number of committee (validators taking part in consensus)
1273    /// validators at any moment. We do not allow the number of committee
1274    /// validators in any epoch to go above this.
1275    max_committee_members_count: Option<u64>,
1276
1277    /// Configures the garbage collection depth for consensus. When is unset or
1278    /// `0` then the garbage collection is disabled.
1279    consensus_gc_depth: Option<u32>,
1280
1281    /// Configures the maximum number of acknowledgments to be included in a
1282    /// block. It must be reasonably larger than the number of validators
1283    /// because not all validators create their blocks at the same pace.
1284    /// Default value set to 400. (5 x expected committee size (80)).
1285    /// Applicable only to `starfish` consensus.
1286    consensus_max_acknowledgments_per_block: Option<u32>,
1287
1288    /// The maximum amount that is allowed to overshoot the congestion limit
1289    /// specified by 'max_accumulated_txn_cost_per_object_in_mysticeti_commit'
1290    /// for any single commit. Any overshoot is tracked as a debt that must
1291    /// be accounted for in subsequent commits.
1292    max_congestion_limit_overshoot_per_commit: Option<u64>,
1293
1294    /// Scorer version. When set to `None`, MisbehaviorReports are not sent nor
1295    /// considered valid. When set to `Some(version)`, scores are included in
1296    /// the MisbehaviorReports messages, where `version` determines the scoring
1297    /// formulas and metrics to be used. Even if set to None, the Scorer
1298    /// component is created, having access to metrics and being able to expose
1299    /// validator scores.
1300    scorer_version: Option<u16>,
1301
1302    // `auth_context` module
1303    // Cost params for the Move native function `native_digest(): vector<u8>`
1304    auth_context_digest_cost_base: Option<u64>,
1305    // Cost params for the Move native function `native_tx_data_bytes(): &vector<u8>`
1306    auth_context_tx_data_bytes_cost_base: Option<u64>,
1307    auth_context_tx_data_bytes_cost_per_byte: Option<u64>,
1308    // Cost params for the Move native function `native_tx_commands<C>(): vector<C>`
1309    auth_context_tx_commands_cost_base: Option<u64>,
1310    auth_context_tx_commands_cost_per_byte: Option<u64>,
1311    // Cost params for the Move native function `native_tx_inputs<I>(): vector<I>`
1312    auth_context_tx_inputs_cost_base: Option<u64>,
1313    auth_context_tx_inputs_cost_per_byte: Option<u64>,
1314    // Cost params for the Move native function `fun native_replace<I, C>(auth_digest: vector<u8>,
1315    // tx_inputs: vector<I>, tx_commands: vector<C>, tx_data_bytes: vector<u8>)`
1316    auth_context_replace_cost_base: Option<u64>,
1317    auth_context_replace_cost_per_byte: Option<u64>,
1318}
1319
1320// feature flags
1321impl ProtocolConfig {
1322    // Add checks for feature flag support here, e.g.:
1323    // pub fn check_new_protocol_feature_supported(&self) -> Result<(), Error> {
1324    //     if self.feature_flags.new_protocol_feature_supported {
1325    //         Ok(())
1326    //     } else {
1327    //         Err(Error(format!(
1328    //             "new_protocol_feature is not supported at {:?}",
1329    //             self.version
1330    //         )))
1331    //     }
1332    // }
1333
1334    pub fn disable_invariant_violation_check_in_swap_loc(&self) -> bool {
1335        self.feature_flags
1336            .disable_invariant_violation_check_in_swap_loc
1337    }
1338
1339    pub fn no_extraneous_module_bytes(&self) -> bool {
1340        self.feature_flags.no_extraneous_module_bytes
1341    }
1342
1343    pub fn consensus_transaction_ordering(&self) -> ConsensusTransactionOrdering {
1344        self.feature_flags.consensus_transaction_ordering
1345    }
1346
1347    pub fn dkg_version(&self) -> u64 {
1348        // Version 0 was deprecated and removed, the default is 1 if not set.
1349        self.random_beacon_dkg_version.unwrap_or(1)
1350    }
1351
1352    pub fn hardened_otw_check(&self) -> bool {
1353        self.feature_flags.hardened_otw_check
1354    }
1355
1356    pub fn enable_poseidon(&self) -> bool {
1357        self.feature_flags.enable_poseidon
1358    }
1359
1360    pub fn enable_group_ops_native_function_msm(&self) -> bool {
1361        self.feature_flags.enable_group_ops_native_function_msm
1362    }
1363
1364    pub fn per_object_congestion_control_mode(&self) -> PerObjectCongestionControlMode {
1365        self.feature_flags.per_object_congestion_control_mode
1366    }
1367
1368    pub fn consensus_choice(&self) -> ConsensusChoice {
1369        self.feature_flags.consensus_choice
1370    }
1371
1372    pub fn consensus_network(&self) -> ConsensusNetwork {
1373        self.feature_flags.consensus_network
1374    }
1375
1376    pub fn enable_vdf(&self) -> bool {
1377        self.feature_flags.enable_vdf
1378    }
1379
1380    pub fn passkey_auth(&self) -> bool {
1381        self.feature_flags.passkey_auth
1382    }
1383
1384    pub fn max_transaction_size_bytes(&self) -> u64 {
1385        // Provide a default value if protocol config version is too low.
1386        self.consensus_max_transaction_size_bytes
1387            .unwrap_or(256 * 1024)
1388    }
1389
1390    pub fn max_transactions_in_block_bytes(&self) -> u64 {
1391        if cfg!(msim) {
1392            256 * 1024
1393        } else {
1394            self.consensus_max_transactions_in_block_bytes
1395                .unwrap_or(512 * 1024)
1396        }
1397    }
1398
1399    pub fn max_num_transactions_in_block(&self) -> u64 {
1400        if cfg!(msim) {
1401            8
1402        } else {
1403            self.consensus_max_num_transactions_in_block.unwrap_or(512)
1404        }
1405    }
1406
1407    pub fn rethrow_serialization_type_layout_errors(&self) -> bool {
1408        self.feature_flags.rethrow_serialization_type_layout_errors
1409    }
1410
1411    pub fn relocate_event_module(&self) -> bool {
1412        self.feature_flags.relocate_event_module
1413    }
1414
1415    pub fn protocol_defined_base_fee(&self) -> bool {
1416        self.feature_flags.protocol_defined_base_fee
1417    }
1418
1419    pub fn uncompressed_g1_group_elements(&self) -> bool {
1420        self.feature_flags.uncompressed_g1_group_elements
1421    }
1422
1423    pub fn disallow_new_modules_in_deps_only_packages(&self) -> bool {
1424        self.feature_flags
1425            .disallow_new_modules_in_deps_only_packages
1426    }
1427
1428    pub fn native_charging_v2(&self) -> bool {
1429        self.feature_flags.native_charging_v2
1430    }
1431
1432    pub fn consensus_round_prober(&self) -> bool {
1433        self.feature_flags.consensus_round_prober
1434    }
1435
1436    pub fn consensus_distributed_vote_scoring_strategy(&self) -> bool {
1437        self.feature_flags
1438            .consensus_distributed_vote_scoring_strategy
1439    }
1440
1441    pub fn gc_depth(&self) -> u32 {
1442        if cfg!(msim) {
1443            // exercise a very low gc_depth
1444            min(5, self.consensus_gc_depth.unwrap_or(0))
1445        } else {
1446            self.consensus_gc_depth.unwrap_or(0)
1447        }
1448    }
1449
1450    pub fn consensus_linearize_subdag_v2(&self) -> bool {
1451        let res = self.feature_flags.consensus_linearize_subdag_v2;
1452        assert!(
1453            !res || self.gc_depth() > 0,
1454            "The consensus linearize sub dag V2 requires GC to be enabled"
1455        );
1456        res
1457    }
1458
1459    pub fn consensus_max_acknowledgments_per_block_or_default(&self) -> u32 {
1460        self.consensus_max_acknowledgments_per_block.unwrap_or(400)
1461    }
1462
1463    pub fn variant_nodes(&self) -> bool {
1464        self.feature_flags.variant_nodes
1465    }
1466
1467    pub fn consensus_smart_ancestor_selection(&self) -> bool {
1468        self.feature_flags.consensus_smart_ancestor_selection
1469    }
1470
1471    pub fn consensus_round_prober_probe_accepted_rounds(&self) -> bool {
1472        self.feature_flags
1473            .consensus_round_prober_probe_accepted_rounds
1474    }
1475
1476    pub fn consensus_zstd_compression(&self) -> bool {
1477        self.feature_flags.consensus_zstd_compression
1478    }
1479
1480    pub fn congestion_control_min_free_execution_slot(&self) -> bool {
1481        self.feature_flags
1482            .congestion_control_min_free_execution_slot
1483    }
1484
1485    pub fn accept_passkey_in_multisig(&self) -> bool {
1486        self.feature_flags.accept_passkey_in_multisig
1487    }
1488
1489    pub fn consensus_batched_block_sync(&self) -> bool {
1490        self.feature_flags.consensus_batched_block_sync
1491    }
1492
1493    /// Check if the gas price feedback mechanism (which is used for
1494    /// transactions cancelled due to shared object congestion) is enabled
1495    pub fn congestion_control_gas_price_feedback_mechanism(&self) -> bool {
1496        self.feature_flags
1497            .congestion_control_gas_price_feedback_mechanism
1498    }
1499
1500    pub fn validate_identifier_inputs(&self) -> bool {
1501        self.feature_flags.validate_identifier_inputs
1502    }
1503
1504    pub fn minimize_child_object_mutations(&self) -> bool {
1505        self.feature_flags.minimize_child_object_mutations
1506    }
1507
1508    pub fn dependency_linkage_error(&self) -> bool {
1509        self.feature_flags.dependency_linkage_error
1510    }
1511
1512    pub fn additional_multisig_checks(&self) -> bool {
1513        self.feature_flags.additional_multisig_checks
1514    }
1515
1516    pub fn consensus_num_requested_prior_commits_at_startup(&self) -> u32 {
1517        // TODO: this will eventually be the max of some number of other
1518        // parameters.
1519        0
1520    }
1521
1522    pub fn normalize_ptb_arguments(&self) -> bool {
1523        self.feature_flags.normalize_ptb_arguments
1524    }
1525
1526    pub fn select_committee_from_eligible_validators(&self) -> bool {
1527        let res = self.feature_flags.select_committee_from_eligible_validators;
1528        assert!(
1529            !res || (self.protocol_defined_base_fee()
1530                && self.max_committee_members_count_as_option().is_some()),
1531            "select_committee_from_eligible_validators requires protocol_defined_base_fee and max_committee_members_count to be set"
1532        );
1533        res
1534    }
1535
1536    pub fn track_non_committee_eligible_validators(&self) -> bool {
1537        self.feature_flags.track_non_committee_eligible_validators
1538    }
1539
1540    pub fn select_committee_supporting_next_epoch_version(&self) -> bool {
1541        let res = self
1542            .feature_flags
1543            .select_committee_supporting_next_epoch_version;
1544        assert!(
1545            !res || (self.track_non_committee_eligible_validators()
1546                && self.select_committee_from_eligible_validators()),
1547            "select_committee_supporting_next_epoch_version requires select_committee_from_eligible_validators to be set"
1548        );
1549        res
1550    }
1551
1552    pub fn consensus_median_timestamp_with_checkpoint_enforcement(&self) -> bool {
1553        let res = self
1554            .feature_flags
1555            .consensus_median_timestamp_with_checkpoint_enforcement;
1556        assert!(
1557            !res || self.gc_depth() > 0,
1558            "The consensus median timestamp with checkpoint enforcement requires GC to be enabled"
1559        );
1560        res
1561    }
1562
1563    pub fn consensus_commit_transactions_only_for_traversed_headers(&self) -> bool {
1564        self.feature_flags
1565            .consensus_commit_transactions_only_for_traversed_headers
1566    }
1567
1568    /// Check whether congestion limit overshoot is enabled in the gas price
1569    /// feedback mechanism.
1570    pub fn congestion_limit_overshoot_in_gas_price_feedback_mechanism(&self) -> bool {
1571        self.feature_flags
1572            .congestion_limit_overshoot_in_gas_price_feedback_mechanism
1573    }
1574
1575    /// Check whether a separate gas price feedback mechanism is used for
1576    /// randomness transactions.
1577    pub fn separate_gas_price_feedback_mechanism_for_randomness(&self) -> bool {
1578        self.feature_flags
1579            .separate_gas_price_feedback_mechanism_for_randomness
1580    }
1581
1582    pub fn metadata_in_module_bytes(&self) -> bool {
1583        self.feature_flags.metadata_in_module_bytes
1584    }
1585
1586    pub fn publish_package_metadata(&self) -> bool {
1587        self.feature_flags.publish_package_metadata
1588    }
1589
1590    pub fn enable_move_authentication(&self) -> bool {
1591        self.feature_flags.enable_move_authentication
1592    }
1593
1594    pub fn additional_borrow_checks(&self) -> bool {
1595        self.feature_flags.additional_borrow_checks
1596    }
1597
1598    pub fn enable_move_authentication_for_sponsor(&self) -> bool {
1599        let enable_move_authentication_for_sponsor =
1600            self.feature_flags.enable_move_authentication_for_sponsor;
1601        assert!(
1602            !enable_move_authentication_for_sponsor || self.enable_move_authentication(),
1603            "enable_move_authentication_for_sponsor requires enable_move_authentication to be set"
1604        );
1605        enable_move_authentication_for_sponsor
1606    }
1607
1608    pub fn pass_validator_scores_to_advance_epoch(&self) -> bool {
1609        self.feature_flags.pass_validator_scores_to_advance_epoch
1610    }
1611
1612    pub fn calculate_validator_scores(&self) -> bool {
1613        let calculate_validator_scores = self.feature_flags.calculate_validator_scores;
1614        assert!(
1615            !calculate_validator_scores || self.scorer_version.is_some(),
1616            "calculate_validator_scores requires scorer_version to be set"
1617        );
1618        calculate_validator_scores
1619    }
1620
1621    pub fn adjust_rewards_by_score(&self) -> bool {
1622        let adjust = self.feature_flags.adjust_rewards_by_score;
1623        assert!(
1624            !adjust || (self.scorer_version.is_some() && self.calculate_validator_scores()),
1625            "adjust_rewards_by_score requires scorer_version to be set"
1626        );
1627        adjust
1628    }
1629
1630    pub fn pass_calculated_validator_scores_to_advance_epoch(&self) -> bool {
1631        let pass = self
1632            .feature_flags
1633            .pass_calculated_validator_scores_to_advance_epoch;
1634        assert!(
1635            !pass
1636                || (self.pass_validator_scores_to_advance_epoch()
1637                    && self.calculate_validator_scores()),
1638            "pass_calculated_validator_scores_to_advance_epoch requires pass_validator_scores_to_advance_epoch and calculate_validator_scores to be enabled"
1639        );
1640        pass
1641    }
1642    pub fn consensus_fast_commit_sync(&self) -> bool {
1643        let res = self.feature_flags.consensus_fast_commit_sync;
1644        assert!(
1645            !res || self.consensus_commit_transactions_only_for_traversed_headers(),
1646            "consensus_fast_commit_sync requires consensus_commit_transactions_only_for_traversed_headers to be enabled"
1647        );
1648        res
1649    }
1650
1651    pub fn move_native_tx_context(&self) -> bool {
1652        self.feature_flags.move_native_tx_context
1653    }
1654}
1655
1656#[cfg(not(msim))]
1657static POISON_VERSION_METHODS: AtomicBool = const { AtomicBool::new(false) };
1658
1659// Use a thread local in sim tests for test isolation.
1660#[cfg(msim)]
1661thread_local! {
1662    static POISON_VERSION_METHODS: AtomicBool = const { AtomicBool::new(false) };
1663}
1664
1665// Instantiations for each protocol version.
1666impl ProtocolConfig {
1667    /// Get the value ProtocolConfig that are in effect during the given
1668    /// protocol version.
1669    pub fn get_for_version(version: ProtocolVersion, chain: Chain) -> Self {
1670        // ProtocolVersion can be deserialized so we need to check it here as well.
1671        assert!(
1672            version >= ProtocolVersion::MIN,
1673            "Network protocol version is {:?}, but the minimum supported version by the binary is {:?}. Please upgrade the binary.",
1674            version,
1675            ProtocolVersion::MIN.0,
1676        );
1677        assert!(
1678            version <= ProtocolVersion::MAX_ALLOWED,
1679            "Network protocol version is {:?}, but the maximum supported version by the binary is {:?}. Please upgrade the binary.",
1680            version,
1681            ProtocolVersion::MAX_ALLOWED.0,
1682        );
1683
1684        let mut ret = Self::get_for_version_impl(version, chain);
1685        ret.version = version;
1686
1687        ret = CONFIG_OVERRIDE.with(|ovr| {
1688            if let Some(override_fn) = &*ovr.borrow() {
1689                warn!(
1690                    "overriding ProtocolConfig settings with custom settings (you should not see this log outside of tests)"
1691                );
1692                override_fn(version, ret)
1693            } else {
1694                ret
1695            }
1696        });
1697
1698        if std::env::var("IOTA_PROTOCOL_CONFIG_OVERRIDE_ENABLE").is_ok() {
1699            warn!(
1700                "overriding ProtocolConfig settings with custom settings; this may break non-local networks"
1701            );
1702            let overrides: ProtocolConfigOptional =
1703                serde_env::from_env_with_prefix("IOTA_PROTOCOL_CONFIG_OVERRIDE")
1704                    .expect("failed to parse ProtocolConfig override env variables");
1705            overrides.apply_to(&mut ret);
1706        }
1707
1708        ret
1709    }
1710
1711    /// Get the value ProtocolConfig that are in effect during the given
1712    /// protocol version. Or none if the version is not supported.
1713    pub fn get_for_version_if_supported(version: ProtocolVersion, chain: Chain) -> Option<Self> {
1714        if version.0 >= ProtocolVersion::MIN.0 && version.0 <= ProtocolVersion::MAX_ALLOWED.0 {
1715            let mut ret = Self::get_for_version_impl(version, chain);
1716            ret.version = version;
1717            Some(ret)
1718        } else {
1719            None
1720        }
1721    }
1722
1723    #[cfg(not(msim))]
1724    pub fn poison_get_for_min_version() {
1725        POISON_VERSION_METHODS.store(true, Ordering::Relaxed);
1726    }
1727
1728    #[cfg(not(msim))]
1729    fn load_poison_get_for_min_version() -> bool {
1730        POISON_VERSION_METHODS.load(Ordering::Relaxed)
1731    }
1732
1733    #[cfg(msim)]
1734    pub fn poison_get_for_min_version() {
1735        POISON_VERSION_METHODS.with(|p| p.store(true, Ordering::Relaxed));
1736    }
1737
1738    #[cfg(msim)]
1739    fn load_poison_get_for_min_version() -> bool {
1740        POISON_VERSION_METHODS.with(|p| p.load(Ordering::Relaxed))
1741    }
1742
1743    pub fn convert_type_argument_error(&self) -> bool {
1744        self.feature_flags.convert_type_argument_error
1745    }
1746
1747    /// Convenience to get the constants at the current minimum supported
1748    /// version. Mainly used by client code that may not yet be
1749    /// protocol-version aware.
1750    pub fn get_for_min_version() -> Self {
1751        if Self::load_poison_get_for_min_version() {
1752            panic!("get_for_min_version called on validator");
1753        }
1754        ProtocolConfig::get_for_version(ProtocolVersion::MIN, Chain::Unknown)
1755    }
1756
1757    /// CAREFUL! - You probably want to use `get_for_version` instead.
1758    ///
1759    /// Convenience to get the constants at the current maximum supported
1760    /// version. Mainly used by genesis. Note well that this function uses
1761    /// the max version supported locally by the node, which is not
1762    /// necessarily the current version of the network. ALSO, this function
1763    /// disregards chain specific config (by using Chain::Unknown), thereby
1764    /// potentially returning a protocol config that is incorrect for some
1765    /// feature flags. Definitely safe for testing and for protocol version
1766    /// 11 and prior.
1767    #[expect(non_snake_case)]
1768    pub fn get_for_max_version_UNSAFE() -> Self {
1769        if Self::load_poison_get_for_min_version() {
1770            panic!("get_for_max_version_UNSAFE called on validator");
1771        }
1772        ProtocolConfig::get_for_version(ProtocolVersion::MAX, Chain::Unknown)
1773    }
1774
1775    fn get_for_version_impl(version: ProtocolVersion, chain: Chain) -> Self {
1776        #[cfg(msim)]
1777        {
1778            // populate the fake simulator version # with a different base tx cost.
1779            if version > ProtocolVersion::MAX {
1780                let mut config = Self::get_for_version_impl(ProtocolVersion::MAX, Chain::Unknown);
1781                config.base_tx_cost_fixed = Some(config.base_tx_cost_fixed() + 1000);
1782                return config;
1783            }
1784        }
1785
1786        // IMPORTANT: Never modify the value of any constant for a pre-existing protocol
1787        // version. To change the values here you must create a new protocol
1788        // version with the new values!
1789        let mut cfg = Self {
1790            version,
1791
1792            feature_flags: Default::default(),
1793
1794            max_tx_size_bytes: Some(128 * 1024),
1795            // We need this number to be at least 100x less than
1796            // `max_serialized_tx_effects_size_bytes`otherwise effects can be huge
1797            max_input_objects: Some(2048),
1798            max_serialized_tx_effects_size_bytes: Some(512 * 1024),
1799            max_serialized_tx_effects_size_bytes_system_tx: Some(512 * 1024 * 16),
1800            max_gas_payment_objects: Some(256),
1801            max_modules_in_publish: Some(64),
1802            max_package_dependencies: Some(32),
1803            max_arguments: Some(512),
1804            max_type_arguments: Some(16),
1805            max_type_argument_depth: Some(16),
1806            max_pure_argument_size: Some(16 * 1024),
1807            max_programmable_tx_commands: Some(1024),
1808            move_binary_format_version: Some(7),
1809            min_move_binary_format_version: Some(6),
1810            binary_module_handles: Some(100),
1811            binary_struct_handles: Some(300),
1812            binary_function_handles: Some(1500),
1813            binary_function_instantiations: Some(750),
1814            binary_signatures: Some(1000),
1815            binary_constant_pool: Some(4000),
1816            binary_identifiers: Some(10000),
1817            binary_address_identifiers: Some(100),
1818            binary_struct_defs: Some(200),
1819            binary_struct_def_instantiations: Some(100),
1820            binary_function_defs: Some(1000),
1821            binary_field_handles: Some(500),
1822            binary_field_instantiations: Some(250),
1823            binary_friend_decls: Some(100),
1824            binary_enum_defs: None,
1825            binary_enum_def_instantiations: None,
1826            binary_variant_handles: None,
1827            binary_variant_instantiation_handles: None,
1828            max_move_object_size: Some(250 * 1024),
1829            max_move_package_size: Some(100 * 1024),
1830            max_publish_or_upgrade_per_ptb: Some(5),
1831            // max gas budget for an authentication is in NANOS
1832            max_auth_gas: None,
1833            // max gas budget is in NANOS and an absolute value 50IOTA
1834            max_tx_gas: Some(50_000_000_000),
1835            max_gas_price: Some(100_000),
1836            max_gas_computation_bucket: Some(5_000_000),
1837            max_loop_depth: Some(5),
1838            max_generic_instantiation_length: Some(32),
1839            max_function_parameters: Some(128),
1840            max_basic_blocks: Some(1024),
1841            max_value_stack_size: Some(1024),
1842            max_type_nodes: Some(256),
1843            max_push_size: Some(10000),
1844            max_struct_definitions: Some(200),
1845            max_function_definitions: Some(1000),
1846            max_fields_in_struct: Some(32),
1847            max_dependency_depth: Some(100),
1848            max_num_event_emit: Some(1024),
1849            max_num_new_move_object_ids: Some(2048),
1850            max_num_new_move_object_ids_system_tx: Some(2048 * 16),
1851            max_num_deleted_move_object_ids: Some(2048),
1852            max_num_deleted_move_object_ids_system_tx: Some(2048 * 16),
1853            max_num_transferred_move_object_ids: Some(2048),
1854            max_num_transferred_move_object_ids_system_tx: Some(2048 * 16),
1855            max_event_emit_size: Some(250 * 1024),
1856            max_move_vector_len: Some(256 * 1024),
1857            max_type_to_layout_nodes: None,
1858            max_ptb_value_size: None,
1859
1860            max_back_edges_per_function: Some(10_000),
1861            max_back_edges_per_module: Some(10_000),
1862
1863            max_verifier_meter_ticks_per_function: Some(16_000_000),
1864
1865            max_meter_ticks_per_module: Some(16_000_000),
1866            max_meter_ticks_per_package: Some(16_000_000),
1867
1868            object_runtime_max_num_cached_objects: Some(1000),
1869            object_runtime_max_num_cached_objects_system_tx: Some(1000 * 16),
1870            object_runtime_max_num_store_entries: Some(1000),
1871            object_runtime_max_num_store_entries_system_tx: Some(1000 * 16),
1872            // min gas budget is in NANOS and an absolute value 1000 NANOS or 0.000001IOTA
1873            base_tx_cost_fixed: Some(1_000),
1874            package_publish_cost_fixed: Some(1_000),
1875            base_tx_cost_per_byte: Some(0),
1876            package_publish_cost_per_byte: Some(80),
1877            obj_access_cost_read_per_byte: Some(15),
1878            obj_access_cost_mutate_per_byte: Some(40),
1879            obj_access_cost_delete_per_byte: Some(40),
1880            obj_access_cost_verify_per_byte: Some(200),
1881            obj_data_cost_refundable: Some(100),
1882            obj_metadata_cost_non_refundable: Some(50),
1883            gas_model_version: Some(1),
1884            storage_rebate_rate: Some(10000),
1885            // Change reward slashing rate to 100%.
1886            reward_slashing_rate: Some(10000),
1887            storage_gas_price: Some(76),
1888            base_gas_price: None,
1889            // The initial subsidy (target reward) for validators per epoch.
1890            // Refer to the IOTA tokenomics for the origin of this value.
1891            validator_target_reward: Some(767_000 * 1_000_000_000),
1892            max_transactions_per_checkpoint: Some(10_000),
1893            max_checkpoint_size_bytes: Some(30 * 1024 * 1024),
1894
1895            // For now, perform upgrades with a bare quorum of validators.
1896            buffer_stake_for_protocol_upgrade_bps: Some(5000),
1897
1898            // === Native Function Costs ===
1899            // `address` module
1900            // Cost params for the Move native function `address::from_bytes(bytes: vector<u8>)`
1901            address_from_bytes_cost_base: Some(52),
1902            // Cost params for the Move native function `address::to_u256(address): u256`
1903            address_to_u256_cost_base: Some(52),
1904            // Cost params for the Move native function `address::from_u256(u256): address`
1905            address_from_u256_cost_base: Some(52),
1906
1907            // `config` module
1908            // Cost params for the Move native function `read_setting_impl``
1909            config_read_setting_impl_cost_base: Some(100),
1910            config_read_setting_impl_cost_per_byte: Some(40),
1911
1912            // `dynamic_field` module
1913            // Cost params for the Move native function `hash_type_and_key<K: copy + drop +
1914            // store>(parent: address, k: K): address`
1915            dynamic_field_hash_type_and_key_cost_base: Some(100),
1916            dynamic_field_hash_type_and_key_type_cost_per_byte: Some(2),
1917            dynamic_field_hash_type_and_key_value_cost_per_byte: Some(2),
1918            dynamic_field_hash_type_and_key_type_tag_cost_per_byte: Some(2),
1919            // Cost params for the Move native function `add_child_object<Child: key>(parent:
1920            // address, child: Child)`
1921            dynamic_field_add_child_object_cost_base: Some(100),
1922            dynamic_field_add_child_object_type_cost_per_byte: Some(10),
1923            dynamic_field_add_child_object_value_cost_per_byte: Some(10),
1924            dynamic_field_add_child_object_struct_tag_cost_per_byte: Some(10),
1925            // Cost params for the Move native function `borrow_child_object_mut<Child: key>(parent:
1926            // &mut UID, id: address): &mut Child`
1927            dynamic_field_borrow_child_object_cost_base: Some(100),
1928            dynamic_field_borrow_child_object_child_ref_cost_per_byte: Some(10),
1929            dynamic_field_borrow_child_object_type_cost_per_byte: Some(10),
1930            // Cost params for the Move native function `remove_child_object<Child: key>(parent:
1931            // address, id: address): Child`
1932            dynamic_field_remove_child_object_cost_base: Some(100),
1933            dynamic_field_remove_child_object_child_cost_per_byte: Some(2),
1934            dynamic_field_remove_child_object_type_cost_per_byte: Some(2),
1935            // Cost params for the Move native function `has_child_object(parent: address, id:
1936            // address): bool`
1937            dynamic_field_has_child_object_cost_base: Some(100),
1938            // Cost params for the Move native function `has_child_object_with_ty<Child:
1939            // key>(parent: address, id: address): bool`
1940            dynamic_field_has_child_object_with_ty_cost_base: Some(100),
1941            dynamic_field_has_child_object_with_ty_type_cost_per_byte: Some(2),
1942            dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: Some(2),
1943
1944            // `event` module
1945            // Cost params for the Move native function `event::emit<T: copy + drop>(event: T)`
1946            event_emit_cost_base: Some(52),
1947            event_emit_value_size_derivation_cost_per_byte: Some(2),
1948            event_emit_tag_size_derivation_cost_per_byte: Some(5),
1949            event_emit_output_cost_per_byte: Some(10),
1950
1951            //  `object` module
1952            // Cost params for the Move native function `borrow_uid<T: key>(obj: &T): &UID`
1953            object_borrow_uid_cost_base: Some(52),
1954            // Cost params for the Move native function `delete_impl(id: address)`
1955            object_delete_impl_cost_base: Some(52),
1956            // Cost params for the Move native function `record_new_uid(id: address)`
1957            object_record_new_uid_cost_base: Some(52),
1958
1959            // `transfer` module
1960            // Cost params for the Move native function `transfer_impl<T: key>(obj: T, recipient:
1961            // address)`
1962            transfer_transfer_internal_cost_base: Some(52),
1963            // Cost params for the Move native function `freeze_object<T: key>(obj: T)`
1964            transfer_freeze_object_cost_base: Some(52),
1965            // Cost params for the Move native function `share_object<T: key>(obj: T)`
1966            transfer_share_object_cost_base: Some(52),
1967            transfer_receive_object_cost_base: Some(52),
1968
1969            // `tx_context` module
1970            // Cost params for the Move native function `transfer_impl<T: key>(obj: T, recipient:
1971            // address)`
1972            tx_context_derive_id_cost_base: Some(52),
1973            tx_context_fresh_id_cost_base: None,
1974            tx_context_sender_cost_base: None,
1975            tx_context_digest_cost_base: None,
1976            tx_context_epoch_cost_base: None,
1977            tx_context_epoch_timestamp_ms_cost_base: None,
1978            tx_context_sponsor_cost_base: None,
1979            tx_context_rgp_cost_base: None,
1980            tx_context_gas_price_cost_base: None,
1981            tx_context_gas_budget_cost_base: None,
1982            tx_context_ids_created_cost_base: None,
1983            tx_context_replace_cost_base: None,
1984
1985            // `types` module
1986            // Cost params for the Move native function `is_one_time_witness<T: drop>(_: &T): bool`
1987            types_is_one_time_witness_cost_base: Some(52),
1988            types_is_one_time_witness_type_tag_cost_per_byte: Some(2),
1989            types_is_one_time_witness_type_cost_per_byte: Some(2),
1990
1991            // `validator` module
1992            // Cost params for the Move native function `validate_metadata_bcs(metadata:
1993            // vector<u8>)`
1994            validator_validate_metadata_cost_base: Some(52),
1995            validator_validate_metadata_data_cost_per_byte: Some(2),
1996
1997            // Crypto
1998            crypto_invalid_arguments_cost: Some(100),
1999            // bls12381::bls12381_min_pk_verify
2000            bls12381_bls12381_min_sig_verify_cost_base: Some(52),
2001            bls12381_bls12381_min_sig_verify_msg_cost_per_byte: Some(2),
2002            bls12381_bls12381_min_sig_verify_msg_cost_per_block: Some(2),
2003
2004            // bls12381::bls12381_min_pk_verify
2005            bls12381_bls12381_min_pk_verify_cost_base: Some(52),
2006            bls12381_bls12381_min_pk_verify_msg_cost_per_byte: Some(2),
2007            bls12381_bls12381_min_pk_verify_msg_cost_per_block: Some(2),
2008
2009            // ecdsa_k1::ecrecover
2010            ecdsa_k1_ecrecover_keccak256_cost_base: Some(52),
2011            ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: Some(2),
2012            ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: Some(2),
2013            ecdsa_k1_ecrecover_sha256_cost_base: Some(52),
2014            ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: Some(2),
2015            ecdsa_k1_ecrecover_sha256_msg_cost_per_block: Some(2),
2016
2017            // ecdsa_k1::decompress_pubkey
2018            ecdsa_k1_decompress_pubkey_cost_base: Some(52),
2019
2020            // ecdsa_k1::secp256k1_verify
2021            ecdsa_k1_secp256k1_verify_keccak256_cost_base: Some(52),
2022            ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: Some(2),
2023            ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: Some(2),
2024            ecdsa_k1_secp256k1_verify_sha256_cost_base: Some(52),
2025            ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: Some(2),
2026            ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: Some(2),
2027
2028            // ecdsa_r1::ecrecover
2029            ecdsa_r1_ecrecover_keccak256_cost_base: Some(52),
2030            ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: Some(2),
2031            ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: Some(2),
2032            ecdsa_r1_ecrecover_sha256_cost_base: Some(52),
2033            ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: Some(2),
2034            ecdsa_r1_ecrecover_sha256_msg_cost_per_block: Some(2),
2035
2036            // ecdsa_r1::secp256k1_verify
2037            ecdsa_r1_secp256r1_verify_keccak256_cost_base: Some(52),
2038            ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: Some(2),
2039            ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: Some(2),
2040            ecdsa_r1_secp256r1_verify_sha256_cost_base: Some(52),
2041            ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: Some(2),
2042            ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: Some(2),
2043
2044            // ecvrf::verify
2045            ecvrf_ecvrf_verify_cost_base: Some(52),
2046            ecvrf_ecvrf_verify_alpha_string_cost_per_byte: Some(2),
2047            ecvrf_ecvrf_verify_alpha_string_cost_per_block: Some(2),
2048
2049            // ed25519
2050            ed25519_ed25519_verify_cost_base: Some(52),
2051            ed25519_ed25519_verify_msg_cost_per_byte: Some(2),
2052            ed25519_ed25519_verify_msg_cost_per_block: Some(2),
2053
2054            // groth16::prepare_verifying_key
2055            groth16_prepare_verifying_key_bls12381_cost_base: Some(52),
2056            groth16_prepare_verifying_key_bn254_cost_base: Some(52),
2057
2058            // groth16::verify_groth16_proof_internal
2059            groth16_verify_groth16_proof_internal_bls12381_cost_base: Some(52),
2060            groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: Some(2),
2061            groth16_verify_groth16_proof_internal_bn254_cost_base: Some(52),
2062            groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: Some(2),
2063            groth16_verify_groth16_proof_internal_public_input_cost_per_byte: Some(2),
2064
2065            // hash::blake2b256
2066            hash_blake2b256_cost_base: Some(52),
2067            hash_blake2b256_data_cost_per_byte: Some(2),
2068            hash_blake2b256_data_cost_per_block: Some(2),
2069            // hash::keccak256
2070            hash_keccak256_cost_base: Some(52),
2071            hash_keccak256_data_cost_per_byte: Some(2),
2072            hash_keccak256_data_cost_per_block: Some(2),
2073
2074            poseidon_bn254_cost_base: None,
2075            poseidon_bn254_cost_per_block: None,
2076
2077            // hmac::hmac_sha3_256
2078            hmac_hmac_sha3_256_cost_base: Some(52),
2079            hmac_hmac_sha3_256_input_cost_per_byte: Some(2),
2080            hmac_hmac_sha3_256_input_cost_per_block: Some(2),
2081
2082            // group ops
2083            group_ops_bls12381_decode_scalar_cost: Some(52),
2084            group_ops_bls12381_decode_g1_cost: Some(52),
2085            group_ops_bls12381_decode_g2_cost: Some(52),
2086            group_ops_bls12381_decode_gt_cost: Some(52),
2087            group_ops_bls12381_scalar_add_cost: Some(52),
2088            group_ops_bls12381_g1_add_cost: Some(52),
2089            group_ops_bls12381_g2_add_cost: Some(52),
2090            group_ops_bls12381_gt_add_cost: Some(52),
2091            group_ops_bls12381_scalar_sub_cost: Some(52),
2092            group_ops_bls12381_g1_sub_cost: Some(52),
2093            group_ops_bls12381_g2_sub_cost: Some(52),
2094            group_ops_bls12381_gt_sub_cost: Some(52),
2095            group_ops_bls12381_scalar_mul_cost: Some(52),
2096            group_ops_bls12381_g1_mul_cost: Some(52),
2097            group_ops_bls12381_g2_mul_cost: Some(52),
2098            group_ops_bls12381_gt_mul_cost: Some(52),
2099            group_ops_bls12381_scalar_div_cost: Some(52),
2100            group_ops_bls12381_g1_div_cost: Some(52),
2101            group_ops_bls12381_g2_div_cost: Some(52),
2102            group_ops_bls12381_gt_div_cost: Some(52),
2103            group_ops_bls12381_g1_hash_to_base_cost: Some(52),
2104            group_ops_bls12381_g2_hash_to_base_cost: Some(52),
2105            group_ops_bls12381_g1_hash_to_cost_per_byte: Some(2),
2106            group_ops_bls12381_g2_hash_to_cost_per_byte: Some(2),
2107            group_ops_bls12381_g1_msm_base_cost: Some(52),
2108            group_ops_bls12381_g2_msm_base_cost: Some(52),
2109            group_ops_bls12381_g1_msm_base_cost_per_input: Some(52),
2110            group_ops_bls12381_g2_msm_base_cost_per_input: Some(52),
2111            group_ops_bls12381_msm_max_len: Some(32),
2112            group_ops_bls12381_pairing_cost: Some(52),
2113            group_ops_bls12381_g1_to_uncompressed_g1_cost: None,
2114            group_ops_bls12381_uncompressed_g1_to_g1_cost: None,
2115            group_ops_bls12381_uncompressed_g1_sum_base_cost: None,
2116            group_ops_bls12381_uncompressed_g1_sum_cost_per_term: None,
2117            group_ops_bls12381_uncompressed_g1_sum_max_terms: None,
2118
2119            // zklogin::check_zklogin_id
2120            #[allow(deprecated)]
2121            check_zklogin_id_cost_base: Some(200),
2122            #[allow(deprecated)]
2123            // zklogin::check_zklogin_issuer
2124            check_zklogin_issuer_cost_base: Some(200),
2125
2126            vdf_verify_vdf_cost: None,
2127            vdf_hash_to_input_cost: None,
2128
2129            bcs_per_byte_serialized_cost: Some(2),
2130            bcs_legacy_min_output_size_cost: Some(1),
2131            bcs_failure_cost: Some(52),
2132            hash_sha2_256_base_cost: Some(52),
2133            hash_sha2_256_per_byte_cost: Some(2),
2134            hash_sha2_256_legacy_min_input_len_cost: Some(1),
2135            hash_sha3_256_base_cost: Some(52),
2136            hash_sha3_256_per_byte_cost: Some(2),
2137            hash_sha3_256_legacy_min_input_len_cost: Some(1),
2138            type_name_get_base_cost: Some(52),
2139            type_name_get_per_byte_cost: Some(2),
2140            string_check_utf8_base_cost: Some(52),
2141            string_check_utf8_per_byte_cost: Some(2),
2142            string_is_char_boundary_base_cost: Some(52),
2143            string_sub_string_base_cost: Some(52),
2144            string_sub_string_per_byte_cost: Some(2),
2145            string_index_of_base_cost: Some(52),
2146            string_index_of_per_byte_pattern_cost: Some(2),
2147            string_index_of_per_byte_searched_cost: Some(2),
2148            vector_empty_base_cost: Some(52),
2149            vector_length_base_cost: Some(52),
2150            vector_push_back_base_cost: Some(52),
2151            vector_push_back_legacy_per_abstract_memory_unit_cost: Some(2),
2152            vector_borrow_base_cost: Some(52),
2153            vector_pop_back_base_cost: Some(52),
2154            vector_destroy_empty_base_cost: Some(52),
2155            vector_swap_base_cost: Some(52),
2156            debug_print_base_cost: Some(52),
2157            debug_print_stack_trace_base_cost: Some(52),
2158
2159            max_size_written_objects: Some(5 * 1000 * 1000),
2160            // max size of written objects during a system TXn to allow for larger writes
2161            // akin to `max_size_written_objects` but for system TXns
2162            max_size_written_objects_system_tx: Some(50 * 1000 * 1000),
2163
2164            // Limits the length of a Move identifier
2165            max_move_identifier_len: Some(128),
2166            max_move_value_depth: Some(128),
2167            max_move_enum_variants: None,
2168
2169            gas_rounding_step: Some(1_000),
2170
2171            execution_version: Some(1),
2172
2173            // We maintain the same total size limit for events, but increase the number of
2174            // events that can be emitted.
2175            max_event_emit_size_total: Some(
2176                256 /* former event count limit */ * 250 * 1024, // size limit per event
2177            ),
2178
2179            // Taking a baby step approach, we consider only 20% by stake as bad nodes so we
2180            // have a 80% by stake of nodes participating in the leader committee. That
2181            // allow us for more redundancy in case we have validators
2182            // under performing - since the responsibility is shared
2183            // amongst more nodes. We can increase that once we do have
2184            // higher confidence.
2185            consensus_bad_nodes_stake_threshold: Some(20),
2186
2187            // Max of 10 votes per hour.
2188            #[allow(deprecated)]
2189            max_jwk_votes_per_validator_per_epoch: Some(240),
2190
2191            #[allow(deprecated)]
2192            max_age_of_jwk_in_epochs: Some(1),
2193
2194            consensus_max_transaction_size_bytes: Some(256 * 1024), // 256KB
2195
2196            // Assume 1KB per transaction and 500 transactions per block.
2197            consensus_max_transactions_in_block_bytes: Some(512 * 1024),
2198
2199            random_beacon_reduction_allowed_delta: Some(800),
2200
2201            random_beacon_reduction_lower_bound: Some(1000),
2202            random_beacon_dkg_timeout_round: Some(3000),
2203            random_beacon_min_round_interval_ms: Some(500),
2204
2205            random_beacon_dkg_version: Some(1),
2206
2207            // Assume 20_000 TPS * 5% max stake per validator / (minimum) 4 blocks per round
2208            // = 250 transactions per block maximum Using a higher limit
2209            // that is 512, to account for bursty traffic and system transactions.
2210            consensus_max_num_transactions_in_block: Some(512),
2211
2212            max_deferral_rounds_for_congestion_control: Some(10),
2213
2214            min_checkpoint_interval_ms: Some(200),
2215
2216            checkpoint_summary_version_specific_data: Some(1),
2217
2218            max_soft_bundle_size: Some(5),
2219
2220            bridge_should_try_to_finalize_committee: None,
2221
2222            max_accumulated_txn_cost_per_object_in_mysticeti_commit: Some(10),
2223
2224            max_committee_members_count: None,
2225
2226            consensus_gc_depth: None,
2227
2228            consensus_max_acknowledgments_per_block: None,
2229
2230            max_congestion_limit_overshoot_per_commit: None,
2231
2232            scorer_version: None,
2233
2234            // `auth_context` module
2235            auth_context_digest_cost_base: None,
2236            auth_context_tx_data_bytes_cost_base: None,
2237            auth_context_tx_data_bytes_cost_per_byte: None,
2238            auth_context_tx_commands_cost_base: None,
2239            auth_context_tx_commands_cost_per_byte: None,
2240            auth_context_tx_inputs_cost_base: None,
2241            auth_context_tx_inputs_cost_per_byte: None,
2242            auth_context_replace_cost_base: None,
2243            auth_context_replace_cost_per_byte: None,
2244            // When adding a new constant, set it to None in the earliest version, like this:
2245            // new_constant: None,
2246        };
2247
2248        cfg.feature_flags.consensus_transaction_ordering = ConsensusTransactionOrdering::ByGasPrice;
2249
2250        // MoveVM related flags
2251        {
2252            cfg.feature_flags
2253                .disable_invariant_violation_check_in_swap_loc = true;
2254            cfg.feature_flags.no_extraneous_module_bytes = true;
2255            cfg.feature_flags.hardened_otw_check = true;
2256            cfg.feature_flags.rethrow_serialization_type_layout_errors = true;
2257        }
2258
2259        // zkLogin related flags
2260        {
2261            #[allow(deprecated)]
2262            {
2263                cfg.feature_flags.zklogin_max_epoch_upper_bound_delta = Some(30);
2264            }
2265        }
2266
2267        // Enable Mysticeti on mainnet.
2268        cfg.feature_flags.consensus_choice = ConsensusChoice::Mysticeti;
2269        // Use tonic networking for Mysticeti.
2270        cfg.feature_flags.consensus_network = ConsensusNetwork::Tonic;
2271
2272        cfg.feature_flags.per_object_congestion_control_mode =
2273            PerObjectCongestionControlMode::TotalTxCount;
2274
2275        // Do not allow bridge committee to finalize on mainnet.
2276        cfg.bridge_should_try_to_finalize_committee = Some(chain != Chain::Mainnet);
2277
2278        // Devnet
2279        if chain != Chain::Mainnet && chain != Chain::Testnet {
2280            cfg.feature_flags.enable_poseidon = true;
2281            cfg.poseidon_bn254_cost_base = Some(260);
2282            cfg.poseidon_bn254_cost_per_block = Some(10);
2283
2284            cfg.feature_flags.enable_group_ops_native_function_msm = true;
2285
2286            cfg.feature_flags.enable_vdf = true;
2287            // Set to 30x and 2x the cost of a signature verification for now. This
2288            // should be updated along with other native crypto functions.
2289            cfg.vdf_verify_vdf_cost = Some(1500);
2290            cfg.vdf_hash_to_input_cost = Some(100);
2291
2292            cfg.feature_flags.passkey_auth = true;
2293        }
2294
2295        for cur in 2..=version.0 {
2296            match cur {
2297                1 => unreachable!(),
2298                // version 2 is a new framework version but with no config changes
2299                2 => {}
2300                3 => {
2301                    cfg.feature_flags.relocate_event_module = true;
2302                }
2303                4 => {
2304                    cfg.max_type_to_layout_nodes = Some(512);
2305                }
2306                5 => {
2307                    cfg.feature_flags.protocol_defined_base_fee = true;
2308                    cfg.base_gas_price = Some(1000);
2309
2310                    cfg.feature_flags.disallow_new_modules_in_deps_only_packages = true;
2311                    cfg.feature_flags.convert_type_argument_error = true;
2312                    cfg.feature_flags.native_charging_v2 = true;
2313
2314                    if chain != Chain::Mainnet && chain != Chain::Testnet {
2315                        cfg.feature_flags.uncompressed_g1_group_elements = true;
2316                    }
2317
2318                    cfg.gas_model_version = Some(2);
2319
2320                    cfg.poseidon_bn254_cost_per_block = Some(388);
2321
2322                    cfg.bls12381_bls12381_min_sig_verify_cost_base = Some(44064);
2323                    cfg.bls12381_bls12381_min_pk_verify_cost_base = Some(49282);
2324                    cfg.ecdsa_k1_secp256k1_verify_keccak256_cost_base = Some(1470);
2325                    cfg.ecdsa_k1_secp256k1_verify_sha256_cost_base = Some(1470);
2326                    cfg.ecdsa_r1_secp256r1_verify_sha256_cost_base = Some(4225);
2327                    cfg.ecdsa_r1_secp256r1_verify_keccak256_cost_base = Some(4225);
2328                    cfg.ecvrf_ecvrf_verify_cost_base = Some(4848);
2329                    cfg.ed25519_ed25519_verify_cost_base = Some(1802);
2330
2331                    // Manually changed to be "under cost"
2332                    cfg.ecdsa_r1_ecrecover_keccak256_cost_base = Some(1173);
2333                    cfg.ecdsa_r1_ecrecover_sha256_cost_base = Some(1173);
2334                    cfg.ecdsa_k1_ecrecover_keccak256_cost_base = Some(500);
2335                    cfg.ecdsa_k1_ecrecover_sha256_cost_base = Some(500);
2336
2337                    cfg.groth16_prepare_verifying_key_bls12381_cost_base = Some(53838);
2338                    cfg.groth16_prepare_verifying_key_bn254_cost_base = Some(82010);
2339                    cfg.groth16_verify_groth16_proof_internal_bls12381_cost_base = Some(72090);
2340                    cfg.groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input =
2341                        Some(8213);
2342                    cfg.groth16_verify_groth16_proof_internal_bn254_cost_base = Some(115502);
2343                    cfg.groth16_verify_groth16_proof_internal_bn254_cost_per_public_input =
2344                        Some(9484);
2345
2346                    cfg.hash_keccak256_cost_base = Some(10);
2347                    cfg.hash_blake2b256_cost_base = Some(10);
2348
2349                    // group ops
2350                    cfg.group_ops_bls12381_decode_scalar_cost = Some(7);
2351                    cfg.group_ops_bls12381_decode_g1_cost = Some(2848);
2352                    cfg.group_ops_bls12381_decode_g2_cost = Some(3770);
2353                    cfg.group_ops_bls12381_decode_gt_cost = Some(3068);
2354
2355                    cfg.group_ops_bls12381_scalar_add_cost = Some(10);
2356                    cfg.group_ops_bls12381_g1_add_cost = Some(1556);
2357                    cfg.group_ops_bls12381_g2_add_cost = Some(3048);
2358                    cfg.group_ops_bls12381_gt_add_cost = Some(188);
2359
2360                    cfg.group_ops_bls12381_scalar_sub_cost = Some(10);
2361                    cfg.group_ops_bls12381_g1_sub_cost = Some(1550);
2362                    cfg.group_ops_bls12381_g2_sub_cost = Some(3019);
2363                    cfg.group_ops_bls12381_gt_sub_cost = Some(497);
2364
2365                    cfg.group_ops_bls12381_scalar_mul_cost = Some(11);
2366                    cfg.group_ops_bls12381_g1_mul_cost = Some(4842);
2367                    cfg.group_ops_bls12381_g2_mul_cost = Some(9108);
2368                    cfg.group_ops_bls12381_gt_mul_cost = Some(27490);
2369
2370                    cfg.group_ops_bls12381_scalar_div_cost = Some(91);
2371                    cfg.group_ops_bls12381_g1_div_cost = Some(5091);
2372                    cfg.group_ops_bls12381_g2_div_cost = Some(9206);
2373                    cfg.group_ops_bls12381_gt_div_cost = Some(27804);
2374
2375                    cfg.group_ops_bls12381_g1_hash_to_base_cost = Some(2962);
2376                    cfg.group_ops_bls12381_g2_hash_to_base_cost = Some(8688);
2377
2378                    cfg.group_ops_bls12381_g1_msm_base_cost = Some(62648);
2379                    cfg.group_ops_bls12381_g2_msm_base_cost = Some(131192);
2380                    cfg.group_ops_bls12381_g1_msm_base_cost_per_input = Some(1333);
2381                    cfg.group_ops_bls12381_g2_msm_base_cost_per_input = Some(3216);
2382
2383                    cfg.group_ops_bls12381_uncompressed_g1_to_g1_cost = Some(677);
2384                    cfg.group_ops_bls12381_g1_to_uncompressed_g1_cost = Some(2099);
2385                    cfg.group_ops_bls12381_uncompressed_g1_sum_base_cost = Some(77);
2386                    cfg.group_ops_bls12381_uncompressed_g1_sum_cost_per_term = Some(26);
2387                    cfg.group_ops_bls12381_uncompressed_g1_sum_max_terms = Some(1200);
2388
2389                    cfg.group_ops_bls12381_pairing_cost = Some(26897);
2390
2391                    cfg.validator_validate_metadata_cost_base = Some(20000);
2392
2393                    cfg.max_committee_members_count = Some(50);
2394                }
2395                6 => {
2396                    cfg.max_ptb_value_size = Some(1024 * 1024);
2397                }
2398                7 => {
2399                    // version 7 is a new framework version but with no config
2400                    // changes
2401                }
2402                8 => {
2403                    cfg.feature_flags.variant_nodes = true;
2404
2405                    if chain != Chain::Mainnet {
2406                        // Enable round prober in consensus.
2407                        cfg.feature_flags.consensus_round_prober = true;
2408                        // Enable distributed vote scoring.
2409                        cfg.feature_flags
2410                            .consensus_distributed_vote_scoring_strategy = true;
2411                        cfg.feature_flags.consensus_linearize_subdag_v2 = true;
2412                        // Enable smart ancestor selection for testnet
2413                        cfg.feature_flags.consensus_smart_ancestor_selection = true;
2414                        // Enable probing for accepted rounds in round prober for testnet
2415                        cfg.feature_flags
2416                            .consensus_round_prober_probe_accepted_rounds = true;
2417                        // Enable zstd compression for consensus in testnet
2418                        cfg.feature_flags.consensus_zstd_compression = true;
2419                        // Assuming a round rate of max 15/sec, then using a gc depth of 60 allow
2420                        // blocks within a window of ~4 seconds
2421                        // to be included before be considered garbage collected.
2422                        cfg.consensus_gc_depth = Some(60);
2423                    }
2424
2425                    // Enable min_free_execution_slot for the shared object congestion tracker in
2426                    // devnet.
2427                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2428                        cfg.feature_flags.congestion_control_min_free_execution_slot = true;
2429                    }
2430                }
2431                9 => {
2432                    if chain != Chain::Mainnet {
2433                        // Disable smart ancestor selection in the testnet and devnet.
2434                        cfg.feature_flags.consensus_smart_ancestor_selection = false;
2435                    }
2436
2437                    // Enable zstd compression for consensus
2438                    cfg.feature_flags.consensus_zstd_compression = true;
2439
2440                    // Enable passkey in multisig in devnet.
2441                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2442                        cfg.feature_flags.accept_passkey_in_multisig = true;
2443                    }
2444
2445                    // this flag is now deprecated because of the bridge removal.
2446                    cfg.bridge_should_try_to_finalize_committee = None;
2447                }
2448                10 => {
2449                    // Enable min_free_execution_slot for the shared object congestion tracker in
2450                    // all networks.
2451                    cfg.feature_flags.congestion_control_min_free_execution_slot = true;
2452
2453                    // Increase the committee size to 80 on all networks.
2454                    cfg.max_committee_members_count = Some(80);
2455
2456                    // Enable round prober in consensus.
2457                    cfg.feature_flags.consensus_round_prober = true;
2458                    // Enable probing for accepted rounds in round.
2459                    cfg.feature_flags
2460                        .consensus_round_prober_probe_accepted_rounds = true;
2461                    // Enable distributed vote scoring.
2462                    cfg.feature_flags
2463                        .consensus_distributed_vote_scoring_strategy = true;
2464                    // Enable the new consensus commit rule.
2465                    cfg.feature_flags.consensus_linearize_subdag_v2 = true;
2466
2467                    // Enable consensus garbage collection
2468                    // Assuming a round rate of max 15/sec, then using a gc depth of 60 allow
2469                    // blocks within a window of ~4 seconds
2470                    // to be included before be considered garbage collected.
2471                    cfg.consensus_gc_depth = Some(60);
2472
2473                    // Enable minimized child object mutation counting.
2474                    cfg.feature_flags.minimize_child_object_mutations = true;
2475
2476                    if chain != Chain::Mainnet {
2477                        // Enable batched block sync in devnet and testnet.
2478                        cfg.feature_flags.consensus_batched_block_sync = true;
2479                    }
2480
2481                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2482                        // Enable the gas price feedback mechanism (which is used for
2483                        // transactions cancelled due to shared object congestion) in devnet
2484                        cfg.feature_flags
2485                            .congestion_control_gas_price_feedback_mechanism = true;
2486                    }
2487
2488                    cfg.feature_flags.validate_identifier_inputs = true;
2489                    cfg.feature_flags.dependency_linkage_error = true;
2490                    cfg.feature_flags.additional_multisig_checks = true;
2491                }
2492                11 => {
2493                    // version 11 is a new framework version but with no config
2494                    // changes
2495                }
2496                12 => {
2497                    // Enable the gas price feedback mechanism for transactions
2498                    // cancelled due to congestion in all networks
2499                    cfg.feature_flags
2500                        .congestion_control_gas_price_feedback_mechanism = true;
2501
2502                    // Enable normalization of PTB arguments in all networks.
2503                    cfg.feature_flags.normalize_ptb_arguments = true;
2504                }
2505                13 => {
2506                    // Enable selecting committee based on eligible active validators on all
2507                    // networks.
2508                    cfg.feature_flags.select_committee_from_eligible_validators = true;
2509                    // Enable tracking non-committee eligible active
2510                    // validators on all networks.
2511                    cfg.feature_flags.track_non_committee_eligible_validators = true;
2512
2513                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2514                        // Enable selecting committee only from active validators that next epoch
2515                        // version and issued valid AuthorityCapabilities notification in devnet.
2516                        cfg.feature_flags
2517                            .select_committee_supporting_next_epoch_version = true;
2518                    }
2519                }
2520                14 => {
2521                    // Enable batched block sync for mainnet.
2522                    cfg.feature_flags.consensus_batched_block_sync = true;
2523
2524                    if chain != Chain::Mainnet {
2525                        // Enable median-based commit timestamp calculation in consensus and
2526                        // enforce checkpoint timestamp monotonicity for testnet.
2527                        cfg.feature_flags
2528                            .consensus_median_timestamp_with_checkpoint_enforcement = true;
2529                        // Enable selecting committee only from active validators that support the
2530                        // next epoch's version and issued valid AuthorityCapabilities notification
2531                        // in testnet.
2532                        cfg.feature_flags
2533                            .select_committee_supporting_next_epoch_version = true;
2534                    }
2535                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2536                        // Switch consensus protocol to Starfish in devnet
2537                        cfg.feature_flags.consensus_choice = ConsensusChoice::Starfish;
2538                    }
2539                }
2540                15 => {
2541                    if chain != Chain::Mainnet && chain != Chain::Testnet {
2542                        // Enable overshoot of 100 in congestion control. This allows bursts of
2543                        // shared object transactions up to 10 times the average allowable
2544                        // load set by `max_accumulated_txn_cost_per_object_in_mysticeti_commit`.
2545                        cfg.max_congestion_limit_overshoot_per_commit = Some(100);
2546                    }
2547                }
2548                16 => {
2549                    // Enable selecting committee only from active validators that support the
2550                    // next epoch's version and issued valid AuthorityCapabilities notification.
2551                    cfg.feature_flags
2552                        .select_committee_supporting_next_epoch_version = true;
2553                    // Enable committing transactions only for traversed headers in Starfish
2554                    cfg.feature_flags
2555                        .consensus_commit_transactions_only_for_traversed_headers = true;
2556                }
2557                17 => {
2558                    // Increase the committee size to 100 on all networks.
2559                    cfg.max_committee_members_count = Some(100);
2560                }
2561                18 => {
2562                    if chain != Chain::Mainnet {
2563                        // Enable passkey authentication support in testnet.
2564                        cfg.feature_flags.passkey_auth = true;
2565                    }
2566                }
2567                19 => {
2568                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2569                        // Enable congestion limit overshoot in the gas price feedback
2570                        // mechanism on devnet.
2571                        cfg.feature_flags
2572                            .congestion_limit_overshoot_in_gas_price_feedback_mechanism = true;
2573                        // Enable a separate gas price feedback mechanism for transactions using
2574                        // randomness on devnet.
2575                        cfg.feature_flags
2576                            .separate_gas_price_feedback_mechanism_for_randomness = true;
2577                        // Enable storing metadata in module bytes and then
2578                        // publishing package metadata in devnet
2579                        cfg.feature_flags.metadata_in_module_bytes = true;
2580                        cfg.feature_flags.publish_package_metadata = true;
2581                        // Enable Move authentication in devnet
2582                        cfg.feature_flags.enable_move_authentication = true;
2583                        // Max auth gas budget is in NANOS and an absolute value 0.25 IOTA
2584                        cfg.max_auth_gas = Some(250_000_000);
2585                        // Increase the base cost for transfer receive object in devnet, since the
2586                        // implementation now does check if parent is not an account.
2587                        cfg.transfer_receive_object_cost_base = Some(100);
2588                        // Enable adjustment of validator rewards based on score in devnet.
2589                        cfg.feature_flags.adjust_rewards_by_score = true;
2590                    }
2591
2592                    if chain != Chain::Mainnet {
2593                        // Switch consensus protocol to Starfish in testnet.
2594                        cfg.feature_flags.consensus_choice = ConsensusChoice::Starfish;
2595
2596                        // Enable validator score calculation on testnet
2597                        cfg.feature_flags.calculate_validator_scores = true;
2598                        cfg.scorer_version = Some(1);
2599                    }
2600
2601                    // Change epoch transaction will contain validator scores
2602                    cfg.feature_flags.pass_validator_scores_to_advance_epoch = true;
2603
2604                    // Enable passkey authentication support in mainnet
2605                    cfg.feature_flags.passkey_auth = true;
2606                }
2607                20 => {
2608                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2609                        // Passes the calculated validator scores to advance epoch only on Devnet
2610                        cfg.feature_flags
2611                            .pass_calculated_validator_scores_to_advance_epoch = true;
2612                    }
2613                }
2614                21 => {
2615                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2616                        // Enable fast commit syncer for faster recovery in devnet.
2617                        cfg.feature_flags.consensus_fast_commit_sync = true;
2618                    }
2619                    if chain != Chain::Mainnet {
2620                        // Enable overshoot of 100 in congestion control on testnet.
2621                        // This allows bursts of shared-object transactions
2622                        // up to 10 times the average allowable load set by
2623                        // `max_accumulated_txn_cost_per_object_in_mysticeti_commit`.
2624                        cfg.max_congestion_limit_overshoot_per_commit = Some(100);
2625                        // Enable congestion limit overshoot in the gas price feedback
2626                        // mechanism on testnet.
2627                        cfg.feature_flags
2628                            .congestion_limit_overshoot_in_gas_price_feedback_mechanism = true;
2629                        // Enable a separate gas price feedback mechanism for transactions using
2630                        // randomness on testnet.
2631                        cfg.feature_flags
2632                            .separate_gas_price_feedback_mechanism_for_randomness = true;
2633                    }
2634
2635                    cfg.auth_context_digest_cost_base = Some(30);
2636                    cfg.auth_context_tx_commands_cost_base = Some(30);
2637                    cfg.auth_context_tx_commands_cost_per_byte = Some(2);
2638                    cfg.auth_context_tx_inputs_cost_base = Some(30);
2639                    cfg.auth_context_tx_inputs_cost_per_byte = Some(2);
2640                    cfg.auth_context_replace_cost_base = Some(30);
2641                    cfg.auth_context_replace_cost_per_byte = Some(2);
2642
2643                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2644                        // Decrease max_auth_gas to 0.00025 IOTA
2645                        cfg.max_auth_gas = Some(250_000);
2646                    }
2647                }
2648                22 => {
2649                    // Enable overshoot of 100 in congestion control on all networks.
2650                    // This allows bursts of shared-object transactions
2651                    // up to 10 times the average allowable load set by
2652                    // `max_accumulated_txn_cost_per_object_in_mysticeti_commit`.
2653                    cfg.max_congestion_limit_overshoot_per_commit = Some(100);
2654                    // Enable congestion limit overshoot in the gas price feedback
2655                    // mechanism on all networks.
2656                    cfg.feature_flags
2657                        .congestion_limit_overshoot_in_gas_price_feedback_mechanism = true;
2658                    // Enable a separate gas price feedback mechanism for transactions using
2659                    // randomness on all networks.
2660                    cfg.feature_flags
2661                        .separate_gas_price_feedback_mechanism_for_randomness = true;
2662
2663                    if chain != Chain::Mainnet {
2664                        // Enable storing metadata in module bytes and then
2665                        // publishing package metadata in testnet
2666                        cfg.feature_flags.metadata_in_module_bytes = true;
2667                        cfg.feature_flags.publish_package_metadata = true;
2668                        // Enable Move authentication in testnet
2669                        cfg.feature_flags.enable_move_authentication = true;
2670                        // Max_auth_gas is 0.00025 IOTA
2671                        cfg.max_auth_gas = Some(250_000);
2672                        // Increase the base cost for transfer receive object in testnet, since the
2673                        // implementation now does check if parent is not an account.
2674                        cfg.transfer_receive_object_cost_base = Some(100);
2675                    }
2676
2677                    if chain != Chain::Mainnet {
2678                        // Enable fast commit syncer for faster recovery on testnet.
2679                        cfg.feature_flags.consensus_fast_commit_sync = true;
2680                    }
2681                }
2682                23 => {
2683                    // Enable Move native context (TxContext via native functions) in all networks.
2684                    cfg.feature_flags.move_native_tx_context = true;
2685                    cfg.tx_context_fresh_id_cost_base = Some(52);
2686                    cfg.tx_context_sender_cost_base = Some(30);
2687                    cfg.tx_context_digest_cost_base = Some(30);
2688                    cfg.tx_context_epoch_cost_base = Some(30);
2689                    cfg.tx_context_epoch_timestamp_ms_cost_base = Some(30);
2690                    cfg.tx_context_sponsor_cost_base = Some(30);
2691                    cfg.tx_context_rgp_cost_base = Some(30);
2692                    cfg.tx_context_gas_price_cost_base = Some(30);
2693                    cfg.tx_context_gas_budget_cost_base = Some(30);
2694                    cfg.tx_context_ids_created_cost_base = Some(30);
2695                    cfg.tx_context_replace_cost_base = Some(30);
2696                }
2697                24 => {
2698                    // Switch consensus protocol to Starfish in all networks.
2699                    cfg.feature_flags.consensus_choice = ConsensusChoice::Starfish;
2700
2701                    if chain != Chain::Testnet && chain != Chain::Mainnet {
2702                        // Enable Move-based sponsor account authentication in devnet.
2703                        cfg.feature_flags.enable_move_authentication_for_sponsor = true;
2704                    }
2705
2706                    // Add tx_data_bytes to AuthContext for intent-based signature
2707                    // verification in account abstraction.
2708                    cfg.auth_context_tx_data_bytes_cost_base = Some(30);
2709                    cfg.auth_context_tx_data_bytes_cost_per_byte = Some(2);
2710
2711                    // Enable additional borrow checks.
2712                    cfg.feature_flags.additional_borrow_checks = true;
2713                }
2714                #[allow(deprecated)]
2715                25 => {
2716                    // Deprecate zkLogin related parameters since zkLogin is deprecated and was
2717                    // never enabled on IOTA.
2718                    cfg.feature_flags.zklogin_max_epoch_upper_bound_delta = None;
2719                    cfg.check_zklogin_id_cost_base = None;
2720                    cfg.check_zklogin_issuer_cost_base = None;
2721                    cfg.max_jwk_votes_per_validator_per_epoch = None;
2722                    cfg.max_age_of_jwk_in_epochs = None;
2723                }
2724
2725                // Use this template when making changes:
2726                //
2727                //     // modify an existing constant.
2728                //     move_binary_format_version: Some(7),
2729                //
2730                //     // Add a new constant (which is set to None in prior versions).
2731                //     new_constant: Some(new_value),
2732                //
2733                //     // Remove a constant (ensure that it is never accessed during this version).
2734                //     max_move_object_size: None,
2735                _ => panic!("unsupported version {version:?}"),
2736            }
2737        }
2738        cfg
2739    }
2740
2741    // Extract the bytecode verifier config from this protocol config.
2742    // If used during signing, `signing_limits` should be set.
2743    // The third limit configures`sanity_check_with_regex_reference_safety`,
2744    // which runs the new regex-based reference safety check to check that it is
2745    // strictly more permissive than the current implementation.
2746    pub fn verifier_config(&self, signing_limits: Option<(usize, usize, usize)>) -> VerifierConfig {
2747        let (
2748            max_back_edges_per_function,
2749            max_back_edges_per_module,
2750            sanity_check_with_regex_reference_safety,
2751        ) = if let Some((
2752            max_back_edges_per_function,
2753            max_back_edges_per_module,
2754            sanity_check_with_regex_reference_safety,
2755        )) = signing_limits
2756        {
2757            (
2758                Some(max_back_edges_per_function),
2759                Some(max_back_edges_per_module),
2760                Some(sanity_check_with_regex_reference_safety),
2761            )
2762        } else {
2763            (None, None, None)
2764        };
2765
2766        let additional_borrow_checks = if signing_limits.is_some() {
2767            // Always apply additional borrow checks during signing regardless of
2768            // protocol version, to prevent accepting potentially unsafe bytecode.
2769            true
2770        } else {
2771            self.additional_borrow_checks()
2772        };
2773
2774        VerifierConfig {
2775            max_loop_depth: Some(self.max_loop_depth() as usize),
2776            max_generic_instantiation_length: Some(self.max_generic_instantiation_length() as usize),
2777            max_function_parameters: Some(self.max_function_parameters() as usize),
2778            max_basic_blocks: Some(self.max_basic_blocks() as usize),
2779            max_value_stack_size: self.max_value_stack_size() as usize,
2780            max_type_nodes: Some(self.max_type_nodes() as usize),
2781            max_push_size: Some(self.max_push_size() as usize),
2782            max_dependency_depth: Some(self.max_dependency_depth() as usize),
2783            max_fields_in_struct: Some(self.max_fields_in_struct() as usize),
2784            max_function_definitions: Some(self.max_function_definitions() as usize),
2785            max_data_definitions: Some(self.max_struct_definitions() as usize),
2786            max_constant_vector_len: Some(self.max_move_vector_len()),
2787            max_back_edges_per_function,
2788            max_back_edges_per_module,
2789            max_basic_blocks_in_script: None,
2790            max_identifier_len: self.max_move_identifier_len_as_option(), /* Before protocol
2791                                                                           * version 9, there was
2792                                                                           * no limit */
2793            bytecode_version: self.move_binary_format_version(),
2794            max_variants_in_enum: self.max_move_enum_variants_as_option(),
2795            additional_borrow_checks,
2796            sanity_check_with_regex_reference_safety: sanity_check_with_regex_reference_safety
2797                .map(|limit| limit as u128),
2798        }
2799    }
2800
2801    /// Override one or more settings in the config, for testing.
2802    /// This must be called at the beginning of the test, before
2803    /// get_for_(min|max)_version is called, since those functions cache
2804    /// their return value.
2805    pub fn apply_overrides_for_testing(
2806        override_fn: impl Fn(ProtocolVersion, Self) -> Self + Send + Sync + 'static,
2807    ) -> OverrideGuard {
2808        CONFIG_OVERRIDE.with(|ovr| {
2809            let mut cur = ovr.borrow_mut();
2810            assert!(cur.is_none(), "config override already present");
2811            *cur = Some(Box::new(override_fn));
2812            OverrideGuard
2813        })
2814    }
2815}
2816
2817// Setters for tests.
2818// This is only needed for feature_flags. Please suffix each setter with
2819// `_for_testing`. Non-feature_flags should already have test setters defined
2820// through macros.
2821impl ProtocolConfig {
2822    pub fn set_per_object_congestion_control_mode_for_testing(
2823        &mut self,
2824        val: PerObjectCongestionControlMode,
2825    ) {
2826        self.feature_flags.per_object_congestion_control_mode = val;
2827    }
2828
2829    pub fn set_consensus_choice_for_testing(&mut self, val: ConsensusChoice) {
2830        self.feature_flags.consensus_choice = val;
2831    }
2832
2833    pub fn set_consensus_network_for_testing(&mut self, val: ConsensusNetwork) {
2834        self.feature_flags.consensus_network = val;
2835    }
2836
2837    pub fn set_passkey_auth_for_testing(&mut self, val: bool) {
2838        self.feature_flags.passkey_auth = val
2839    }
2840
2841    pub fn set_disallow_new_modules_in_deps_only_packages_for_testing(&mut self, val: bool) {
2842        self.feature_flags
2843            .disallow_new_modules_in_deps_only_packages = val;
2844    }
2845
2846    pub fn set_consensus_round_prober_for_testing(&mut self, val: bool) {
2847        self.feature_flags.consensus_round_prober = val;
2848    }
2849
2850    pub fn set_consensus_distributed_vote_scoring_strategy_for_testing(&mut self, val: bool) {
2851        self.feature_flags
2852            .consensus_distributed_vote_scoring_strategy = val;
2853    }
2854
2855    pub fn set_gc_depth_for_testing(&mut self, val: u32) {
2856        self.consensus_gc_depth = Some(val);
2857    }
2858
2859    pub fn set_consensus_linearize_subdag_v2_for_testing(&mut self, val: bool) {
2860        self.feature_flags.consensus_linearize_subdag_v2 = val;
2861    }
2862
2863    pub fn set_consensus_round_prober_probe_accepted_rounds(&mut self, val: bool) {
2864        self.feature_flags
2865            .consensus_round_prober_probe_accepted_rounds = val;
2866    }
2867
2868    pub fn set_accept_passkey_in_multisig_for_testing(&mut self, val: bool) {
2869        self.feature_flags.accept_passkey_in_multisig = val;
2870    }
2871
2872    pub fn set_consensus_smart_ancestor_selection_for_testing(&mut self, val: bool) {
2873        self.feature_flags.consensus_smart_ancestor_selection = val;
2874    }
2875
2876    pub fn set_consensus_batched_block_sync_for_testing(&mut self, val: bool) {
2877        self.feature_flags.consensus_batched_block_sync = val;
2878    }
2879
2880    pub fn set_congestion_control_min_free_execution_slot_for_testing(&mut self, val: bool) {
2881        self.feature_flags
2882            .congestion_control_min_free_execution_slot = val;
2883    }
2884
2885    pub fn set_congestion_control_gas_price_feedback_mechanism_for_testing(&mut self, val: bool) {
2886        self.feature_flags
2887            .congestion_control_gas_price_feedback_mechanism = val;
2888    }
2889
2890    pub fn set_select_committee_from_eligible_validators_for_testing(&mut self, val: bool) {
2891        self.feature_flags.select_committee_from_eligible_validators = val;
2892    }
2893
2894    pub fn set_track_non_committee_eligible_validators_for_testing(&mut self, val: bool) {
2895        self.feature_flags.track_non_committee_eligible_validators = val;
2896    }
2897
2898    pub fn set_select_committee_supporting_next_epoch_version(&mut self, val: bool) {
2899        self.feature_flags
2900            .select_committee_supporting_next_epoch_version = val;
2901    }
2902
2903    pub fn set_consensus_median_timestamp_with_checkpoint_enforcement_for_testing(
2904        &mut self,
2905        val: bool,
2906    ) {
2907        self.feature_flags
2908            .consensus_median_timestamp_with_checkpoint_enforcement = val;
2909    }
2910
2911    pub fn set_consensus_commit_transactions_only_for_traversed_headers_for_testing(
2912        &mut self,
2913        val: bool,
2914    ) {
2915        self.feature_flags
2916            .consensus_commit_transactions_only_for_traversed_headers = val;
2917    }
2918
2919    pub fn set_congestion_limit_overshoot_in_gas_price_feedback_mechanism_for_testing(
2920        &mut self,
2921        val: bool,
2922    ) {
2923        self.feature_flags
2924            .congestion_limit_overshoot_in_gas_price_feedback_mechanism = val;
2925    }
2926
2927    pub fn set_separate_gas_price_feedback_mechanism_for_randomness_for_testing(
2928        &mut self,
2929        val: bool,
2930    ) {
2931        self.feature_flags
2932            .separate_gas_price_feedback_mechanism_for_randomness = val;
2933    }
2934
2935    pub fn set_metadata_in_module_bytes_for_testing(&mut self, val: bool) {
2936        self.feature_flags.metadata_in_module_bytes = val;
2937    }
2938
2939    pub fn set_publish_package_metadata_for_testing(&mut self, val: bool) {
2940        self.feature_flags.publish_package_metadata = val;
2941    }
2942
2943    pub fn set_enable_move_authentication_for_testing(&mut self, val: bool) {
2944        self.feature_flags.enable_move_authentication = val;
2945    }
2946
2947    pub fn set_enable_move_authentication_for_sponsor_for_testing(&mut self, val: bool) {
2948        self.feature_flags.enable_move_authentication_for_sponsor = val;
2949    }
2950
2951    pub fn set_consensus_fast_commit_sync_for_testing(&mut self, val: bool) {
2952        self.feature_flags.consensus_fast_commit_sync = val;
2953    }
2954}
2955
2956type OverrideFn = dyn Fn(ProtocolVersion, ProtocolConfig) -> ProtocolConfig + Send + Sync;
2957
2958thread_local! {
2959    static CONFIG_OVERRIDE: RefCell<Option<Box<OverrideFn>>> = const { RefCell::new(None) };
2960}
2961
2962#[must_use]
2963pub struct OverrideGuard;
2964
2965impl Drop for OverrideGuard {
2966    fn drop(&mut self) {
2967        info!("restoring override fn");
2968        CONFIG_OVERRIDE.with(|ovr| {
2969            *ovr.borrow_mut() = None;
2970        });
2971    }
2972}
2973
2974/// Defines which limit got crossed.
2975/// The value which crossed the limit and value of the limit crossed are
2976/// embedded
2977#[derive(PartialEq, Eq)]
2978pub enum LimitThresholdCrossed {
2979    None,
2980    Soft(u128, u128),
2981    Hard(u128, u128),
2982}
2983
2984/// Convenience function for comparing limit ranges
2985/// V::MAX must be at >= U::MAX and T::MAX
2986pub fn check_limit_in_range<T: Into<V>, U: Into<V>, V: PartialOrd + Into<u128>>(
2987    x: T,
2988    soft_limit: U,
2989    hard_limit: V,
2990) -> LimitThresholdCrossed {
2991    let x: V = x.into();
2992    let soft_limit: V = soft_limit.into();
2993
2994    debug_assert!(soft_limit <= hard_limit);
2995
2996    // It is important to preserve this comparison order because if soft_limit ==
2997    // hard_limit we want LimitThresholdCrossed::Hard
2998    if x >= hard_limit {
2999        LimitThresholdCrossed::Hard(x.into(), hard_limit.into())
3000    } else if x < soft_limit {
3001        LimitThresholdCrossed::None
3002    } else {
3003        LimitThresholdCrossed::Soft(x.into(), soft_limit.into())
3004    }
3005}
3006
3007#[macro_export]
3008macro_rules! check_limit {
3009    ($x:expr, $hard:expr) => {
3010        check_limit!($x, $hard, $hard)
3011    };
3012    ($x:expr, $soft:expr, $hard:expr) => {
3013        check_limit_in_range($x as u64, $soft, $hard)
3014    };
3015}
3016
3017/// Used to check which limits were crossed if the TX is metered (not system tx)
3018/// Args are: is_metered, value_to_check, metered_limit, unmetered_limit
3019/// metered_limit is always less than or equal to unmetered_hard_limit
3020#[macro_export]
3021macro_rules! check_limit_by_meter {
3022    ($is_metered:expr, $x:expr, $metered_limit:expr, $unmetered_hard_limit:expr, $metric:expr) => {{
3023        // If this is metered, we use the metered_limit limit as the upper bound
3024        let (h, metered_str) = if $is_metered {
3025            ($metered_limit, "metered")
3026        } else {
3027            // Unmetered gets more headroom
3028            ($unmetered_hard_limit, "unmetered")
3029        };
3030        use iota_protocol_config::check_limit_in_range;
3031        let result = check_limit_in_range($x as u64, $metered_limit, h);
3032        match result {
3033            LimitThresholdCrossed::None => {}
3034            LimitThresholdCrossed::Soft(_, _) => {
3035                $metric.with_label_values(&[metered_str, "soft"]).inc();
3036            }
3037            LimitThresholdCrossed::Hard(_, _) => {
3038                $metric.with_label_values(&[metered_str, "hard"]).inc();
3039            }
3040        };
3041        result
3042    }};
3043}
3044
3045#[cfg(all(test, not(msim)))]
3046mod test {
3047    use insta::assert_yaml_snapshot;
3048
3049    use super::*;
3050
3051    #[test]
3052    fn snapshot_tests() {
3053        println!("\n============================================================================");
3054        println!("!                                                                          !");
3055        println!("! IMPORTANT: never update snapshots from this test. only add new versions! !");
3056        println!("!                                                                          !");
3057        println!("============================================================================\n");
3058        for chain_id in &[Chain::Unknown, Chain::Mainnet, Chain::Testnet] {
3059            // make Chain::Unknown snapshots compatible with pre-chain-id snapshots so that
3060            // we don't break the release-time compatibility tests. Once Chain
3061            // Id configs have been released everywhere, we can remove this and
3062            // only test Mainnet and Testnet
3063            let chain_str = match chain_id {
3064                Chain::Unknown => "".to_string(),
3065                _ => format!("{chain_id:?}_"),
3066            };
3067            for i in MIN_PROTOCOL_VERSION..=MAX_PROTOCOL_VERSION {
3068                let cur = ProtocolVersion::new(i);
3069                assert_yaml_snapshot!(
3070                    format!("{}version_{}", chain_str, cur.as_u64()),
3071                    ProtocolConfig::get_for_version(cur, *chain_id)
3072                );
3073            }
3074        }
3075    }
3076
3077    #[test]
3078    fn test_getters() {
3079        let prot: ProtocolConfig =
3080            ProtocolConfig::get_for_version(ProtocolVersion::new(1), Chain::Unknown);
3081        assert_eq!(
3082            prot.max_arguments(),
3083            prot.max_arguments_as_option().unwrap()
3084        );
3085    }
3086
3087    #[test]
3088    fn test_setters() {
3089        let mut prot: ProtocolConfig =
3090            ProtocolConfig::get_for_version(ProtocolVersion::new(1), Chain::Unknown);
3091        prot.set_max_arguments_for_testing(123);
3092        assert_eq!(prot.max_arguments(), 123);
3093
3094        prot.set_max_arguments_from_str_for_testing("321".to_string());
3095        assert_eq!(prot.max_arguments(), 321);
3096
3097        prot.disable_max_arguments_for_testing();
3098        assert_eq!(prot.max_arguments_as_option(), None);
3099
3100        prot.set_attr_for_testing("max_arguments".to_string(), "456".to_string());
3101        assert_eq!(prot.max_arguments(), 456);
3102    }
3103
3104    #[test]
3105    #[should_panic(expected = "unsupported version")]
3106    fn max_version_test() {
3107        // When this does not panic, version higher than MAX_PROTOCOL_VERSION exists.
3108        // To fix, bump MAX_PROTOCOL_VERSION or disable this check for the version.
3109        let _ = ProtocolConfig::get_for_version_impl(
3110            ProtocolVersion::new(MAX_PROTOCOL_VERSION + 1),
3111            Chain::Unknown,
3112        );
3113    }
3114
3115    #[test]
3116    fn lookup_by_string_test() {
3117        let prot: ProtocolConfig =
3118            ProtocolConfig::get_for_version(ProtocolVersion::new(1), Chain::Mainnet);
3119        // Does not exist
3120        assert!(prot.lookup_attr("some random string".to_string()).is_none());
3121
3122        assert!(
3123            prot.lookup_attr("max_arguments".to_string())
3124                == Some(ProtocolConfigValue::u32(prot.max_arguments())),
3125        );
3126
3127        // We didnt have this in version 1 on Mainnet
3128        assert!(
3129            prot.lookup_attr("poseidon_bn254_cost_base".to_string())
3130                .is_none()
3131        );
3132        assert!(
3133            prot.attr_map()
3134                .get("poseidon_bn254_cost_base")
3135                .unwrap()
3136                .is_none()
3137        );
3138
3139        // But we did in version 1 on Devnet
3140        let prot: ProtocolConfig =
3141            ProtocolConfig::get_for_version(ProtocolVersion::new(1), Chain::Unknown);
3142
3143        assert!(
3144            prot.lookup_attr("poseidon_bn254_cost_base".to_string())
3145                == Some(ProtocolConfigValue::u64(prot.poseidon_bn254_cost_base()))
3146        );
3147        assert!(
3148            prot.attr_map().get("poseidon_bn254_cost_base").unwrap()
3149                == &Some(ProtocolConfigValue::u64(prot.poseidon_bn254_cost_base()))
3150        );
3151
3152        // Check feature flags
3153        let prot: ProtocolConfig =
3154            ProtocolConfig::get_for_version(ProtocolVersion::new(1), Chain::Mainnet);
3155        // Does not exist
3156        assert!(
3157            prot.feature_flags
3158                .lookup_attr("some random string".to_owned())
3159                .is_none()
3160        );
3161        assert!(
3162            !prot
3163                .feature_flags
3164                .attr_map()
3165                .contains_key("some random string")
3166        );
3167
3168        // Was false in v1 on Mainnet
3169        assert!(prot.feature_flags.lookup_attr("enable_poseidon".to_owned()) == Some(false));
3170        assert!(
3171            prot.feature_flags
3172                .attr_map()
3173                .get("enable_poseidon")
3174                .unwrap()
3175                == &false
3176        );
3177        let prot: ProtocolConfig =
3178            ProtocolConfig::get_for_version(ProtocolVersion::new(1), Chain::Unknown);
3179        // Was true from v1 and up on Devnet
3180        assert!(prot.feature_flags.lookup_attr("enable_poseidon".to_owned()) == Some(true));
3181        assert!(
3182            prot.feature_flags
3183                .attr_map()
3184                .get("enable_poseidon")
3185                .unwrap()
3186                == &true
3187        );
3188    }
3189
3190    #[test]
3191    fn limit_range_fn_test() {
3192        let low = 100u32;
3193        let high = 10000u64;
3194
3195        assert!(check_limit!(1u8, low, high) == LimitThresholdCrossed::None);
3196        assert!(matches!(
3197            check_limit!(255u16, low, high),
3198            LimitThresholdCrossed::Soft(255u128, 100)
3199        ));
3200        // This wont compile because lossy
3201        // assert!(check_limit!(100000000u128, low, high) ==
3202        // LimitThresholdCrossed::None); This wont compile because lossy
3203        // assert!(check_limit!(100000000usize, low, high) ==
3204        // LimitThresholdCrossed::None);
3205
3206        assert!(matches!(
3207            check_limit!(2550000u64, low, high),
3208            LimitThresholdCrossed::Hard(2550000, 10000)
3209        ));
3210
3211        assert!(matches!(
3212            check_limit!(2550000u64, high, high),
3213            LimitThresholdCrossed::Hard(2550000, 10000)
3214        ));
3215
3216        assert!(matches!(
3217            check_limit!(1u8, high),
3218            LimitThresholdCrossed::None
3219        ));
3220
3221        assert!(check_limit!(255u16, high) == LimitThresholdCrossed::None);
3222
3223        assert!(matches!(
3224            check_limit!(2550000u64, high),
3225            LimitThresholdCrossed::Hard(2550000, 10000)
3226        ));
3227    }
3228}