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