|
3 | 3 | pub use crate::mock::*; |
4 | 4 | use crate::{ |
5 | 5 | config::{EPOCHS_PER_SYNC_COMMITTEE_PERIOD, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT}, |
6 | | - functions::compute_period, |
| 6 | + functions::{compute_epoch, compute_period}, |
7 | 7 | mock::{ |
8 | 8 | get_message_verification_payload, load_checkpoint_update_fixture, |
9 | 9 | load_finalized_header_update_fixture, load_next_finalized_header_update_fixture, |
@@ -974,3 +974,83 @@ fn verify_message_invalid_topic() { |
974 | 974 | ); |
975 | 975 | }); |
976 | 976 | } |
| 977 | + |
| 978 | +#[test] |
| 979 | +fn signing_root_uses_previous_slot_for_fork_version() { |
| 980 | + new_tester().execute_with(|| { |
| 981 | + // Use a signature_slot at a fork boundary (first slot of the fulu epoch). |
| 982 | + // In mock.rs: electra.epoch = 0, fulu.epoch = 100000000 |
| 983 | + let fulu_epoch = ChainForkVersions::get().fulu.epoch; |
| 984 | + let signature_slot: u64 = fulu_epoch * (SLOTS_PER_EPOCH as u64); |
| 985 | + |
| 986 | + // Verify this is the first slot of the epoch |
| 987 | + assert_eq!(signature_slot % (SLOTS_PER_EPOCH as u64), 0); |
| 988 | + |
| 989 | + let header = BeaconHeader { |
| 990 | + slot: signature_slot - 1, |
| 991 | + proposer_index: 0, |
| 992 | + parent_root: H256::repeat_byte(0x11), |
| 993 | + state_root: H256::repeat_byte(0x22), |
| 994 | + body_root: H256::repeat_byte(0x33), |
| 995 | + }; |
| 996 | + |
| 997 | + let validators_root = H256::repeat_byte(0x44); |
| 998 | + |
| 999 | + // Get fork versions for comparison |
| 1000 | + let fork_version_at_signature_slot = EthereumBeaconClient::compute_fork_version( |
| 1001 | + compute_epoch(signature_slot, SLOTS_PER_EPOCH as u64), |
| 1002 | + ); |
| 1003 | + let fork_version_at_previous_slot = EthereumBeaconClient::compute_fork_version( |
| 1004 | + compute_epoch(signature_slot.saturating_sub(1), SLOTS_PER_EPOCH as u64), |
| 1005 | + ); |
| 1006 | + |
| 1007 | + // At the fork boundary, these should differ |
| 1008 | + assert_ne!( |
| 1009 | + fork_version_at_signature_slot, fork_version_at_previous_slot, |
| 1010 | + "Test setup error: fork versions should differ at fork boundary" |
| 1011 | + ); |
| 1012 | + |
| 1013 | + // Compute signing roots using both fork versions |
| 1014 | + let domain_type = crate::config::DOMAIN_SYNC_COMMITTEE.to_vec(); |
| 1015 | + |
| 1016 | + let domain_with_previous_slot = EthereumBeaconClient::compute_domain( |
| 1017 | + domain_type.clone(), |
| 1018 | + fork_version_at_previous_slot, |
| 1019 | + validators_root, |
| 1020 | + ) |
| 1021 | + .unwrap(); |
| 1022 | + |
| 1023 | + let signing_root_with_previous_slot = |
| 1024 | + EthereumBeaconClient::compute_signing_root(&header, domain_with_previous_slot).unwrap(); |
| 1025 | + |
| 1026 | + // The pallet's signing_root should use the previous slot's fork version (per spec) |
| 1027 | + let pallet_signing_root = |
| 1028 | + EthereumBeaconClient::signing_root(&header, validators_root, signature_slot).unwrap(); |
| 1029 | + |
| 1030 | + assert_eq!( |
| 1031 | + pallet_signing_root, signing_root_with_previous_slot, |
| 1032 | + "signing_root should use fork version from signature_slot - 1" |
| 1033 | + ); |
| 1034 | + }); |
| 1035 | +} |
| 1036 | + |
| 1037 | +#[test] |
| 1038 | +fn signing_root_handles_signature_slot_zero() { |
| 1039 | + // Per spec: fork_version_slot = max(signature_slot, 1) - 1 |
| 1040 | + // When signature_slot = 0, saturating_sub(1) = 0, which matches max(0, 1) - 1 = 0 |
| 1041 | + new_tester().execute_with(|| { |
| 1042 | + let header = BeaconHeader { |
| 1043 | + slot: 0, |
| 1044 | + proposer_index: 0, |
| 1045 | + parent_root: H256::repeat_byte(0x11), |
| 1046 | + state_root: H256::repeat_byte(0x22), |
| 1047 | + body_root: H256::repeat_byte(0x33), |
| 1048 | + }; |
| 1049 | + |
| 1050 | + let validators_root = H256::repeat_byte(0x44); |
| 1051 | + |
| 1052 | + // Should not panic and should use epoch 0 fork version |
| 1053 | + let result = EthereumBeaconClient::signing_root(&header, validators_root, 0); |
| 1054 | + assert!(result.is_ok(), "signing_root should handle signature_slot = 0"); |
| 1055 | + }); |
| 1056 | +} |
0 commit comments