kona_genesis/updates/
eip1559.rs1use alloy_primitives::LogData;
4use alloy_sol_types::{SolType, sol};
5
6use crate::{EIP1559UpdateError, SystemConfig, SystemConfigLog};
7
8#[derive(Debug, Default, Clone, Hash, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Eip1559Update {
12 pub eip1559_denominator: u32,
14 pub eip1559_elasticity: u32,
16}
17
18impl Eip1559Update {
19 pub const fn apply(&self, config: &mut SystemConfig) {
21 config.eip1559_denominator = Some(self.eip1559_denominator);
22 config.eip1559_elasticity = Some(self.eip1559_elasticity);
23 }
24}
25
26impl TryFrom<&SystemConfigLog> for Eip1559Update {
27 type Error = EIP1559UpdateError;
28
29 fn try_from(log: &SystemConfigLog) -> Result<Self, Self::Error> {
30 let LogData { data, .. } = &log.log.data;
31 if data.len() != 96 {
32 return Err(EIP1559UpdateError::InvalidDataLen(data.len()));
33 }
34
35 let Ok(pointer) = <sol!(uint64)>::abi_decode_validate(&data[0..32]) else {
36 return Err(EIP1559UpdateError::PointerDecodingError);
37 };
38 if pointer != 32 {
39 return Err(EIP1559UpdateError::InvalidDataPointer(pointer));
40 }
41
42 let Ok(length) = <sol!(uint64)>::abi_decode_validate(&data[32..64]) else {
43 return Err(EIP1559UpdateError::LengthDecodingError);
44 };
45 if length != 32 {
46 return Err(EIP1559UpdateError::InvalidDataLength(length));
47 }
48
49 let Ok(eip1559_params) = <sol!(uint64)>::abi_decode_validate(&data[64..96]) else {
50 return Err(EIP1559UpdateError::EIP1559DecodingError);
51 };
52
53 Ok(Self {
54 eip1559_denominator: (eip1559_params >> 32) as u32,
55 eip1559_elasticity: eip1559_params as u32,
56 })
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use crate::{CONFIG_UPDATE_EVENT_VERSION_0, CONFIG_UPDATE_TOPIC};
64 use alloc::vec;
65 use alloy_primitives::{Address, B256, Bytes, Log, LogData, hex};
66
67 #[test]
68 fn test_eip1559_update_try_from() {
69 let update_type = B256::ZERO;
70
71 let log = Log {
72 address: Address::ZERO,
73 data: LogData::new_unchecked(
74 vec![
75 CONFIG_UPDATE_TOPIC,
76 CONFIG_UPDATE_EVENT_VERSION_0,
77 update_type,
78 ],
79 hex!("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000babe0000beef").into()
80 )
81 };
82
83 let system_log = SystemConfigLog::new(log, false);
84 let update = Eip1559Update::try_from(&system_log).unwrap();
85
86 assert_eq!(update.eip1559_denominator, 0xbabe_u32);
87 assert_eq!(update.eip1559_elasticity, 0xbeef_u32);
88 }
89
90 #[test]
91 fn test_eip1559_update_invalid_data_len() {
92 let log =
93 Log { address: Address::ZERO, data: LogData::new_unchecked(vec![], Bytes::default()) };
94 let system_log = SystemConfigLog::new(log, false);
95 let err = Eip1559Update::try_from(&system_log).unwrap_err();
96 assert_eq!(err, EIP1559UpdateError::InvalidDataLen(0));
97 }
98
99 #[test]
100 fn test_eip1559_update_pointer_decoding_error() {
101 let log = Log {
102 address: Address::ZERO,
103 data: LogData::new_unchecked(
104 vec![
105 CONFIG_UPDATE_TOPIC,
106 CONFIG_UPDATE_EVENT_VERSION_0,
107 B256::ZERO,
108 ],
109 hex!("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000babe0000beef").into()
110 )
111 };
112
113 let system_log = SystemConfigLog::new(log, false);
114 let err = Eip1559Update::try_from(&system_log).unwrap_err();
115 assert_eq!(err, EIP1559UpdateError::PointerDecodingError);
116 }
117
118 #[test]
119 fn test_eip1559_update_invalid_pointer_length() {
120 let log = Log {
121 address: Address::ZERO,
122 data: LogData::new_unchecked(
123 vec![
124 CONFIG_UPDATE_TOPIC,
125 CONFIG_UPDATE_EVENT_VERSION_0,
126 B256::ZERO,
127 ],
128 hex!("000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000babe0000beef").into()
129 )
130 };
131
132 let system_log = SystemConfigLog::new(log, false);
133 let err = Eip1559Update::try_from(&system_log).unwrap_err();
134 assert_eq!(err, EIP1559UpdateError::InvalidDataPointer(33));
135 }
136
137 #[test]
138 fn test_eip1559_update_length_decoding_error() {
139 let log = Log {
140 address: Address::ZERO,
141 data: LogData::new_unchecked(
142 vec![
143 CONFIG_UPDATE_TOPIC,
144 CONFIG_UPDATE_EVENT_VERSION_0,
145 B256::ZERO,
146 ],
147 hex!("0000000000000000000000000000000000000000000000000000000000000020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000babe0000beef").into()
148 )
149 };
150
151 let system_log = SystemConfigLog::new(log, false);
152 let err = Eip1559Update::try_from(&system_log).unwrap_err();
153 assert_eq!(err, EIP1559UpdateError::LengthDecodingError);
154 }
155
156 #[test]
157 fn test_eip1559_update_invalid_data_length() {
158 let log = Log {
159 address: Address::ZERO,
160 data: LogData::new_unchecked(
161 vec![
162 CONFIG_UPDATE_TOPIC,
163 CONFIG_UPDATE_EVENT_VERSION_0,
164 B256::ZERO,
165 ],
166 hex!("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000babe0000beef").into()
167 )
168 };
169
170 let system_log = SystemConfigLog::new(log, false);
171 let err = Eip1559Update::try_from(&system_log).unwrap_err();
172 assert_eq!(err, EIP1559UpdateError::InvalidDataLength(33));
173 }
174
175 #[test]
176 fn test_eip1559_update_eip1559_decoding_error() {
177 let log = Log {
178 address: Address::ZERO,
179 data: LogData::new_unchecked(
180 vec![
181 CONFIG_UPDATE_TOPIC,
182 CONFIG_UPDATE_EVENT_VERSION_0,
183 B256::ZERO,
184 ],
185 hex!("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").into()
186 )
187 };
188
189 let system_log = SystemConfigLog::new(log, false);
190 let err = Eip1559Update::try_from(&system_log).unwrap_err();
191 assert_eq!(err, EIP1559UpdateError::EIP1559DecodingError);
192 }
193}