kabu_types_entities/
latest_block.rs1use 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}