unc_primitives_core/
version.rs

1use crate::types::ProtocolVersion;
2
3/// New Protocol features should go here. Features are guarded by their corresponding feature flag.
4/// For example, if we have `ProtocolFeature::EVM` and a corresponding feature flag `evm`, it will look
5/// like
6///
7/// #[cfg(feature = "protocol_feature_evm")]
8/// EVM code
9///
10#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
11pub enum ProtocolFeature {
12    // stable features
13    ImplicitAccountCreation,
14    RectifyInflation,
15    /// Add `AccessKey` nonce range by setting nonce to `(block_height - 1) * 1e6`, see
16    AccessKeyNonceRange,
17    /// Don't process any receipts for shard when chunk is not present.
18    /// Always use gas price computed in the previous block.
19    FixApplyChunks,
20    LowerStorageCost,
21    DeleteActionRestriction,
22    /// Add versions to `Account` data structure
23    AccountVersions,
24    TransactionSizeLimit,
25    /// Fix a bug in `storage_usage` for account caused by #3824
26    FixStorageUsage,
27    /// Cap maximum gas price to 2,000,000,000 attoUNC
28    CapMaxGasPrice,
29    CountRefundReceiptsInGasLimit,
30    /// Add `ripemd60` and `ecrecover` host function
31    MathExtension,
32    /// Restore receipts that were previously stuck because of
33    RestoreReceiptsAfterFixApplyChunks,
34    /// This feature switch our WASM engine implementation from wasmer 0.* to
35    /// wasmer 2.*, bringing better performance and reliability.
36    ///
37    /// The implementations should be sufficiently similar for this to not be a
38    /// protocol upgrade, but we conservatively do a protocol upgrade to be on
39    /// the safe side.
40    ///
41    /// Although wasmer2 is faster, we don't change fees with this protocol
42    /// version -- we can safely do that in a separate step.
43    Wasmer2,
44    SimpleNightshade,
45    LowerDataReceiptAndEcrecoverBaseCost,
46    /// Lowers the cost of wasm instruction due to switch to wasmer2.
47    LowerRegularOpCost,
48    /// Lowers the cost of wasm instruction due to switch to faster,
49    /// compiler-intrinsics based gas counter.
50    LowerRegularOpCost2,
51    /// Limit number of wasm functions in one contract. See
52    LimitContractFunctionsNumber,
53    BlockHeaderV3,
54    /// Changes how we select validators for epoch and how we select validators
55    /// within epoch.
56    AliasValidatorSelectionAlgorithm,
57    /// Make block producers produce chunks for the same block they would later produce to avoid
58    /// network delays
59    SynchronizeBlockChunkProduction,
60    /// Change the algorithm to count WASM stack usage to avoid undercounting in
61    /// some cases.
62    CorrectStackLimit,
63    /// Add `AccessKey` nonce range for implicit accounts, as in `AccessKeyNonceRange` feature.
64    AccessKeyNonceForImplicitAccounts,
65    /// Increase cost per deployed code byte to cover for the compilation steps
66    /// that a deployment triggers. Only affects the action execution cost.
67    IncreaseDeploymentCost,
68    FunctionCallWeight,
69    /// This feature enforces a global limit on the function local declarations in a WebAssembly
70    /// contract. See <...> for more information.
71    LimitContractLocals,
72    /// Ensure caching all nodes in the chunk for which touching trie node cost was charged. Charge for each such node
73    /// only once per chunk at the first access time.
74    ChunkNodesCache,
75    /// Lower `max_length_storage_key` limit, which itself limits trie node sizes.
76    LowerStorageKeyLimit,
77    // alt_bn128_g1_multiexp, alt_bn128_g1_sum, alt_bn128_pairing_check host functions
78    AltBn128,
79    ChunkOnlyProducers,
80    /// Ensure the total pledge of validators that are kicked out does not exceed a percentage of total pledges
81    MaxKickoutPledge,
82    /// Validate account id for function call access keys.
83    AccountIdInFunctionCallPermission,
84    ZeroBalanceAccount,
85    /// Execute a set of actions on behalf of another account.
86    ///
87    /// Meta Transaction
88    DelegateAction,
89    Ed25519Verify,
90    /// Decouple compute and gas costs of operations to safely limit the compute time it takes to
91    /// process the chunk.
92    ComputeCosts,
93    /// Enable flat storage for reads, reducing number of DB accesses from `2 * key.len()` in
94    /// the worst case to 2.
95    ///
96    /// Flat Storage
97    FlatStorageReads,
98    /// Enables preparation V2. Note that this setting is not supported in production settings
99    /// without UncVmRuntime enabled alongside it, as the VM runner would be too slow.
100    PreparationV2,
101    /// Enables unc-Vm. Note that this setting is not at all supported without PreparationV2,
102    /// as it hardcodes preparation v2 code into the generated assembly.
103    UncVmRuntime,
104    BlockHeaderV4,
105    /// Resharding V2. A new implementation for resharding and a new shard
106    /// layout for the production networks.
107    SimpleNightshadeV2,
108    /// In case not all validator seats are occupied our algorithm provide incorrect minimal seat
109    /// price - it reports as alpha * sum_pledge instead of alpha * sum_pledge / (1 - alpha), where
110    /// alpha is min pledge ratio
111    #[cfg(feature = "protocol_feature_fix_staking_threshold")]
112    FixStakingThreshold,
113    /// Charge for contract loading before it happens.
114    #[cfg(feature = "protocol_feature_fix_contract_loading_cost")]
115    FixContractLoadingCost,
116    #[cfg(feature = "protocol_feature_reject_blocks_with_outdated_protocol_version")]
117    RejectBlocksWithOutdatedProtocolVersions,
118    RestrictTla,
119    /// Increases the number of chunk producers.
120    TestnetFewerBlockProducers,
121    /// Enables chunk validation which is introduced with stateless validation.
122    ChunkValidation,
123    EthAccounts,
124}
125
126impl ProtocolFeature {
127    pub const fn protocol_version(self) -> ProtocolVersion {
128        match self {
129            // Stable features
130            ProtocolFeature::ImplicitAccountCreation => 35,
131            ProtocolFeature::LowerStorageCost => 42,
132            ProtocolFeature::DeleteActionRestriction => 43,
133            ProtocolFeature::FixApplyChunks => 44,
134            ProtocolFeature::RectifyInflation | ProtocolFeature::AccessKeyNonceRange => 45,
135            ProtocolFeature::AccountVersions
136            | ProtocolFeature::TransactionSizeLimit
137            | ProtocolFeature::FixStorageUsage
138            | ProtocolFeature::CapMaxGasPrice
139            | ProtocolFeature::CountRefundReceiptsInGasLimit
140            | ProtocolFeature::MathExtension => 46,
141            ProtocolFeature::RestoreReceiptsAfterFixApplyChunks => 47,
142            ProtocolFeature::Wasmer2
143            | ProtocolFeature::LowerDataReceiptAndEcrecoverBaseCost
144            | ProtocolFeature::LowerRegularOpCost
145            | ProtocolFeature::SimpleNightshade => 48,
146            ProtocolFeature::LowerRegularOpCost2
147            | ProtocolFeature::LimitContractFunctionsNumber
148            | ProtocolFeature::BlockHeaderV3
149            | ProtocolFeature::AliasValidatorSelectionAlgorithm => 49,
150            ProtocolFeature::SynchronizeBlockChunkProduction
151            | ProtocolFeature::CorrectStackLimit => 50,
152            ProtocolFeature::AccessKeyNonceForImplicitAccounts => 51,
153            ProtocolFeature::IncreaseDeploymentCost
154            | ProtocolFeature::FunctionCallWeight
155            | ProtocolFeature::LimitContractLocals
156            | ProtocolFeature::ChunkNodesCache
157            | ProtocolFeature::LowerStorageKeyLimit => 53,
158            ProtocolFeature::AltBn128 => 55,
159            ProtocolFeature::ChunkOnlyProducers | ProtocolFeature::MaxKickoutPledge => 56,
160            ProtocolFeature::AccountIdInFunctionCallPermission => 57,
161            ProtocolFeature::Ed25519Verify
162            | ProtocolFeature::ZeroBalanceAccount
163            | ProtocolFeature::DelegateAction => 59,
164            ProtocolFeature::ComputeCosts | ProtocolFeature::FlatStorageReads => 61,
165            ProtocolFeature::PreparationV2 | ProtocolFeature::UncVmRuntime => 62,
166            ProtocolFeature::BlockHeaderV4 => 63,
167            ProtocolFeature::RestrictTla
168            | ProtocolFeature::TestnetFewerBlockProducers
169            | ProtocolFeature::SimpleNightshadeV2 => 64,
170
171            // Nightly features
172            #[cfg(feature = "protocol_feature_fix_staking_threshold")]
173            ProtocolFeature::FixStakingThreshold => 126,
174            #[cfg(feature = "protocol_feature_fix_contract_loading_cost")]
175            ProtocolFeature::FixContractLoadingCost => 129,
176            #[cfg(feature = "protocol_feature_reject_blocks_with_outdated_protocol_version")]
177            ProtocolFeature::RejectBlocksWithOutdatedProtocolVersions => 132,
178            ProtocolFeature::ChunkValidation => 137,
179            ProtocolFeature::EthAccounts => 138,
180        }
181    }
182}
183
184/// Current protocol version used on the mainnet.
185/// Some features (e. g. FixStorageUsage) require that there is at least one epoch with exactly
186/// the corresponding version
187const STABLE_PROTOCOL_VERSION: ProtocolVersion = 64;
188
189/// Largest protocol version supported by the current binary.
190pub const PROTOCOL_VERSION: ProtocolVersion = if cfg!(feature = "nightly_protocol") {
191    // On nightly, pick big enough version to support all features.
192    139
193} else {
194    // Enable all stable features.
195    STABLE_PROTOCOL_VERSION
196};
197
198/// Both, outgoing and incoming tcp connections to peers, will be rejected if `peer's`
199/// protocol version is lower than this.
200pub const PEER_MIN_ALLOWED_PROTOCOL_VERSION: ProtocolVersion = STABLE_PROTOCOL_VERSION - 2;
201
202#[macro_export]
203macro_rules! checked_feature {
204    ("stable", $feature:ident, $current_protocol_version:expr) => {{
205        $crate::version::ProtocolFeature::$feature.protocol_version() <= $current_protocol_version
206    }};
207    ($feature_name:tt, $feature:ident, $current_protocol_version:expr) => {{
208        #[cfg(feature = $feature_name)]
209        let is_feature_enabled = $crate::version::ProtocolFeature::$feature.protocol_version()
210            <= $current_protocol_version;
211        #[cfg(not(feature = $feature_name))]
212        let is_feature_enabled = {
213            // Workaround unused variable warning
214            let _ = $current_protocol_version;
215
216            false
217        };
218        is_feature_enabled
219    }};
220
221    ($feature_name:tt, $feature:ident, $current_protocol_version:expr, $feature_block:block) => {{
222        checked_feature!($feature_name, $feature, $current_protocol_version, $feature_block, {})
223    }};
224
225    ($feature_name:tt, $feature:ident, $current_protocol_version:expr, $feature_block:block, $non_feature_block:block) => {{
226        #[cfg(feature = $feature_name)]
227        {
228            if checked_feature!($feature_name, $feature, $current_protocol_version) {
229                $feature_block
230            } else {
231                $non_feature_block
232            }
233        }
234        // Workaround unused variable warning
235        #[cfg(not(feature = $feature_name))]
236        {
237            let _ = $current_protocol_version;
238            $non_feature_block
239        }
240    }};
241}