| 310 | |
| 311 | assert_eq!(epoch_length, new_epoch_length, "Epoch length should be {}", new_epoch_length); |
| 312 | println!("Epoch length successfully updated to {}!", new_epoch_length); |
| 313 | |
| 314 | println!("Protocol parameter change test completed successfully!"); |
| 315 | |
| 316 | Ok::<(), Box<dyn std::error::Error>>(()) |
| 317 | } |
| 318 | })?; |
| 319 | std::process::exit(0); |
| 320 | } |
| 321 | |
| 322 | async fn send_protocol_params_transaction<P>( |
| 323 | provider: &P, |
| 324 | protocol_params_contract_address: Address, |
| 325 | param_id: u8, |
| 326 | param_value: Vec<u8>, |
| 327 | nonce: u64, |
| 328 | ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> |
| 329 | where |
| 330 | P: Provider + WalletProvider, |
| 331 | { |
| 332 | use alloy_primitives::keccak256; |
| 333 | |
| 334 | // ABI encode the function call: set_param(uint8 param_id, bytes calldata param) |
| 335 | // Function selector is first 4 bytes of keccak256("set_param(uint8,bytes)") |
| 336 | let function_selector = &keccak256("set_param(uint8,bytes)")[0..4]; |
| 337 | |
| 338 | // ABI encoding: |
| 339 | // - 4 bytes: function selector |
| 340 | // - 32 bytes: param_id (uint8 left-padded to 32 bytes) |
| 341 | // - 32 bytes: offset to bytes data (always 0x40 = 64 bytes from start of params) |
| 342 | // - 32 bytes: length of bytes data |
| 343 | // - N bytes: actual bytes data (padded to 32-byte boundary) |
| 344 | |
| 345 | let mut call_data = Vec::new(); |
| 346 | |
| 347 | // Add function selector |
| 348 | call_data.extend_from_slice(function_selector); |
| 349 | |
| 350 | // Add param_id (uint8 left-padded to 32 bytes) |
| 351 | let mut param_id_bytes = [0u8; 32]; |
| 352 | param_id_bytes[31] = param_id; |
| 353 | call_data.extend_from_slice(¶m_id_bytes); |
| 354 | |
| 355 | // Add offset to bytes data (0x40 = 64 bytes from start of parameter encoding) |
| 356 | let mut offset_bytes = [0u8; 32]; |
| 357 | offset_bytes[28..32].copy_from_slice(&64u32.to_be_bytes()); |
| 358 | call_data.extend_from_slice(&offset_bytes); |
| 359 | |
| 360 | // Add length of bytes data |
| 361 | let mut length_bytes = [0u8; 32]; |
| 362 | length_bytes[28..32].copy_from_slice(&(param_value.len() as u32).to_be_bytes()); |
| 363 | call_data.extend_from_slice(&length_bytes); |
| 364 | |
| 365 | // Add the actual bytes data |
| 366 | call_data.extend_from_slice(¶m_value); |
| 367 | |
| 368 | // Pad to 32-byte boundary if needed |
| 369 | let padding_needed = (32 - (param_value.len() % 32)) % 32; |