fees.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use darkfi_serial::{async_trait, SerialDecodable, SerialEncodable};
  19. use crate::zkas::ZkBinary;
  20. /// Fixed fee for verifying a Schnorr signature over the Pallas curve.
  21. pub const PALLAS_SCHNORR_VERIFY_GAS: u64 = 1850;
  22. /// Base gas subtracted at the start of every host function call.
  23. pub const MIN_GAS: u64 = 1;
  24. /// Per-byte multiplier for on-chain storage reads.
  25. pub const READ_GAS_PER_BYTE: u64 = 7;
  26. /// Per-byte multiplier for on-chain storage writes.
  27. pub const WRITE_GAS_PER_BYTE: u64 = 70;
  28. /// One-time fee for inserting a new key into on-chain storage.
  29. pub const STATE_GROWTH_GAS: u64 = 20_000;
  30. /// Fee for initializing a new DB tree.
  31. pub const TREE_GAS: u64 = 300;
  32. /// Gas per `Poseidon` hash in the sparse Merkle tree.
  33. pub const POSEIDON_HASH_GAS: u64 = 150;
  34. /// Gas per `Sinsemilla` hash in Merkle trees.
  35. pub const SINSEMILLA_HASH_GAS: u64 = 800;
  36. /// Per-row gas for compiling ZK circuits.
  37. pub const COMPILE_GAS_PER_ROW: u64 = 7800;
  38. /// Per-row gas for verifying ZK circuits.
  39. pub const VERIFY_GAS_PER_ROW: u64 = 80;
  40. /// The fee-estimation constants in `darkfi_sdk::fee` mirror the validator
  41. /// gas rules above so wallets can predict the exact minimum fee. These
  42. /// assertions fail the build if the two ever drift apart. The circuit gas
  43. /// uses k = 11, the size of fee_v1.zk; update it if the circuit is ever
  44. /// regenerated with a different size.
  45. const _: () = assert!(PALLAS_SCHNORR_VERIFY_GAS == darkfi_sdk::fee::FEE_CALL_SIG_GAS);
  46. const _: () = assert!(VERIFY_GAS_PER_ROW * (1 << 11) == darkfi_sdk::fee::FEE_CALL_CIRCUIT_GAS);
  47. /// Calculate the gas use for verifying a given zkas circuit.
  48. /// This function assumes that the zkbin was properly decoded.
  49. pub fn circuit_gas_use(zkbin: &ZkBinary) -> u64 {
  50. let rows = 1u64.checked_shl(zkbin.k).unwrap_or(u64::MAX);
  51. VERIFY_GAS_PER_ROW.saturating_mul(rows)
  52. }
  53. /// Auxiliary struct representing the full gas usage breakdown of a
  54. /// transaction.
  55. ///
  56. /// This data is used for accounting of fees, providing details
  57. /// relating to resource consumption across different transactions.
  58. #[derive(Default, Clone, Eq, PartialEq, SerialEncodable, SerialDecodable)]
  59. pub struct GasData {
  60. /// Wasm calls gas consumption. The fee call's entry is the fixed
  61. /// `FEE_CALL_GAS` charge, not its measured opcode count.
  62. pub wasm: u64,
  63. /// ZK circuits gas consumption
  64. pub zk_circuits: u64,
  65. /// Signature fee
  66. pub signatures: u64,
  67. /// Contract deployment gas
  68. pub deployments: u64,
  69. /// Transaction paid fee
  70. pub paid: u64,
  71. /// Transaction declared burned fee
  72. pub burned: u64,
  73. }
  74. impl GasData {
  75. /// Calculates the total gas used by summing all individual gas
  76. /// usage fields.
  77. pub fn total_gas_used(&self) -> u64 {
  78. self.wasm
  79. .saturating_add(self.zk_circuits)
  80. .saturating_add(self.signatures)
  81. .saturating_add(self.deployments)
  82. }
  83. }
  84. /// Implements custom debug trait to include
  85. /// [`GasData::total_gas_used`].
  86. impl std::fmt::Debug for GasData {
  87. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  88. f.debug_struct("GasData")
  89. .field("total", &self.total_gas_used())
  90. .field("wasm", &self.wasm)
  91. .field("zk_circuits", &self.zk_circuits)
  92. .field("signatures", &self.signatures)
  93. .field("deployments", &self.deployments)
  94. .field("paid", &self.paid)
  95. .field("burned", &self.burned)
  96. .finish()
  97. }
  98. }