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}