diff --git a/consensus/types/src/core/config_and_preset.rs b/consensus/types/src/core/config_and_preset.rs index 08141c77311..4b83112ca78 100644 --- a/consensus/types/src/core/config_and_preset.rs +++ b/consensus/types/src/core/config_and_preset.rs @@ -141,6 +141,13 @@ pub fn get_extra_fields(spec: &ChainSpec) -> HashMap { "compounding_withdrawal_prefix".to_uppercase() => u8_hex(spec.compounding_withdrawal_prefix_byte), "unset_deposit_requests_start_index".to_uppercase() => spec.unset_deposit_requests_start_index.to_string().into(), "full_exit_request_amount".to_uppercase() => spec.full_exit_request_amount.to_string().into(), + // Time parameters + "slot_duration_ms".to_uppercase() => spec.slot_duration_ms.to_string().into(), + "proposer_reorg_cutoff_bps".to_uppercase() => spec.proposer_reorg_cutoff_bps.to_string().into(), + "attestation_due_bps".to_uppercase() => spec.attestation_due_bps.to_string().into(), + "aggregate_due_bps".to_uppercase() => spec.aggregate_due_bps.to_string().into(), + "contribution_due_bps".to_uppercase() => spec.contribution_due_bps.to_string().into(), + "sync_message_due_bps".to_uppercase() => spec.sync_message_due_bps.to_string().into(), } } @@ -183,4 +190,24 @@ mod test { serde_yaml::from_reader(reader).expect("error while deserializing"); assert_eq!(ConfigAndPreset::Gloas(from), yamlconfig); } + + // This is not exhaustive, but it can be extended as new fields are added to the spec. + #[test] + fn test_required_spec_fields_exist() { + let mainnet_spec = ChainSpec::mainnet(); + let config = ConfigAndPreset::from_chain_spec::(&mainnet_spec); + let json = serde_json::to_value(&config).expect("should serialize"); + let obj = json.as_object().expect("should be an object"); + let required_fields = [ + "SLOT_DURATION_MS", + "PROPOSER_REORG_CUTOFF_BPS", + "ATTESTATION_DUE_BPS", + "AGGREGATE_DUE_BPS", + "CONTRIBUTION_DUE_BPS", + "SYNC_MESSAGE_DUE_BPS", + ]; + for field in required_fields { + assert!(obj.contains_key(field), "Missing required field: {}", field); + } + } }