eventify_primitives/networks/polygon/
block.rs

1use std::{fmt::Debug, hash::Hash};
2
3use alloy_primitives::U256;
4use eyre::Result;
5use redis::AsyncCommands;
6use sqlx::FromRow;
7use utoipa::ToSchema;
8
9use crate::{
10    networks::{core::CoreBlock, NetworkKind, ResourceKind},
11    traits::{Block, Emit, Insert, Stream},
12    PropagateError,
13};
14
15#[derive(
16    Clone,
17    Debug,
18    Default,
19    serde::Deserialize,
20    serde::Serialize,
21    PartialEq,
22    Eq,
23    Hash,
24    FromRow,
25    ToSchema,
26)]
27pub struct PolygonBlock {
28    #[serde(flatten)]
29    core: CoreBlock,
30
31    #[serde(rename = "baseFeePerGas")]
32    pub base_fee: Option<U256>,
33    #[serde(rename = "totalDifficulty")]
34    pub total_difficulty: Option<U256>,
35}
36
37impl Block for PolygonBlock {
38    fn core(&self) -> &CoreBlock {
39        &self.core
40    }
41}
42
43impl Insert for PolygonBlock {
44    async fn insert(
45        &self,
46        pool: &sqlx::PgPool,
47        _: &Option<alloy_primitives::B256>,
48    ) -> Result<(), sqlx::Error> {
49        self.core.insert(pool, NetworkKind::Polygon).await
50    }
51}
52
53impl Emit for PolygonBlock {
54    async fn emit(
55        &self,
56        queue: &redis::Client,
57        network: &NetworkKind,
58    ) -> Result<(), PropagateError> {
59        let mut con = queue.get_async_connection().await?;
60
61        let channel = format!("{}:{}", network, ResourceKind::Block);
62        con.lpush(channel, serde_json::to_string(self)?).await?;
63
64        Ok(())
65    }
66}
67
68impl Stream for PolygonBlock {
69    async fn stream(
70        &self,
71        queue: &redis::Client,
72        network: &NetworkKind,
73    ) -> Result<(), PropagateError> {
74        self.core().stream(queue, network).await
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn deserialize_polygon_block() {
84        let json = serde_json::json!(
85            {
86                "parentHash": "0x4912fcaf7296fb5bdb46d48e2c0b3cc41cb3aa1850e2a1fbeae6932b455c8d0d",
87                "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
88                "miner": "0x0000000000000000000000000000000000000000",
89                "stateRoot": "0xc935b71945c996e1b01aef1561c07687c4fcec10f93a150da9e33e40a768ffe4",
90                "transactionsRoot": "0x116d6f925a8b3abe7c390ccc7f0fb10b40c4d15d3c28ff3df9816c6c3f91ab4a",
91                "receiptsRoot": "0x4e82db0e69291538acaedc49446154b4fbdf01cf14d97855e5b826f5fd431422",
92                "logsBloom": "0x176f24aae180d2c873b520bebc350e067ac8e17c884185a6bdb6c8ff90a0f9b15210158c6ec791fb461a1b3057157e914845c7ad6b47fc02261a0d9094e62b08295cc9187efb442c56f01c19f1e75affe28194e6bdc6d5b41f47d422823b6e5911771bf75a4a8414537e0c09b7c68ac8534632a32bda762df531d036e04916ebe7fba905a5ac71bc5121ffc53c9380e3d71b37ddab265ece6b5fad4760a40a9d7fd0737655c02e2135a1efbf78f892056fd94c7594d78c87cd889fb21a6a29c9ab8477f3841b6d97e2abeb280f9875dce256e20b539bf41a5f3feb53eacba2c512f58dc829acce8a7b853ddeb082dd6a5fb8c78b91e12a631065d93326b6c99a",
93                "difficulty": "0x16",
94                "number": "0x3412ab0",
95                "gasLimit": "0x1c9c380",
96                "gasUsed": "0xfcf8cb",
97                "timestamp": "0x65f1686f",
98                "extraData": "0xd88301020783626f7289676f312e32302e3134856c696e757800000000000000817c89d9bd2e4714e027a526d7ba90692ffe08dc71fa0831f8f6412f53fa747704a6c45259b8744e88458ea2c839a6c902f944059c0fc0b5610bfea22210874701",
99                "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
100                "nonce": "0x0000000000000000",
101                "baseFeePerGas": "0x112fe5ea31",
102                "withdrawalsRoot": null,
103                "blobGasUsed": null,
104                "excessBlobGas": null,
105                "parentBeaconBlockRoot": null,
106                "hash": "0xf70473275b652c4542cc90e3d6e807679522fc7f8a998d7a4dba6f5420f30463"
107              }
108        );
109
110        assert!(serde_json::from_value::<PolygonBlock>(json.clone()).is_ok());
111    }
112
113    #[test]
114    fn deserialize_empty_polygon_block() {
115        let json = serde_json::json!({});
116
117        assert!(serde_json::from_value::<PolygonBlock>(json).is_err());
118    }
119}