forest/message_pool/msgpool/
utils.rs1use crate::chain::MINIMUM_BASE_FEE;
5use crate::message::{MessageRead as _, SignedMessage};
6use crate::message_pool::{
7 Error,
8 msgpool::{RBF_DENOM, REPLACE_BY_FEE_RATIO_MIN},
9};
10use crate::shim::address::Address;
11use crate::shim::{crypto::Signature, econ::TokenAmount, message::Message, percent::Percent};
12use crate::utils::cache::SizeTrackingCache;
13use crate::utils::get_size::CidWrapper;
14use ahash::HashMap;
15use num_rational::BigRational;
16use num_traits::ToPrimitive;
17
18pub(in crate::message_pool) fn get_base_fee_lower_bound(
19 base_fee: &TokenAmount,
20 factor: i64,
21) -> TokenAmount {
22 let base_fee_lower_bound = base_fee.div_floor(factor);
23 if base_fee_lower_bound.atto() < &MINIMUM_BASE_FEE.into() {
24 TokenAmount::from_atto(MINIMUM_BASE_FEE)
25 } else {
26 base_fee_lower_bound
27 }
28}
29
30pub(in crate::message_pool) fn get_gas_reward(
32 msg: &SignedMessage,
33 base_fee: &TokenAmount,
34) -> TokenAmount {
35 let mut max_prem = msg.gas_fee_cap() - base_fee;
36 if max_prem < msg.gas_premium() {
37 max_prem = msg.gas_premium();
38 }
39 max_prem * msg.gas_limit()
40}
41
42pub(in crate::message_pool) fn get_gas_perf(gas_reward: &TokenAmount, gas_limit: u64) -> f64 {
43 if gas_limit == 0 {
46 return 0.0;
47 }
48 let a = BigRational::new(
49 gas_reward.atto() * crate::shim::econ::BLOCK_GAS_LIMIT,
50 gas_limit.into(),
51 );
52 a.to_f64().unwrap()
53}
54
55pub(in crate::message_pool) fn recover_sig(
58 bls_sig_cache: &SizeTrackingCache<CidWrapper, Signature>,
59 msg: Message,
60) -> Result<SignedMessage, Error> {
61 let val = bls_sig_cache
62 .get(&msg.cid())
63 .ok_or_else(|| Error::Other("Could not recover sig".to_owned()))?;
64 let smsg = SignedMessage::new_from_parts(msg, val)?;
65 Ok(smsg)
66}
67
68pub(in crate::message_pool) fn add_to_selected_msgs(
69 m: SignedMessage,
70 rmsgs: &mut HashMap<Address, HashMap<u64, SignedMessage>>,
71) {
72 rmsgs.entry(m.from()).or_default().insert(m.sequence(), m);
73}
74
75pub(in crate::message_pool) fn remove_from_selected_msgs(
76 from: &Address,
77 sequence: u64,
78 rmsgs: &mut HashMap<Address, HashMap<u64, SignedMessage>>,
79) {
80 if let Some(set) = rmsgs.get_mut(from) {
81 set.remove(&sequence);
82 }
83}
84
85pub(crate) fn compute_rbf_min_premium(premium: &TokenAmount) -> TokenAmount {
90 (premium * *REPLACE_BY_FEE_RATIO_MIN).div_floor(RBF_DENOM) + TokenAmount::from_atto(1u8)
91}
92
93pub(crate) fn compute_rbf(premium: &TokenAmount, replace_by_fee_ratio: Percent) -> TokenAmount {
98 (premium * *replace_by_fee_ratio).div_floor(RBF_DENOM) + TokenAmount::from_atto(1u8)
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn test_compute_rbf() {
107 let replace_by_fee_ratio = Percent(125);
108 assert_eq!(
109 super::compute_rbf(&TokenAmount::from_atto(100u64), replace_by_fee_ratio),
110 TokenAmount::from_atto(126u64) );
112 }
113
114 #[test]
115 fn test_compute_rbf_min_premium() {
116 assert_eq!(
117 super::compute_rbf_min_premium(&TokenAmount::from_atto(100u64)),
118 TokenAmount::from_atto(111u64) );
120 }
121
122 #[test]
123 fn get_gas_perf_zero_gas_limit_does_not_panic() {
124 assert_eq!(
128 super::get_gas_perf(&TokenAmount::from_atto(1_000u64), 0),
129 0.0
130 );
131 }
132}