stratus/eth/primitives/
external_receipts.rs

1use std::collections::HashMap;
2
3use anyhow::anyhow;
4#[cfg(test)]
5use fake::Dummy;
6#[cfg(test)]
7use fake::Faker;
8
9use crate::eth::primitives::ExternalReceipt;
10use crate::eth::primitives::Hash;
11
12/// A collection of [`ExternalReceipt`].
13#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
14pub struct ExternalReceipts(HashMap<Hash, ExternalReceipt, hash_hasher::HashBuildHasher>);
15
16impl ExternalReceipts {
17    /// Tries to remove a receipt by its hash.
18    pub fn try_remove(&mut self, tx_hash: Hash) -> anyhow::Result<ExternalReceipt> {
19        match self.0.remove(&tx_hash) {
20            Some(receipt) => Ok(receipt),
21            None => {
22                tracing::error!(%tx_hash, "receipt is missing for hash");
23                Err(anyhow!("receipt missing for hash {tx_hash}"))
24            }
25        }
26    }
27}
28
29#[cfg(test)]
30impl Dummy<Faker> for ExternalReceipts {
31    fn dummy_with_rng<R: rand::Rng + ?Sized>(faker: &Faker, rng: &mut R) -> Self {
32        let count = (rng.next_u32() % 5 + 1) as usize;
33        let receipts = (0..count).map(|_| ExternalReceipt::dummy_with_rng(faker, rng)).collect::<Vec<_>>();
34
35        Self::from(receipts)
36    }
37}
38
39// -----------------------------------------------------------------------------
40// Conversions: Other -> Self
41// -----------------------------------------------------------------------------
42
43impl From<Vec<ExternalReceipt>> for ExternalReceipts {
44    fn from(receipts: Vec<ExternalReceipt>) -> Self {
45        let mut receipts_by_hash = HashMap::with_capacity_and_hasher(receipts.len(), hash_hasher::HashBuildHasher::default());
46        for receipt in receipts {
47            receipts_by_hash.insert(receipt.hash(), receipt);
48        }
49        Self(receipts_by_hash)
50    }
51}