reth_rpc_eth_types/
utils.rs1use super::{EthApiError, EthResult};
4use reth_primitives_traits::{Recovered, SignedTransaction};
5use std::future::Future;
6
7pub fn recover_raw_transaction<T: SignedTransaction>(mut data: &[u8]) -> EthResult<Recovered<T>> {
14 if data.is_empty() {
15 return Err(EthApiError::EmptyRawTransactionData)
16 }
17
18 let transaction =
19 T::decode_2718(&mut data).map_err(|_| EthApiError::FailedToDecodeSignedTransaction)?;
20
21 SignedTransaction::try_into_recovered(transaction)
22 .or(Err(EthApiError::InvalidTransactionSignature))
23}
24
25pub async fn binary_search<F, Fut, E>(low: u64, high: u64, check: F) -> Result<u64, E>
40where
41 F: Fn(u64) -> Fut,
42 Fut: Future<Output = Result<bool, E>>,
43{
44 let mut low = low;
45 let mut high = high;
46 let mut num = high;
47
48 while low <= high {
49 let mid = (low + high) / 2;
50 if check(mid).await? {
51 high = mid - 1;
52 num = mid;
53 } else {
54 low = mid + 1
55 }
56 }
57
58 Ok(num)
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[tokio::test]
66 async fn test_binary_search() {
67 let num: Result<_, ()> =
69 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 5) })).await;
70 assert_eq!(num, Ok(5));
71
72 let num: Result<_, ()> =
74 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 7) })).await;
75 assert_eq!(num, Ok(7));
76
77 let num: Result<_, ()> =
79 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 1) })).await;
80 assert_eq!(num, Ok(1));
81
82 let num: Result<_, ()> =
84 binary_search(1, 10, |mid| Box::pin(async move { Ok(mid >= 11) })).await;
85 assert_eq!(num, Ok(10));
86 }
87}