sui_sdk_types/
gas.rs

1/// Summary of gas charges.
2///
3/// Storage is charged independently of computation.
4/// There are 3 parts to the storage charges:
5/// `storage_cost`: it is the charge of storage at the time the transaction is executed.
6///                 The cost of storage is the number of bytes of the objects being mutated
7///                 multiplied by a variable storage cost per byte
8/// `storage_rebate`: this is the amount a user gets back when manipulating an object.
9///                   The `storage_rebate` is the `storage_cost` for an object minus fees.
10/// `non_refundable_storage_fee`: not all the value of the object storage cost is
11///                               given back to user and there is a small fraction that
12///                               is kept by the system. This value tracks that charge.
13///
14/// When looking at a gas cost summary the amount charged to the user is
15/// `computation_cost + storage_cost - storage_rebate`
16/// and that is the amount that is deducted from the gas coins.
17/// `non_refundable_storage_fee` is collected from the objects being mutated/deleted
18/// and it is tracked by the system in storage funds.
19///
20/// Objects deleted, including the older versions of objects mutated, have the storage field
21/// on the objects added up to a pool of "potential rebate". This rebate then is reduced
22/// by the "nonrefundable rate" such that:
23/// `potential_rebate(storage cost of deleted/mutated objects) =
24/// storage_rebate + non_refundable_storage_fee`
25///
26/// # BCS
27///
28/// The BCS serialized form for this type is defined by the following ABNF:
29///
30/// ```text
31/// gas-cost-summary = u64 ; computation-cost
32///                    u64 ; storage-cost
33///                    u64 ; storage-rebate
34///                    u64 ; non-refundable-storage-fee
35/// ```
36#[derive(Clone, Debug, Default, PartialEq, Eq)]
37#[cfg_attr(
38    feature = "serde",
39    derive(serde_derive::Serialize, serde_derive::Deserialize)
40)]
41#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
42pub struct GasCostSummary {
43    /// Cost of computation/execution
44    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
45    pub computation_cost: u64,
46
47    /// Storage cost, it's the sum of all storage cost for all objects created or mutated.
48    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
49    pub storage_cost: u64,
50
51    /// The amount of storage cost refunded to the user for all objects deleted or mutated in the
52    /// transaction.
53    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
54    pub storage_rebate: u64,
55
56    /// The fee for the rebate. The portion of the storage rebate kept by the system.
57    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
58    pub non_refundable_storage_fee: u64,
59}
60
61impl GasCostSummary {
62    /// Create a new gas cost summary.
63    ///
64    /// # Arguments
65    /// * `computation_cost` - Cost of computation cost/execution.
66    /// * `storage_cost` - Storage cost, it's the sum of all storage cost for all objects created or mutated.
67    /// * `storage_rebate` - The amount of storage cost refunded to the user for all objects deleted or mutated in the transaction.
68    /// * `non_refundable_storage_fee` - The fee for the rebate. The portion of the storage rebate kept by the system.
69    pub fn new(
70        computation_cost: u64,
71        storage_cost: u64,
72        storage_rebate: u64,
73        non_refundable_storage_fee: u64,
74    ) -> GasCostSummary {
75        GasCostSummary {
76            computation_cost,
77            storage_cost,
78            storage_rebate,
79            non_refundable_storage_fee,
80        }
81    }
82
83    /// The total gas used, which is the sum of computation and storage costs.
84    pub fn gas_used(&self) -> u64 {
85        self.computation_cost + self.storage_cost
86    }
87
88    /// The net gas usage, which is the total gas used minus the storage rebate.
89    /// A positive number means used gas; negative number means refund.
90    pub fn net_gas_usage(&self) -> i64 {
91        self.gas_used() as i64 - self.storage_rebate as i64
92    }
93}
94
95impl std::fmt::Display for GasCostSummary {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        write!(f, "computation_cost: {}, ", self.computation_cost)?;
98        write!(f, "storage_cost: {}, ", self.storage_cost)?;
99        write!(f, "storage_rebate: {}, ", self.storage_rebate)?;
100        write!(
101            f,
102            "non_refundable_storage_fee: {}",
103            self.non_refundable_storage_fee
104        )
105    }
106}
107
108#[cfg(test)]
109mod test {
110    use super::*;
111
112    #[cfg(target_arch = "wasm32")]
113    use wasm_bindgen_test::wasm_bindgen_test as test;
114
115    #[test]
116    #[cfg(feature = "serde")]
117    fn formats() {
118        let actual = GasCostSummary {
119            computation_cost: 42,
120            storage_cost: u64::MAX,
121            storage_rebate: 0,
122            non_refundable_storage_fee: 9,
123        };
124
125        println!("{}", serde_json::to_string(&actual).unwrap());
126        println!("{:?}", bcs::to_bytes(&actual).unwrap());
127    }
128}