alloy_eip7928/
block_access_list.rs1use crate::account_changes::AccountChanges;
4use alloc::vec::Vec;
5
6pub type BlockAccessList = Vec<AccountChanges>;
8
9#[cfg(feature = "rlp")]
11pub fn compute_block_access_list_hash(bal: &[AccountChanges]) -> alloy_primitives::B256 {
12 let mut buf = Vec::new();
13 alloy_rlp::encode_list(bal, &mut buf);
14 alloy_primitives::keccak256(&buf)
15}
16
17pub fn total_bal_items(bal: &[AccountChanges]) -> u64 {
20 let mut bal_items: u64 = 0;
21
22 for account in bal {
23 bal_items += 1;
25
26 let mut unique_slots = alloy_primitives::map::HashSet::new();
28
29 for change in account.storage_changes() {
30 unique_slots.insert(change.slot);
31 }
32
33 for slot in account.storage_reads() {
34 unique_slots.insert(*slot);
35 }
36
37 bal_items += unique_slots.len() as u64;
39 }
40 bal_items
41}
42
43pub mod bal {
45 use crate::account_changes::AccountChanges;
46 use alloc::vec::{IntoIter, Vec};
47 use core::{
48 ops::{Deref, Index},
49 slice::Iter,
50 };
51
52 #[derive(Clone, Debug, Default, PartialEq, Eq)]
58 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59 #[cfg_attr(feature = "rlp", derive(alloy_rlp::RlpEncodable, alloy_rlp::RlpDecodable))]
60 pub struct Bal(Vec<AccountChanges>);
61
62 impl From<Bal> for Vec<AccountChanges> {
63 fn from(this: Bal) -> Self {
64 this.0
65 }
66 }
67
68 impl From<Vec<AccountChanges>> for Bal {
69 fn from(list: Vec<AccountChanges>) -> Self {
70 Self(list)
71 }
72 }
73
74 impl Deref for Bal {
75 type Target = [AccountChanges];
76
77 fn deref(&self) -> &Self::Target {
78 self.as_slice()
79 }
80 }
81
82 impl IntoIterator for Bal {
83 type Item = AccountChanges;
84 type IntoIter = IntoIter<AccountChanges>;
85
86 fn into_iter(self) -> Self::IntoIter {
87 self.0.into_iter()
88 }
89 }
90
91 impl<'a> IntoIterator for &'a Bal {
92 type Item = &'a AccountChanges;
93 type IntoIter = Iter<'a, AccountChanges>;
94
95 fn into_iter(self) -> Self::IntoIter {
96 self.iter()
97 }
98 }
99
100 impl FromIterator<AccountChanges> for Bal {
101 fn from_iter<I: IntoIterator<Item = AccountChanges>>(iter: I) -> Self {
102 Self(iter.into_iter().collect())
103 }
104 }
105
106 impl<I> Index<I> for Bal
107 where
108 I: core::slice::SliceIndex<[AccountChanges]>,
109 {
110 type Output = I::Output;
111
112 #[inline]
113 fn index(&self, index: I) -> &Self::Output {
114 &self.0[index]
115 }
116 }
117
118 impl Bal {
119 pub const fn new(account_changes: Vec<AccountChanges>) -> Self {
121 Self(account_changes)
122 }
123
124 pub fn push(&mut self, account_changes: AccountChanges) {
126 self.0.push(account_changes)
127 }
128
129 #[inline]
131 pub const fn is_empty(&self) -> bool {
132 self.0.is_empty()
133 }
134
135 #[inline]
137 pub const fn len(&self) -> usize {
138 self.0.len()
139 }
140
141 #[inline]
143 pub fn iter(&self) -> Iter<'_, AccountChanges> {
144 self.0.iter()
145 }
146
147 #[inline]
149 pub const fn as_slice(&self) -> &[AccountChanges] {
150 self.0.as_slice()
151 }
152
153 pub fn into_inner(self) -> Vec<AccountChanges> {
155 self.0
156 }
157
158 #[inline]
160 pub const fn account_count(&self) -> usize {
161 self.0.len()
162 }
163
164 pub fn total_storage_changes(&self) -> usize {
166 self.0.iter().map(|a| a.storage_changes.len()).sum()
167 }
168
169 pub fn total_storage_reads(&self) -> usize {
171 self.0.iter().map(|a| a.storage_reads.len()).sum()
172 }
173
174 pub fn total_slots(&self) -> usize {
176 self.0.iter().map(|a| a.storage_changes.len() + a.storage_reads.len()).sum()
177 }
178
179 pub fn total_balance_changes(&self) -> usize {
181 self.0.iter().map(|a| a.balance_changes.len()).sum()
182 }
183
184 pub fn total_nonce_changes(&self) -> usize {
186 self.0.iter().map(|a| a.nonce_changes.len()).sum()
187 }
188
189 pub fn total_code_changes(&self) -> usize {
191 self.0.iter().map(|a| a.code_changes.len()).sum()
192 }
193
194 pub fn change_counts(&self) -> BalChangeCounts {
199 let mut counts = BalChangeCounts::default();
200 for account in &self.0 {
201 counts.accounts += 1;
202 counts.storage += account.storage_changes.len();
203 counts.balance += account.balance_changes.len();
204 counts.nonce += account.nonce_changes.len();
205 counts.code += account.code_changes.len();
206 }
207 counts
208 }
209
210 pub fn total_bal_items(&self) -> u64 {
213 super::total_bal_items(&self.0)
214 }
215
216 #[cfg(feature = "rlp")]
218 pub fn compute_hash(&self) -> alloy_primitives::B256 {
219 super::compute_block_access_list_hash(&self.0)
220 }
221 }
222
223 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
225 pub struct BalChangeCounts {
226 pub accounts: usize,
228 pub storage: usize,
230 pub balance: usize,
232 pub nonce: usize,
234 pub code: usize,
236 }
237}