penumbra_sdk_transaction/gas.rs
1use penumbra_sdk_auction::auction::dutch::actions::{
2 ActionDutchAuctionEnd, ActionDutchAuctionSchedule, ActionDutchAuctionWithdraw,
3};
4use penumbra_sdk_community_pool::{CommunityPoolDeposit, CommunityPoolOutput, CommunityPoolSpend};
5use penumbra_sdk_dex::{PositionClose, PositionOpen, PositionWithdraw, Swap, SwapClaim};
6use penumbra_sdk_fee::Gas;
7use penumbra_sdk_ibc::IbcRelay;
8use penumbra_sdk_shielded_pool::{Ics20Withdrawal, Output, Spend};
9use penumbra_sdk_stake::{
10 validator::Definition as ValidatorDefinition, Delegate, Undelegate, UndelegateClaim,
11};
12
13use penumbra_sdk_governance::{
14 DelegatorVote, ProposalDepositClaim, ProposalSubmit, ProposalWithdraw, ValidatorVote,
15};
16
17use crate::{
18 plan::{ActionPlan, TransactionPlan},
19 Action, Transaction,
20};
21
22use penumbra_sdk_proto::DomainType;
23
24const NULLIFIER_SIZE: u64 = 2 + 32;
25const NOTEPAYLOAD_SIZE: u64 = 32 + 32 + 176;
26const SWAPPAYLOAD_SIZE: u64 = 32 + 272;
27const ZKPROOF_SIZE: u64 = 192;
28// This is an approximation, the actual size is variable
29const BSOD_SIZE: u64 = 16 + 16 + 0 + 4 + 64 + 4;
30
31/// Allows [`Action`]s and [`Transaction`]s to statically indicate their relative resource consumption.
32/// Since the gas cost needs to be multiplied by a price, the values returned
33/// only need to be scaled relatively to each other.
34pub trait GasCost {
35 fn gas_cost(&self) -> Gas;
36}
37
38// Where block space costs are hard-coded instead of calculated in the following functions, the values are based on the approximate byte size of the
39// encoded action and ignore the protobuf framing overhead, because it makes only a small difference and simplifies accounting.
40
41pub fn spend_gas_cost() -> Gas {
42 Gas {
43 // penumbra.core.asset.v1.BalanceCommitment `balance_commitment` = 32 bytes
44 // penumbra.core.component.sct.v1.Nullifier `nullifier` = 32 bytes
45 // penumbra.crypto.decaf377_rdsa.v1.SpendVerificationKey `rk` = 32 bytes
46 // penumbra.crypto.decaf377_rdsa.v1.SpendAuthSignature `auth_sig` = 64 bytes
47 // ZKSpendProof `proof` = 192 bytes
48
49 // The block space measured as the byte length of the encoded action.
50 block_space: 160 + ZKPROOF_SIZE, // 352 bytes
51 // The compact block space cost is based on the byte size of the data the [`Action`] adds
52 // to the compact block. For a `Spend`, this is the byte size of a `Nullifier`.
53 compact_block_space: NULLIFIER_SIZE,
54 // Includes a zk-SNARK proof, so we include a constant verification cost.
55 verification: 1000,
56 // Execution cost is currently hardcoded at 10 for all [`Action`] variants.
57 execution: 10,
58 }
59}
60
61pub fn output_gas_cost() -> Gas {
62 Gas {
63 // NotePayload `note_payload` = 32 + 32 + 176 = 240 bytes
64 // penumbra.core.asset.v1.BalanceCommitment `balance_commitment` = 32 bytes
65 // wrapped_memo_key `wrapped_memo_key` = 48 bytes
66 // ovk_wrapped_key `ovk_wrapped_key` = 48 bytes
67 // ZKOutputProof `proof` = 192 bytes
68
69 // The block space measured as the byte length of the encoded action.
70 block_space: 128 + NOTEPAYLOAD_SIZE + ZKPROOF_SIZE, // 560 bytes
71 // The compact block space cost is based on the byte size of the data the [`Action`] adds
72 // to the compact block.
73 compact_block_space: NOTEPAYLOAD_SIZE,
74 // Includes a zk-SNARK proof, so we include a constant verification cost.
75 verification: 1000,
76 // Execution cost is currently hardcoded at 10 for all [`Action`] variants.
77 execution: 10,
78 }
79}
80
81fn delegate_gas_cost(delegate: &Delegate) -> Gas {
82 Gas {
83 // The block space measured as the byte length of the encoded action.
84 block_space: delegate.encode_to_vec().len() as u64,
85 // The compact block space cost is based on the byte size of the data the [`Action`] adds
86 // to the compact block.
87 // For a Delegate, nothing is added to the compact block directly. The associated [`Action::Spend`]
88 // actions will add their costs, but there's nothing to add here.
89 compact_block_space: 0,
90 // Does not include a zk-SNARK proof, so there's no verification cost.
91 verification: 0,
92 // Execution cost is currently hardcoded at 10 for all Action variants.
93 execution: 10,
94 }
95}
96
97fn undelegate_gas_cost(undelegate: &Undelegate) -> Gas {
98 Gas {
99 // The block space measured as the byte length of the encoded action.
100 block_space: undelegate.encode_to_vec().len() as u64,
101 // The compact block space cost is based on the byte size of the data the [`Action`] adds
102 // to the compact block.
103 // For an Undelegate, nothing is added to the compact block directly. The associated [`Action::Spend`]
104 // actions will add their costs, but there's nothing to add here.
105 compact_block_space: 0,
106 // Does not include a zk-SNARK proof, so there's no verification cost.
107 verification: 0,
108 // Execution cost is currently hardcoded at 10 for all Action variants.
109 execution: 10,
110 }
111}
112
113fn undelegate_claim_gas_cost() -> Gas {
114 Gas {
115 // penumbra.core.keys.v1.IdentityKey `validator_identity` = 32 bytes
116 // uint64 `start_epoch_index` = 8 bytes
117 // Penalty `penalty` = 32 bytes
118 // penumbra.core.asset.v1.BalanceCommitment `balance_commitment` = 32 bytes
119 // uint64 `unbonding_start_height` = 8 bytes
120 // ZKSpendProof `proof` = 192 bytes
121
122 // The block space measured as the byte length of the encoded action.
123 block_space: 112 + ZKPROOF_SIZE, // 304 bytes
124 // The compact block space cost is based on the byte size of the data the [`Action`] adds
125 // to the compact block.
126 // For an `UndelegateClaim`, nothing is added to the compact block directly. The associated [`Action::Output`]
127 // actions will add their costs, but there's nothing to add here.
128 compact_block_space: 0,
129 // Includes a zk-SNARK proof, so we include a constant verification cost.
130 verification: 1000,
131 // Execution cost is currently hardcoded at 10 for all Action variants.
132 execution: 10,
133 }
134}
135
136fn validator_definition_gas_cost(validator_definition: &ValidatorDefinition) -> Gas {
137 Gas {
138 // The block space measured as the byte length of the encoded action.
139 block_space: validator_definition.encode_to_vec().len() as u64,
140 // The compact block space cost is based on the byte size of the data the [`Action`] adds
141 // to the compact block.
142 // For a ValidatorDefinition the compact block is not modified.
143 compact_block_space: 0,
144 // Includes a signature verification, so we include a small constant verification cost.
145 verification: 200,
146 // Execution cost is currently hardcoded at 10 for all Action variants.
147 execution: 10,
148 }
149}
150
151fn swap_gas_cost() -> Gas {
152 Gas {
153 // TradingPair `trading_pair` = 64 bytes
154 // penumbra.core.num.v1.Amount `delta_1_i` = 16 bytes
155 // penumbra.core.num.v1.Amount `delta_2_i` = 16 bytes
156 // penumbra.core.asset.v1.BalanceCommitment `fee_commitment` = 32 bytes
157 // SwapPayload `payload` = 304 bytes
158 // ZKSwapProof `proof` = 192 bytes
159 // Batch swap output data = 104 bytes
160
161 // The block space measured as the byte length of the encoded action.
162 block_space: 128 + ZKPROOF_SIZE + SWAPPAYLOAD_SIZE + BSOD_SIZE, // 728 bytes
163 // The compact block space cost is based on the byte size of the data the [`Action`] adds
164 // to the compact block.
165 // For a `Swap` this is the byte size of a [`StatePayload`] and a [`BatchSwapOutputData`].
166 // `Swap`s are batched so technically the cost of the `BatchSwapOutputData` is shared across
167 // multiple swaps, but if only one `swap` for a trading pair is performed in a block, that
168 // `swap` will add a `BatchSwapOutputData` all on its own.
169 // Note: the BSOD has variable size, we pick an approximation.
170 compact_block_space: SWAPPAYLOAD_SIZE + BSOD_SIZE,
171 // Includes a zk-SNARK proof, so we include a constant verification cost.
172 verification: 1000,
173 // Execution cost is currently hardcoded at 10 for all Action variants.
174 execution: 10,
175 }
176}
177
178pub fn swap_claim_gas_cost() -> Gas {
179 Gas {
180 // penumbra.core.component.sct.v1.Nullifier `nullifier` = 32 bytes
181 // penumbra.core.component.fee.v1.Fee `fee`` = 48 bytes
182 // penumbra.crypto.tct.v1.StateCommitment `output_1_commitment`` = 32 bytes
183 // penumbra.crypto.tct.v1.StateCommitment `output_2_commitment` = 32 bytes
184 // BatchSwapOutputData `output_data` = 176 bytes
185 // uint64 `epoch_duration` = 8 bytes
186 // ZKSwapClaimProof `proof` = 192 bytes
187 // Batch swap output data = 104 bytes
188
189 // The block space measured as the byte length of the encoded action.
190 block_space: 328 + ZKPROOF_SIZE + BSOD_SIZE, // 624 bytes
191 // The compact block space cost is based on the byte size of the data the [`Action`] adds
192 // to the compact block.
193 // For a `SwapClaim`, nothing is added to the compact block directly. The associated [`Action::Spend`]
194 // and [`Action::Output`] actions will add their costs, but there's nothing to add here.
195 compact_block_space: 0,
196 // Includes a zk-SNARK proof, so we include a constant verification cost.
197 verification: 1000,
198 // Execution cost is currently hardcoded at 10 for all Action variants.
199 execution: 10,
200 }
201}
202
203fn delegator_vote_gas_cost() -> Gas {
204 Gas {
205 // uint64 `proposal` = 8 bytes
206 // uint64 `start_position` = 8 bytes
207 // Vote `vote` = 1 byte
208 // penumbra.core.asset.v1.Value `value` = 48 bytes
209 // penumbra.core.num.v1.Amount `unbonded_amount` = 16 bytes
210 // penumbra.core.component.sct.v1.Nullifier `nullifier` = 32 bytes
211 // penumbra.crypto.decaf377_rdsa.v1.SpendVerificationKey `rk` = 32 bytes
212 // penumbra.crypto.decaf377_rdsa.v1.SpendAuthSignature `auth_sig` = 64 bytes
213 // ZKDelegatorVoteProof `proof` = 192 bytes
214
215 // The block space measured as the byte length of the encoded action.
216 block_space: 209 + ZKPROOF_SIZE, // 401 bytes
217 // The compact block space cost is based on the byte size of the data the [`Action`] adds
218 // to the compact block.
219 // For a DelegatorVote the compact block is not modified.
220 compact_block_space: 0,
221 // Includes a zk-SNARK proof, so we include a constant verification cost.
222 verification: 1000,
223 // Execution cost is currently hardcoded at 10 for all Action variants.
224 execution: 10,
225 }
226}
227
228fn position_withdraw_gas_cost() -> Gas {
229 Gas {
230 // PositionId `position_id` = 32 bytes
231 // penumbra.core.asset.v1.BalanceCommitment `reserves_commitment` = 32 bytes
232 // uint64 `sequence` = 8 bytes
233
234 // The block space measured as the byte length of the encoded action.
235 block_space: 72, // 72 bytes
236 // The compact block space cost is based on the byte size of the data the [`Action`] adds
237 // to the compact block.
238 // For a PositionWithdraw the compact block is not modified.
239 compact_block_space: 0,
240 // Does not include a zk-SNARK proof, so there's no verification cost.
241 verification: 0,
242 // Execution cost is currently hardcoded at 10 for all `Action`` variants.
243 // Reminder: Any change to this execution gas vector must also be reflected
244 // in updates to the dutch auction gas vectors.
245 execution: 10,
246 }
247}
248
249fn dutch_auction_schedule_gas_cost(dutch_action_schedule: &ActionDutchAuctionSchedule) -> Gas {
250 Gas {
251 // penumbra.core.asset.v1.Value `input` = 48 bytes
252 // penumbra.core.asset.v1.AssetId `output_id` = 32 bytes
253 // penumbra.core.num.v1.Amount `max_output` = 16 bytes
254 // penumbra.core.num.v1.Amount `min_output` = 16 bytes
255 // uint64 `start_height` = 8 bytes
256 // uint64 `end_height` = 8 bytes
257 // uint64 `step_count` = 8 bytes
258 // bytes `nonce` = 32 bytes
259 block_space: 168,
260 compact_block_space: 0,
261 verification: 50,
262 // Currently, we make the execution cost for DA actions proportional to the number of steps
263 // and costs of position open/close in dutch action. The gas cost is calculated by:
264 // 2 * step_count * (`PositionOpen`` + `PositionClose` cost).
265 execution: 2 * dutch_action_schedule.description.step_count * (10 + 10),
266 }
267}
268
269fn dutch_auction_end_gas_cost() -> Gas {
270 Gas {
271 // AuctionId `auction_id` = 32 bytes
272 block_space: 32, // 32 bytes
273 compact_block_space: 0,
274 verification: 0,
275 execution: 10,
276 }
277}
278
279fn dutch_auction_withdraw_gas_cost() -> Gas {
280 Gas {
281 // AuctionId `auction_id` = 32 bytes
282 // uint64 `seq`= 8 bytes
283 // penumbra.core.asset.v1.BalanceCommitment `reserves_commitment` = 32 bytes
284 block_space: 72, // 72 bytes
285 compact_block_space: 0,
286 verification: 0,
287 execution: 10,
288 }
289}
290
291impl GasCost for Transaction {
292 fn gas_cost(&self) -> Gas {
293 self.actions().map(GasCost::gas_cost).sum()
294 }
295}
296
297impl GasCost for TransactionPlan {
298 fn gas_cost(&self) -> Gas {
299 self.actions.iter().map(GasCost::gas_cost).sum()
300 }
301}
302
303// The planner also needs to be able to calculate gas costs,
304// however until the transaction is finalized, the planner only
305// has access to `ActionPlan` variants.
306//
307// IMPORTANT: The results produced by this impl should always
308// match what the impl for the associated `Action` variant would
309// produce, otherwise the planner will not include proper gas in
310// transactions.
311impl GasCost for ActionPlan {
312 fn gas_cost(&self) -> Gas {
313 match self {
314 // Some variants use separate `*Plan` inners and need their
315 // own implementations; others encapsulate an `Action` variant
316 // and can call the `GasCost` impl on that.
317 ActionPlan::Spend(_) => spend_gas_cost(),
318 ActionPlan::Output(_) => output_gas_cost(),
319 ActionPlan::UndelegateClaim(_) => undelegate_claim_gas_cost(),
320 ActionPlan::Swap(_) => swap_gas_cost(),
321 ActionPlan::SwapClaim(_) => swap_claim_gas_cost(),
322 ActionPlan::DelegatorVote(_) => delegator_vote_gas_cost(),
323 ActionPlan::PositionWithdraw(_) => position_withdraw_gas_cost(),
324 ActionPlan::ActionDutchAuctionSchedule(das) => das.gas_cost(),
325 ActionPlan::ActionDutchAuctionEnd(_) => dutch_auction_end_gas_cost(),
326 ActionPlan::ActionDutchAuctionWithdraw(_) => dutch_auction_withdraw_gas_cost(),
327
328 ActionPlan::Delegate(d) => d.gas_cost(),
329 ActionPlan::Undelegate(u) => u.gas_cost(),
330 ActionPlan::ValidatorDefinition(vd) => vd.gas_cost(),
331 ActionPlan::IbcAction(i) => i.gas_cost(),
332 ActionPlan::ProposalSubmit(ps) => ps.gas_cost(),
333 ActionPlan::ProposalWithdraw(pw) => pw.gas_cost(),
334 ActionPlan::ValidatorVote(v) => v.gas_cost(),
335 ActionPlan::ProposalDepositClaim(pdc) => pdc.gas_cost(),
336 ActionPlan::PositionOpen(po) => po.gas_cost(),
337 ActionPlan::PositionClose(pc) => pc.gas_cost(),
338 ActionPlan::CommunityPoolSpend(ds) => ds.gas_cost(),
339 ActionPlan::CommunityPoolOutput(d) => d.gas_cost(),
340 ActionPlan::CommunityPoolDeposit(dd) => dd.gas_cost(),
341 ActionPlan::Ics20Withdrawal(w) => w.gas_cost(),
342 }
343 }
344}
345
346impl GasCost for Action {
347 fn gas_cost(&self) -> Gas {
348 match self {
349 Action::Output(output) => output.gas_cost(),
350 Action::Spend(spend) => spend.gas_cost(),
351 Action::Delegate(delegate) => delegate.gas_cost(),
352 Action::Undelegate(undelegate) => undelegate.gas_cost(),
353 Action::UndelegateClaim(undelegate_claim) => undelegate_claim.gas_cost(),
354 Action::Swap(swap) => swap.gas_cost(),
355 Action::SwapClaim(swap_claim) => swap_claim.gas_cost(),
356 Action::ProposalSubmit(submit) => submit.gas_cost(),
357 Action::ProposalWithdraw(withdraw) => withdraw.gas_cost(),
358 Action::DelegatorVote(delegator_vote) => delegator_vote.gas_cost(),
359 Action::ValidatorVote(validator_vote) => validator_vote.gas_cost(),
360 Action::ProposalDepositClaim(p) => p.gas_cost(),
361 Action::PositionOpen(p) => p.gas_cost(),
362 Action::PositionClose(p) => p.gas_cost(),
363 Action::PositionWithdraw(p) => p.gas_cost(),
364 Action::Ics20Withdrawal(withdrawal) => withdrawal.gas_cost(),
365 Action::CommunityPoolDeposit(deposit) => deposit.gas_cost(),
366 Action::CommunityPoolSpend(spend) => spend.gas_cost(),
367 Action::CommunityPoolOutput(output) => output.gas_cost(),
368 Action::IbcRelay(x) => x.gas_cost(),
369 Action::ValidatorDefinition(x) => x.gas_cost(),
370 Action::ActionDutchAuctionSchedule(action_dutch_auction_schedule) => {
371 action_dutch_auction_schedule.gas_cost()
372 }
373 Action::ActionDutchAuctionEnd(action_dutch_auction_end) => {
374 action_dutch_auction_end.gas_cost()
375 }
376 Action::ActionDutchAuctionWithdraw(action_dutch_auction_withdraw) => {
377 action_dutch_auction_withdraw.gas_cost()
378 }
379 }
380 }
381}
382
383impl GasCost for Output {
384 fn gas_cost(&self) -> Gas {
385 output_gas_cost()
386 }
387}
388
389impl GasCost for Spend {
390 fn gas_cost(&self) -> Gas {
391 spend_gas_cost()
392 }
393}
394
395impl GasCost for Delegate {
396 fn gas_cost(&self) -> Gas {
397 delegate_gas_cost(&self)
398 }
399}
400
401impl GasCost for Undelegate {
402 fn gas_cost(&self) -> Gas {
403 undelegate_gas_cost(&self)
404 }
405}
406
407impl GasCost for UndelegateClaim {
408 fn gas_cost(&self) -> Gas {
409 undelegate_claim_gas_cost()
410 }
411}
412
413impl GasCost for Swap {
414 fn gas_cost(&self) -> Gas {
415 swap_gas_cost()
416 }
417}
418
419impl GasCost for SwapClaim {
420 fn gas_cost(&self) -> Gas {
421 swap_claim_gas_cost()
422 }
423}
424
425impl GasCost for ProposalSubmit {
426 fn gas_cost(&self) -> Gas {
427 Gas {
428 // The block space measured as the byte length of the encoded action.
429 block_space: self.encode_to_vec().len() as u64,
430 // In the case of a proposal submission, the compact block cost is zero.
431 // The compact block is only modified it the proposal is ratified.
432 // And when that's the case, the cost is mutualized.
433 compact_block_space: 0,
434 // There are some checks performed to validate the proposed state changes, so we include a constant verification cost,
435 // smaller than a zk-SNARK verification cost.
436 verification: 100,
437 // Execution cost is currently hardcoded at 10 for all Action variants.
438 execution: 10,
439 }
440 }
441}
442
443impl GasCost for ProposalWithdraw {
444 fn gas_cost(&self) -> Gas {
445 Gas {
446 // The block space measured as the byte length of the encoded action.
447 block_space: self.encode_to_vec().len() as u64,
448 // The compact block space cost is based on the byte size of the data the [`Action`] adds
449 // to the compact block.
450 // For a ProposalWithdraw the compact block is not modified.
451 compact_block_space: 0,
452 // Does not include a zk-SNARK proof, so there's no verification cost.
453 verification: 0,
454 // Execution cost is currently hardcoded at 10 for all Action variants.
455 execution: 10,
456 }
457 }
458}
459
460impl GasCost for DelegatorVote {
461 fn gas_cost(&self) -> Gas {
462 delegator_vote_gas_cost()
463 }
464}
465
466impl GasCost for ValidatorVote {
467 fn gas_cost(&self) -> Gas {
468 Gas {
469 // The block space measured as the byte length of the encoded action.
470 block_space: self.encode_to_vec().len() as u64,
471 // The compact block space cost is based on the byte size of the data the [`Action`] adds
472 // to the compact block.
473 // For a ValidatorVote the compact block is not modified.
474 compact_block_space: 0,
475 // Includes a signature verification, so we include a small constant verification cost.
476 verification: 200,
477 // Execution cost is currently hardcoded at 10 for all Action variants.
478 execution: 10,
479 }
480 }
481}
482
483impl GasCost for ProposalDepositClaim {
484 fn gas_cost(&self) -> Gas {
485 Gas {
486 // The block space measured as the byte length of the encoded action.
487 block_space: self.encode_to_vec().len() as u64,
488 // The compact block space cost is based on the byte size of the data the [`Action`] adds
489 // to the compact block.
490 // For a ProposalDepositClaim the compact block is not modified.
491 compact_block_space: 0,
492 // Does not include a zk-SNARK proof, so there's no verification cost.
493 verification: 0,
494 // Execution cost is currently hardcoded at 10 for all Action variants.
495 execution: 10,
496 }
497 }
498}
499
500impl GasCost for PositionOpen {
501 fn gas_cost(&self) -> Gas {
502 Gas {
503 // The block space measured as the byte length of the encoded action.
504 block_space: self.encode_to_vec().len() as u64,
505 // The compact block space cost is based on the byte size of the data the [`Action`] adds
506 // to the compact block.
507 // For a PositionOpen the compact block is not modified.
508 compact_block_space: 0,
509 // There are some small validations performed so a token amount of gas is charged.
510 verification: 50,
511 // Execution cost is currently hardcoded at 10 for all Action variants.
512 // Reminder: Any change to this execution gas vector must also be reflected
513 // in updates to the dutch auction gas vectors.
514 execution: 10,
515 }
516 }
517}
518
519impl GasCost for PositionClose {
520 fn gas_cost(&self) -> Gas {
521 Gas {
522 // The block space measured as the byte length of the encoded action.
523 block_space: self.encode_to_vec().len() as u64,
524 // The compact block space cost is based on the byte size of the data the [`Action`] adds
525 // to the compact block.
526 // For a PositionClose the compact block is not modified.
527 compact_block_space: 0,
528 // Does not include a zk-SNARK proof, so there's no verification cost.
529 verification: 0,
530 // Execution cost is currently hardcoded at 10 for all Action variants.
531 // Reminder: Any change to this execution gas vector must also be reflected
532 // in updates to the dutch auction gas vectors.
533 execution: 10,
534 }
535 }
536}
537
538impl GasCost for PositionWithdraw {
539 fn gas_cost(&self) -> Gas {
540 position_withdraw_gas_cost()
541 }
542}
543
544impl GasCost for Ics20Withdrawal {
545 fn gas_cost(&self) -> Gas {
546 Gas {
547 // The block space measured as the byte length of the encoded action.
548 block_space: self.encode_to_vec().len() as u64,
549 // The compact block space cost is based on the byte size of the data the [`Action`] adds
550 // to the compact block.
551 // For a Ics20Withdrawal the compact block is not modified.
552 compact_block_space: 0,
553 // Does not include a zk-SNARK proof, so there's no verification cost.
554 verification: 0,
555 // Execution cost is currently hardcoded at 10 for all Action variants.
556 execution: 10,
557 }
558 }
559}
560
561impl GasCost for CommunityPoolDeposit {
562 fn gas_cost(&self) -> Gas {
563 Gas {
564 // The block space measured as the byte length of the encoded action.
565 block_space: self.encode_to_vec().len() as u64,
566 // The compact block space cost is based on the byte size of the data the [`Action`] adds
567 // to the compact block.
568 // For a CommunityPoolDeposit the compact block is not modified.
569 compact_block_space: 0,
570 // Does not include a zk-SNARK proof, so there's no verification cost.
571 verification: 0,
572 // Execution cost is currently hardcoded at 10 for all Action variants.
573 execution: 10,
574 }
575 }
576}
577
578impl GasCost for CommunityPoolSpend {
579 fn gas_cost(&self) -> Gas {
580 Gas {
581 // The block space measured as the byte length of the encoded action.
582 block_space: self.encode_to_vec().len() as u64,
583 // The compact block space cost is based on the byte size of the data the [`Action`] adds
584 // to the compact block.
585 // For a CommunityPoolSpend the compact block is not modified.
586 compact_block_space: 0,
587 // Does not include a zk-SNARK proof, so there's no verification cost.
588 verification: 0,
589 // Execution cost is currently hardcoded at 10 for all Action variants.
590 execution: 10,
591 }
592 }
593}
594
595impl GasCost for CommunityPoolOutput {
596 fn gas_cost(&self) -> Gas {
597 // We hardcode the gas costs of a `CommunityPoolOutput` to 0, since it's a protocol action.
598 Gas {
599 block_space: 0,
600 compact_block_space: 0,
601 verification: 0,
602 execution: 0,
603 }
604 }
605}
606
607impl GasCost for IbcRelay {
608 fn gas_cost(&self) -> Gas {
609 Gas {
610 // The block space measured as the byte length of the encoded action.
611 block_space: self.encode_to_vec().len() as u64,
612 // The compact block space cost is based on the byte size of the data the [`Action`] adds
613 // to the compact block.
614 // For a IbcAction this is the byte size of a [`StatePayload`].
615 compact_block_space: match self {
616 // RecvPacket will mint a note if successful.
617 IbcRelay::RecvPacket(_) => NOTEPAYLOAD_SIZE,
618 _ => 0,
619 },
620 // Includes a proof in the execution for RecvPacket (TODO: check the other variants).
621 verification: match self {
622 IbcRelay::RecvPacket(_) => 1000,
623 _ => 0,
624 },
625 // Execution cost is currently hardcoded at 10 for all Action variants.
626 execution: 10,
627 }
628 }
629}
630
631impl GasCost for ValidatorDefinition {
632 fn gas_cost(&self) -> Gas {
633 validator_definition_gas_cost(&self)
634 }
635}
636
637impl GasCost for ActionDutchAuctionSchedule {
638 fn gas_cost(&self) -> Gas {
639 dutch_auction_schedule_gas_cost(&self)
640 }
641}
642
643impl GasCost for ActionDutchAuctionEnd {
644 fn gas_cost(&self) -> Gas {
645 dutch_auction_end_gas_cost()
646 }
647}
648
649impl GasCost for ActionDutchAuctionWithdraw {
650 fn gas_cost(&self) -> Gas {
651 dutch_auction_withdraw_gas_cost()
652 }
653}