1use darkfi_sdk::crypto::constants::{MERKLE_DEPTH_ORCHARD, SPARSE_MERKLE_DEPTH};
20use darkfi_serial::{async_trait, SerialDecodable, SerialEncodable};
21
22use crate::zkas::{Opcode, VarType, ZkBinary};
23
24pub const PALLAS_SCHNORR_SIGNATURE_FEE: u64 = 1000;
27
28pub fn circuit_gas_use(zkbin: &ZkBinary) -> u64 {
31 let mut accumulator: u64 = 0;
32
33 accumulator = accumulator.saturating_add(10u64.saturating_mul(zkbin.constants.len() as u64));
35
36 accumulator = accumulator.saturating_add(10u64.saturating_mul(zkbin.literals.len() as u64));
39
40 for witness in &zkbin.witnesses {
42 let cost = match witness {
43 VarType::Dummy => unreachable!(),
44 VarType::EcPoint => 20,
45 VarType::EcFixedPoint => unreachable!(),
46 VarType::EcFixedPointShort => unreachable!(),
47 VarType::EcFixedPointBase => unreachable!(),
48 VarType::EcNiPoint => 20,
49 VarType::Base => 10,
50 VarType::BaseArray => unreachable!(),
51 VarType::Scalar => 20,
52 VarType::ScalarArray => unreachable!(),
53 VarType::MerklePath => 10 * MERKLE_DEPTH_ORCHARD as u64,
54 VarType::SparseMerklePath => 10 * SPARSE_MERKLE_DEPTH as u64,
55 VarType::Uint32 => 10,
56 VarType::Uint64 => 10,
57 VarType::Any => 10,
58 };
59
60 accumulator = accumulator.saturating_add(cost);
61 }
62
63 for opcode in &zkbin.opcodes {
65 let cost = match opcode.0 {
66 Opcode::Noop => unreachable!(),
67 Opcode::EcAdd => 30,
68 Opcode::EcMul => 30,
69 Opcode::EcMulBase => 30,
70 Opcode::EcMulShort => 30,
71 Opcode::EcMulVarBase => 30,
72 Opcode::EcGetX => 5,
73 Opcode::EcGetY => 5,
74 Opcode::PoseidonHash => {
75 20u64.saturating_add(10u64.saturating_mul(opcode.1.len() as u64))
76 }
77 Opcode::MerkleRoot => 10 * MERKLE_DEPTH_ORCHARD as u64,
78 Opcode::SparseMerkleRoot => 10 * SPARSE_MERKLE_DEPTH as u64,
79 Opcode::BaseAdd => 15,
80 Opcode::BaseMul => 15,
81 Opcode::BaseSub => 15,
82 Opcode::WitnessBase => 10,
83 Opcode::RangeCheck => 60,
84 Opcode::LessThanStrict => 100,
85 Opcode::LessThanLoose => 100,
86 Opcode::BoolCheck => 20,
87 Opcode::CondSelect => 10,
88 Opcode::ZeroCondSelect => 10,
89 Opcode::ConstrainEqualBase => 10,
90 Opcode::ConstrainEqualPoint => 20,
91 Opcode::ConstrainInstance => 10,
92 Opcode::DebugPrint => 100,
93 };
94
95 accumulator = accumulator.saturating_add(cost);
96 }
97
98 accumulator
99}
100
101#[derive(Default, Clone, Eq, PartialEq, SerialEncodable, SerialDecodable)]
107pub struct GasData {
108 pub wasm: u64,
110 pub zk_circuits: u64,
112 pub signatures: u64,
114 pub deployments: u64,
116 pub paid: u64,
118}
119
120impl GasData {
121 pub fn total_gas_used(&self) -> u64 {
124 self.wasm
125 .saturating_add(self.zk_circuits)
126 .saturating_add(self.signatures)
127 .saturating_add(self.deployments)
128 }
129}
130
131impl std::fmt::Debug for GasData {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 f.debug_struct("GasData")
136 .field("total", &self.total_gas_used())
137 .field("wasm", &self.wasm)
138 .field("zk_circuits", &self.zk_circuits)
139 .field("signatures", &self.signatures)
140 .field("deployments", &self.deployments)
141 .field("paid", &self.paid)
142 .finish()
143 }
144}
145
146pub fn compute_fee(gas: &u64) -> u64 {
151 gas / 100
152}