kabu_types_entities/
latest_block.rs

1use alloy_primitives::map::B256HashMap;
2use alloy_primitives::{Address, BlockHash, BlockNumber, B256};
3use alloy_rpc_types::state::{AccountOverride, StateOverride};
4use alloy_rpc_types::Header;
5
6use kabu_types_blockchain::{GethStateUpdate, KabuBlock, KabuHeader};
7use kabu_types_blockchain::{KabuDataTypes, KabuDataTypesEthereum};
8
9pub struct LatestBlock<LDT: KabuDataTypes = KabuDataTypesEthereum> {
10    pub block_number: BlockNumber,
11    pub block_hash: BlockHash,
12    pub block_header: Option<LDT::Header>,
13    pub block_with_txs: Option<LDT::Block>,
14    pub logs: Option<Vec<LDT::Log>>,
15    pub diff: Option<Vec<LDT::StateUpdate>>,
16}
17
18impl<LDT: KabuDataTypes<Header = Header, StateUpdate = GethStateUpdate>> LatestBlock<LDT> {
19    pub fn hash(&self) -> BlockHash {
20        self.block_hash
21    }
22
23    pub fn parent_hash(&self) -> Option<BlockHash> {
24        self.block_header.as_ref().map(|x| <Header as KabuHeader<LDT>>::get_parent_hash(x))
25    }
26    pub fn number(&self) -> BlockNumber {
27        self.block_number
28    }
29
30    pub fn number_and_hash(&self) -> (BlockNumber, BlockHash) {
31        (self.block_number, self.block_hash)
32    }
33
34    pub fn new(block_number: BlockNumber, block_hash: BlockHash) -> Self {
35        Self { block_number, block_hash, block_header: None, block_with_txs: None, logs: None, diff: None }
36    }
37
38    pub fn node_state_override(&self) -> StateOverride {
39        let mut cur_state_override = StateOverride::default();
40
41        if let Some(cur_diff) = self.diff.as_ref() {
42            for diff_entry in cur_diff {
43                for (addr, state) in diff_entry {
44                    let account = cur_state_override.entry(*addr).or_insert(AccountOverride::default());
45                    account.balance = state.balance;
46                    account.nonce = state.nonce;
47
48                    let diff: B256HashMap<B256> = state.storage.iter().map(|(k, v)| (*k, *v)).collect();
49                    account.state_diff = Some(diff);
50                }
51            }
52        }
53        cur_state_override
54    }
55
56    pub fn txs(&self) -> Option<Vec<LDT::Transaction>> {
57        self.block_with_txs.as_ref().map(|block| block.get_transactions())
58    }
59
60    pub fn coinbase(&self) -> Option<Address> {
61        if let Some(block) = &self.block_with_txs {
62            return Some(<alloy_rpc_types::Header as KabuHeader<LDT>>::get_beneficiary(&block.get_header()));
63        }
64        None
65    }
66
67    pub fn update(
68        &mut self,
69        block_number: BlockNumber,
70        block_hash: BlockHash,
71        block_header: Option<LDT::Header>,
72        block_with_txes: Option<LDT::Block>,
73        logs: Option<Vec<LDT::Log>>,
74        diff: Option<Vec<LDT::StateUpdate>>,
75    ) -> bool {
76        if block_number >= self.block_number {
77            let is_new = block_number > self.block_number;
78
79            if block_number > self.block_number || block_hash != self.block_hash {
80                *self = Self::new(block_number, block_hash);
81            }
82
83            if let Some(x) = block_header {
84                self.block_header = Some(x);
85            }
86            if let Some(x) = block_with_txes {
87                self.block_with_txs = Some(x);
88            }
89            if let Some(x) = logs {
90                self.logs = Some(x);
91            }
92            if let Some(x) = diff {
93                self.diff = Some(x)
94            }
95
96            is_new
97        } else {
98            false
99        }
100    }
101}