reth_rpc_eth_types/
utils.rs1use super::{EthApiError, EthResult};
4use alloy_consensus::TxReceipt;
5use reth_primitives_traits::{Recovered, SignedTransaction};
6use std::future::Future;
7
8pub fn calculate_gas_used_and_next_log_index(
10 tx_index: u64,
11 all_receipts: &[impl TxReceipt],
12) -> (u64, usize) {
13 let mut gas_used = 0;
14 let mut next_log_index = 0;
15
16 if tx_index > 0 {
17 for receipt in all_receipts.iter().take(tx_index as usize) {
18 gas_used = receipt.cumulative_gas_used();
19 next_log_index += receipt.logs().len();
20 }
21 }
22
23 (gas_used, next_log_index)
24}
25
26pub fn recover_raw_transaction<T: SignedTransaction>(data: &[u8]) -> EthResult<Recovered<T>> {
36 if data.is_empty() {
37 return Err(EthApiError::EmptyRawTransactionData)
38 }
39
40 let transaction =
41 T::decode_2718_exact(data).map_err(|_| EthApiError::FailedToDecodeSignedTransaction)?;
42
43 SignedTransaction::try_into_recovered(transaction)
44 .or(Err(EthApiError::InvalidTransactionSignature))
45}
46
47pub async fn binary_search<F, Fut, E>(low: u64, high: u64, check: F) -> Result<u64, E>
62where
63 F: Fn(u64) -> Fut,
64 Fut: Future<Output = Result<bool, E>>,
65{
66 let mut low = low;
67 let mut high = high;
68 let mut num = high;
69
70 while low <= high {
71 let mid = (low + high) / 2;
72 if check(mid).await? {
73 high = mid - 1;
74 num = mid;
75 } else {
76 low = mid + 1
77 }
78 }
79
80 Ok(num)
81}
82
83pub fn checked_blob_gas_used_ratio(blob_gas_used: u64, max_blob_gas_per_block: u64) -> f64 {
89 if blob_gas_used == 0 {
90 0.0
91 } else {
92 blob_gas_used as f64 / max_blob_gas_per_block as f64
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[tokio::test]
101 async fn test_binary_search() {
102 let num: Result<_, ()> =
104 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 5) })).await;
105 assert_eq!(num, Ok(5));
106
107 let num: Result<_, ()> =
109 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 7) })).await;
110 assert_eq!(num, Ok(7));
111
112 let num: Result<_, ()> =
114 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 1) })).await;
115 assert_eq!(num, Ok(1));
116
117 let num: Result<_, ()> =
119 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 11) })).await;
120 assert_eq!(num, Ok(10));
121 }
122
123 #[test]
124 fn test_checked_blob_gas_used_ratio() {
125 assert_eq!(checked_blob_gas_used_ratio(0, 0), 0.0);
127 assert_eq!(checked_blob_gas_used_ratio(0, 100), 0.0);
129 assert_eq!(checked_blob_gas_used_ratio(50, 100), 0.5);
131 assert_eq!(checked_blob_gas_used_ratio(100, 100), 1.0);
133 }
134}