Skip to main content

platform_version/version/fee/
mod.rs

1use crate::error::PlatformVersionError;
2use crate::version::fee::data_contract_registration::v1::FEE_DATA_CONTRACT_REGISTRATION_VERSION1;
3use crate::version::fee::data_contract_registration::FeeDataContractRegistrationVersion;
4use crate::version::fee::data_contract_validation::FeeDataContractValidationVersion;
5use crate::version::fee::document_ttl::v1::FEE_DOCUMENT_TTL_VERSION1;
6use crate::version::fee::document_ttl::FeeDocumentTtlVersion;
7use crate::version::fee::hashing::v1::FEE_HASHING_VERSION1;
8use crate::version::fee::hashing::{FeeHashingVersion, FeeHashingVersionBeforeVersion11};
9use crate::version::fee::processing::{
10    FeeProcessingVersion, FeeProcessingVersionFieldsBeforeVersion1Point4,
11};
12use crate::version::fee::signature::FeeSignatureVersion;
13use crate::version::fee::state_transition_min_fees::{
14    StateTransitionMinFees, StateTransitionMinFeesBeforeProtocolVersion11,
15};
16use crate::version::fee::storage::FeeStorageVersion;
17use crate::version::fee::v1::FEE_VERSION1;
18use crate::version::fee::vote_resolution_fund_fees::{
19    VoteResolutionFundFees, VoteResolutionFundFeesFieldsBeforeVersion4,
20};
21use bincode::{Decode, Encode};
22
23pub mod data_contract_registration;
24mod data_contract_validation;
25pub mod document_ttl;
26mod hashing;
27mod processing;
28pub mod signature;
29pub mod state_transition_min_fees;
30pub mod storage;
31pub mod v1;
32pub mod v2;
33pub mod v3;
34pub mod vote_resolution_fund_fees;
35
36pub type FeeVersionNumber = u32;
37
38pub const FEE_VERSIONS: &[FeeVersion] = &[FEE_VERSION1];
39
40#[derive(Clone, Debug, Encode, Decode, Default, PartialEq, Eq)]
41pub struct FeeVersion {
42    pub fee_version_number: FeeVersionNumber,
43    // Permille means devise by 1000
44    pub uses_version_fee_multiplier_permille: Option<u64>,
45    pub storage: FeeStorageVersion,
46    pub signature: FeeSignatureVersion,
47    pub hashing: FeeHashingVersion,
48    pub processing: FeeProcessingVersion,
49    pub data_contract_validation: FeeDataContractValidationVersion,
50    pub data_contract_registration: FeeDataContractRegistrationVersion,
51    pub state_transition_min_fees: StateTransitionMinFees,
52    pub vote_resolution_fund_fees: VoteResolutionFundFees,
53    /// Fees of documents whose document type declares a `ttl` (read from protocol
54    /// version 14). Platform states store only `fee_version_number`, so this field does
55    /// not touch any stored format; `FeeVersionFieldsBeforeVersion4` must not gain it.
56    pub document_ttl: FeeDocumentTtlVersion,
57}
58
59impl FeeVersion {
60    pub fn as_static(&self) -> &'static FeeVersion {
61        FeeVersion::get(self.fee_version_number).expect("expected fee version to exist")
62    }
63    pub fn get<'a>(version: FeeVersionNumber) -> Result<&'a Self, PlatformVersionError> {
64        if version > 0 {
65            FEE_VERSIONS.get(version as usize - 1).ok_or_else(|| {
66                PlatformVersionError::UnknownVersionError(format!("no fee version {version}"))
67            })
68        } else {
69            Err(PlatformVersionError::UnknownVersionError(format!(
70                "no fee version {version}"
71            )))
72        }
73    }
74
75    pub fn get_optional<'a>(version: FeeVersionNumber) -> Option<&'a Self> {
76        if version > 0 {
77            FEE_VERSIONS.get(version as usize - 1)
78        } else {
79            None
80        }
81    }
82
83    pub fn first<'a>() -> &'a Self {
84        FEE_VERSIONS
85            .first()
86            .expect("expected to have a fee version")
87    }
88
89    pub fn latest<'a>() -> &'a Self {
90        FEE_VERSIONS.last().expect("expected to have a fee version")
91    }
92}
93
94// This is type only meant for deserialization because of an issue
95// The issue was that the platform state was stored with FeeVersions in it before version 1.4
96// When we would add new fields we would be unable to deserialize
97// This FeeProcessingVersionFieldsBeforeVersion4 is how things were before version 1.4 was released
98/// The storage fee table exactly as every pre-4.2 release serialized it
99/// (5 fields). `FeeStorageVersion` gained
100/// `ttl_ephemeral_disk_usage_credit_per_byte` in 4.2; embedding the live
101/// struct here would shift the frozen pre-1.4 platform-state wire format
102/// and break deserialization of old stored states (bincode
103/// `UnexpectedEnd`). Any future field added to `FeeStorageVersion` must
104/// NOT be added here.
105#[derive(Clone, Debug, Encode, Decode, Default, PartialEq, Eq)]
106pub struct FeeStorageVersionFieldsBeforeVersion4 {
107    pub storage_disk_usage_credit_per_byte: u64,
108    pub storage_processing_credit_per_byte: u64,
109    pub storage_load_credit_per_byte: u64,
110    pub non_storage_load_credit_per_byte: u64,
111    pub storage_seek_cost: u64,
112}
113
114impl From<FeeStorageVersionFieldsBeforeVersion4> for FeeStorageVersion {
115    fn from(value: FeeStorageVersionFieldsBeforeVersion4) -> Self {
116        FeeStorageVersion {
117            storage_disk_usage_credit_per_byte: value.storage_disk_usage_credit_per_byte,
118            storage_processing_credit_per_byte: value.storage_processing_credit_per_byte,
119            storage_load_credit_per_byte: value.storage_load_credit_per_byte,
120            non_storage_load_credit_per_byte: value.non_storage_load_credit_per_byte,
121            storage_seek_cost: value.storage_seek_cost,
122            // Pre-4.2 tables predate the TTL grammar entirely.
123            ttl_ephemeral_disk_usage_credit_per_byte: 0,
124        }
125    }
126}
127
128#[derive(Clone, Debug, Encode, Decode, Default, PartialEq, Eq)]
129pub struct FeeVersionFieldsBeforeVersion4 {
130    // Permille means devise by 1000
131    pub uses_version_fee_multiplier_permille: Option<u64>,
132    pub storage: FeeStorageVersionFieldsBeforeVersion4,
133    pub signature: FeeSignatureVersion,
134    pub hashing: FeeHashingVersionBeforeVersion11,
135    pub processing: FeeProcessingVersionFieldsBeforeVersion1Point4,
136    pub data_contract: FeeDataContractValidationVersion,
137    pub state_transition_min_fees: StateTransitionMinFeesBeforeProtocolVersion11,
138    pub vote_resolution_fund_fees: VoteResolutionFundFeesFieldsBeforeVersion4,
139}
140
141impl From<FeeVersionFieldsBeforeVersion4> for FeeVersion {
142    fn from(value: FeeVersionFieldsBeforeVersion4) -> Self {
143        FeeVersion {
144            fee_version_number: 1,
145            uses_version_fee_multiplier_permille: value.uses_version_fee_multiplier_permille,
146            storage: value.storage.into(),
147            signature: value.signature,
148            hashing: FEE_HASHING_VERSION1,
149            processing: FeeProcessingVersion::from(value.processing),
150            data_contract_validation: value.data_contract,
151            data_contract_registration: FEE_DATA_CONTRACT_REGISTRATION_VERSION1,
152            state_transition_min_fees: StateTransitionMinFees::from(
153                value.state_transition_min_fees,
154            ),
155            vote_resolution_fund_fees: value.vote_resolution_fund_fees.into(),
156            // Pre-4.2 tables predate the document `ttl` keyword; the group is unread there.
157            document_ttl: FEE_DOCUMENT_TTL_VERSION1,
158        }
159    }
160}