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