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