penumbra_sdk_fee/component/
view.rs1use anyhow::{anyhow, Result};
2use async_trait::async_trait;
3use cnidarium::{StateRead, StateWrite};
4use penumbra_sdk_asset::asset;
5use penumbra_sdk_num::Amount;
6use penumbra_sdk_proto::{StateReadProto, StateWriteProto};
7
8use crate::{params::FeeParameters, state_key, Fee, GasPrices};
9
10#[async_trait]
13pub trait StateReadExt: StateRead {
14 async fn get_fee_params(&self) -> Result<FeeParameters> {
16 self.get(state_key::fee_params())
17 .await?
18 .ok_or_else(|| anyhow!("Missing FeeParameters"))
19 }
20
21 async fn get_gas_prices(&self) -> Result<GasPrices> {
23 let params = self.get_fee_params().await?;
28 Ok(params.fixed_gas_prices)
29 }
30
31 async fn get_alt_gas_prices(&self) -> Result<Vec<GasPrices>> {
33 let params = self.get_fee_params().await?;
38 Ok(params.fixed_alt_gas_prices)
39 }
40
41 fn gas_prices_changed(&self) -> bool {
43 self.object_get::<()>(state_key::gas_prices_changed())
44 .is_some()
45 }
46
47 fn accumulated_base_fees_and_tips(&self) -> im::OrdMap<asset::Id, (Amount, Amount)> {
49 self.object_get(state_key::fee_accumulator())
50 .unwrap_or_default()
51 }
52}
53
54impl<T: StateRead + ?Sized> StateReadExt for T {}
55
56#[async_trait]
57pub trait StateWriteExt: StateWrite {
58 fn put_fee_params(&mut self, params: FeeParameters) {
60 self.put(state_key::fee_params().into(), params);
61 self.object_put(state_key::gas_prices_changed(), ());
63 }
64
65 fn take_accumulated_base_fees_and_tips(&mut self) -> im::OrdMap<asset::Id, (Amount, Amount)> {
79 let old = self.accumulated_base_fees_and_tips();
80 let new = im::OrdMap::<asset::Id, (Amount, Amount)>::new();
81 self.object_put(state_key::fee_accumulator(), new);
82 old
83 }
84
85 fn raw_accumulate_base_fee(&mut self, base_fee: Fee) {
86 let old = self.accumulated_base_fees_and_tips();
87 let new = old.alter(
88 |maybe_amounts| match maybe_amounts {
89 Some((base, tip)) => Some((base + base_fee.amount(), tip)),
90 None => Some((base_fee.amount(), Amount::zero())),
91 },
92 base_fee.asset_id(),
93 );
94 self.object_put(state_key::fee_accumulator(), new);
95 }
96
97 fn raw_accumulate_tip(&mut self, tip_fee: Fee) {
98 let old = self.accumulated_base_fees_and_tips();
99 let new = old.alter(
100 |maybe_amounts| match maybe_amounts {
101 Some((base, tip)) => Some((base, tip + tip_fee.amount())),
102 None => Some((Amount::zero(), tip_fee.amount())),
103 },
104 tip_fee.asset_id(),
105 );
106 self.object_put(state_key::fee_accumulator(), new);
107 }
108}
109
110impl<T: StateWrite + ?Sized> StateWriteExt for T {}