platform_version/version/
protocol_version.rs1use crate::error::PlatformVersionError;
2use crate::version::dpp_versions::DPPVersion;
3use crate::version::drive_abci_versions::DriveAbciVersion;
4use crate::version::drive_versions::DriveVersion;
5use crate::version::fee::FeeVersion;
6#[cfg(feature = "mock-versions")]
7use crate::version::mocks::v2_test::TEST_PLATFORM_V2;
8#[cfg(feature = "mock-versions")]
9use crate::version::mocks::v3_test::TEST_PLATFORM_V3;
10#[cfg(feature = "mock-versions")]
11use crate::version::mocks::TEST_PROTOCOL_VERSION_SHIFT_BYTES;
12use crate::version::system_data_contract_versions::SystemDataContractVersions;
13#[cfg(feature = "mock-versions")]
14use std::sync::OnceLock;
15
16use crate::version::consensus_versions::ConsensusVersions;
17use crate::version::system_limits::SystemLimits;
18
19use crate::version::v1::PLATFORM_V1;
20use crate::version::v10::PLATFORM_V10;
21use crate::version::v11::PLATFORM_V11;
22use crate::version::v12::PLATFORM_V12;
23use crate::version::v2::PLATFORM_V2;
24use crate::version::v3::PLATFORM_V3;
25use crate::version::v4::PLATFORM_V4;
26use crate::version::v5::PLATFORM_V5;
27use crate::version::v6::PLATFORM_V6;
28use crate::version::v7::PLATFORM_V7;
29use crate::version::v8::PLATFORM_V8;
30use crate::version::v9::PLATFORM_V9;
31
32use crate::version::ProtocolVersion;
33pub use versioned_feature_core::*;
34
35#[derive(Clone, Debug)]
36pub struct PlatformVersion {
37 pub protocol_version: ProtocolVersion,
38 pub dpp: DPPVersion,
39 pub drive: DriveVersion,
40 pub drive_abci: DriveAbciVersion,
41 pub consensus: ConsensusVersions,
42 pub fee_version: FeeVersion,
43 pub system_data_contracts: SystemDataContractVersions,
44 pub system_limits: SystemLimits,
45}
46
47pub const PLATFORM_VERSIONS: &[PlatformVersion] = &[
48 PLATFORM_V1,
49 PLATFORM_V2,
50 PLATFORM_V3,
51 PLATFORM_V4,
52 PLATFORM_V5,
53 PLATFORM_V6,
54 PLATFORM_V7,
55 PLATFORM_V8,
56 PLATFORM_V9,
57 PLATFORM_V10,
58 PLATFORM_V11,
59 PLATFORM_V12,
60];
61
62#[cfg(feature = "mock-versions")]
63pub static PLATFORM_TEST_VERSIONS: OnceLock<Vec<PlatformVersion>> = OnceLock::new();
65#[cfg(feature = "mock-versions")]
66const DEFAULT_PLATFORM_TEST_VERSIONS: &[PlatformVersion] = &[TEST_PLATFORM_V2, TEST_PLATFORM_V3];
67
68pub const LATEST_PLATFORM_VERSION: &PlatformVersion = &PLATFORM_V12;
69
70pub const DESIRED_PLATFORM_VERSION: &PlatformVersion = LATEST_PLATFORM_VERSION;
71
72impl PlatformVersion {
73 pub fn get<'a>(version: ProtocolVersion) -> Result<&'a Self, PlatformVersionError> {
74 if version > 0 {
75 #[cfg(feature = "mock-versions")]
76 {
77 if version >> TEST_PROTOCOL_VERSION_SHIFT_BYTES > 0 {
78 let test_version = version - (1 << TEST_PROTOCOL_VERSION_SHIFT_BYTES);
79
80 let versions = PLATFORM_TEST_VERSIONS
82 .get_or_init(|| vec![TEST_PLATFORM_V2, TEST_PLATFORM_V3]);
83
84 return versions.get(test_version as usize - 2).ok_or(
85 PlatformVersionError::UnknownVersionError(format!(
86 "no test platform version {test_version}"
87 )),
88 );
89 }
90 }
91 PLATFORM_VERSIONS.get(version as usize - 1).ok_or_else(|| {
92 PlatformVersionError::UnknownVersionError(format!("no platform version {version}"))
93 })
94 } else {
95 Err(PlatformVersionError::UnknownVersionError(format!(
96 "no platform version {version}"
97 )))
98 }
99 }
100
101 pub fn get_optional<'a>(version: ProtocolVersion) -> Option<&'a Self> {
102 if version > 0 {
103 #[cfg(feature = "mock-versions")]
104 {
105 if version >> TEST_PROTOCOL_VERSION_SHIFT_BYTES > 0 {
106 let test_version = version - (1 << TEST_PROTOCOL_VERSION_SHIFT_BYTES);
107
108 let versions = PLATFORM_TEST_VERSIONS
110 .get_or_init(|| vec![TEST_PLATFORM_V2, TEST_PLATFORM_V3]);
111
112 return versions.get(test_version as usize - 2);
113 }
114 }
115 PLATFORM_VERSIONS.get(version as usize - 1)
116 } else {
117 None
118 }
119 }
120
121 pub fn get_version_or_latest<'a>(
122 version: Option<ProtocolVersion>,
123 ) -> Result<&'a Self, PlatformVersionError> {
124 if let Some(version) = version {
125 if version > 0 {
126 #[cfg(feature = "mock-versions")]
127 {
128 if version >> TEST_PROTOCOL_VERSION_SHIFT_BYTES > 0 {
129 let test_version = version - (1 << TEST_PROTOCOL_VERSION_SHIFT_BYTES);
130
131 let versions = PLATFORM_TEST_VERSIONS
133 .get_or_init(|| Vec::from(DEFAULT_PLATFORM_TEST_VERSIONS));
134
135 return versions.get(test_version as usize - 2).ok_or(
136 PlatformVersionError::UnknownVersionError(format!(
137 "no test platform version {test_version}"
138 )),
139 );
140 }
141 }
142 PLATFORM_VERSIONS.get(version as usize - 1).ok_or(
143 PlatformVersionError::UnknownVersionError(format!(
144 "no platform version {version}"
145 )),
146 )
147 } else {
148 Err(PlatformVersionError::UnknownVersionError(format!(
149 "no platform version {version}"
150 )))
151 }
152 } else {
153 Ok(Self::latest())
154 }
155 }
156
157 pub fn first<'a>() -> &'a Self {
158 PLATFORM_VERSIONS
159 .first()
160 .expect("expected to have a platform version")
161 }
162
163 pub fn latest<'a>() -> &'a Self {
164 PLATFORM_VERSIONS
165 .last()
166 .expect("expected to have a platform version")
167 }
168
169 pub fn desired<'a>() -> &'a Self {
170 DESIRED_PLATFORM_VERSION
171 }
172
173 #[cfg(feature = "mock-versions")]
174 pub fn replace_test_versions(versions: Vec<PlatformVersion>) {
176 PLATFORM_TEST_VERSIONS
177 .set(versions)
178 .expect("failed to set test versions")
179 }
180}