1#[derive(Debug, Clone, Copy)]
3pub struct MemoryModel {
4 pub free_pages: u16,
5 pub page_gas: u16,
6}
7
8impl MemoryModel {
9 pub fn new(free_pages: u16, page_gas: u16) -> Self {
10 Self {
11 free_pages,
12 page_gas,
13 }
14 }
15
16 pub fn gas_cost(&self, new_pages: u16, open: u16, ever: u16) -> u64 {
18 let new_open = open.saturating_add(new_pages);
19 let new_ever = ever.max(new_open);
20
21 if new_ever <= self.free_pages {
22 return 0;
23 }
24
25 let sub_free = |pages: u16| -> u16 { pages.saturating_sub(self.free_pages) };
26
27 let adding = sub_free(new_open).saturating_sub(sub_free(open));
28 let linear = (adding as u64).saturating_mul(self.page_gas as u64);
29 let expand = self.exp(new_ever).saturating_sub(self.exp(ever));
30 linear.saturating_add(expand)
31 }
32
33 fn exp(&self, pages: u16) -> u64 {
34 let idx = pages as usize;
35 if idx < MEMORY_EXPONENTS.len() {
36 MEMORY_EXPONENTS[idx] as u64
37 } else {
38 u64::MAX
39 }
40 }
41}
42
43static MEMORY_EXPONENTS: [u32; 129] = [
45 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 14, 17, 19, 22, 25, 29, 33, 38,
46 43, 50, 57, 65, 75, 85, 98, 112, 128, 147, 168, 193, 221, 253, 289, 331, 379, 434, 497, 569,
47 651, 745, 853, 976, 1117, 1279, 1463, 1675, 1917, 2194, 2511, 2874, 3290, 3765, 4309, 4932,
48 5645, 6461, 7395, 8464, 9687, 11087, 12689, 14523, 16621, 19024, 21773, 24919, 28521, 32642,
49 37359, 42758, 48938, 56010, 64104, 73368, 83971, 96106, 109994, 125890, 144082, 164904, 188735,
50 216010, 247226, 282953, 323844, 370643, 424206, 485509, 555672, 635973, 727880, 833067, 953456,
51 1091243, 1248941, 1429429, 1636000, 1872423, 2143012, 2452704, 2807151, 3212820, 3677113,
52 4208502, 4816684, 5512756, 6309419, 7221210, 8264766, 9459129, 10826093, 12390601, 14181199,
53 16230562, 18576084, 21260563, 24332984, 27849408, 31873999,
54];