From 4412e8eb39759e8e6d071710c5cf86977d3d9772 Mon Sep 17 00:00:00 2001 From: Maciej Skrzypkowski Date: Fri, 22 May 2026 15:26:56 +0200 Subject: [PATCH 1/3] Corrected DutyDefinitionSet to match Charon implementation --- crates/core/src/types.rs | 89 +++++++++++++--------------------------- 1 file changed, 29 insertions(+), 60 deletions(-) diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 8d971f7d..35edacde 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -69,6 +69,25 @@ impl DutyType { pub fn is_valid(&self) -> bool { !matches!(self, DutyType::Unknown | DutyType::DutySentinel(_)) } + + /// Returns all valid duty types, matching Go's `AllDutyTypes()`. + pub fn all() -> &'static [DutyType] { + &[ + DutyType::Proposer, + DutyType::Attester, + DutyType::Signature, + DutyType::Exit, + DutyType::BuilderProposer, + DutyType::BuilderRegistration, + DutyType::Randao, + DutyType::PrepareAggregator, + DutyType::Aggregator, + DutyType::SyncMessage, + DutyType::PrepareSyncContribution, + DutyType::SyncContribution, + DutyType::InfoSync, + ] + } } /// Error type for duty type conversion. @@ -400,60 +419,12 @@ impl AsRef<[u8]> for PubKey { // todo: add toEth2Format for the pub key // https://github.com/ObolNetwork/charon/blob/b3008103c5429b031b63518195f4c49db4e9a68d/core/types.go#L311 -/// Duty definition type -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct DutyDefinition(T); - -impl DutyDefinition -where - T: Clone + Serialize + StdDebug, -{ - /// Create a new duty definition. - pub fn new(duty_definition: T) -> Self { - Self(duty_definition) - } -} - -/// Duty definition set -#[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct DutyDefinitionSet(HashMap>) -where - T: Clone + Serialize + StdDebug; +/// Duty definition interface +pub trait DutyDefinition: DynClone + StdDebug + Send + Sync {} +dyn_clone::clone_trait_object!(DutyDefinition); -impl DutyDefinitionSet -where - T: Clone + Serialize + StdDebug, -{ - /// Create a new duty definition set. - pub fn new() -> Self { - Self(HashMap::default()) - } - - /// Get a duty definition by duty type. - pub fn get(&self, duty_type: &DutyType) -> Option<&DutyDefinition> { - self.0.get(duty_type) - } - - /// Insert a duty definition. - pub fn insert(&mut self, duty_type: DutyType, duty_definition: DutyDefinition) { - self.0.insert(duty_type, duty_definition); - } - - /// Remove a duty definition by duty type. - pub fn remove(&mut self, duty_type: &DutyType) -> Option> { - self.0.remove(duty_type) - } - - /// Inner duty definition set. - pub fn inner(&self) -> &HashMap> { - &self.0 - } - - /// Inner duty definition set. - pub fn inner_mut(&mut self) -> &mut HashMap> { - &mut self.0 - } -} +/// One duty definition per validator +pub type DutyDefinitionSet = HashMap>; /// Unsigned data type #[derive(Debug, Clone, PartialEq, Eq)] @@ -997,13 +968,11 @@ mod tests { } #[test] - fn duty_definition_set() { - let mut duty_definition_set = DutyDefinitionSet::new(); - duty_definition_set.insert(DutyType::Proposer, DutyDefinition::new(DutyType::Proposer)); - assert_eq!( - duty_definition_set.get(&DutyType::Proposer), - Some(&DutyDefinition::new(DutyType::Proposer)) - ); + fn duty_type_all() { + let all = DutyType::all(); + assert_eq!(all.len(), 13); + assert!(all.iter().all(DutyType::is_valid)); + assert!(!all.contains(&DutyType::Unknown)); } #[test] From 61024debfb24cb5cf84f6cb2c48a978813e21ae7 Mon Sep 17 00:00:00 2001 From: Maciej Skrzypkowski Date: Fri, 22 May 2026 16:07:18 +0200 Subject: [PATCH 2/3] back to generic version of DutyDefinitionSet --- crates/core/src/types.rs | 75 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 35edacde..520e6111 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -419,12 +419,65 @@ impl AsRef<[u8]> for PubKey { // todo: add toEth2Format for the pub key // https://github.com/ObolNetwork/charon/blob/b3008103c5429b031b63518195f4c49db4e9a68d/core/types.go#L311 -/// Duty definition interface -pub trait DutyDefinition: DynClone + StdDebug + Send + Sync {} -dyn_clone::clone_trait_object!(DutyDefinition); +/// Duty definition type. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DutyDefinition(T); + +impl DutyDefinition +where + T: Clone + Serialize + StdDebug, +{ + /// Create a new duty definition. + pub fn new(duty_definition: T) -> Self { + Self(duty_definition) + } + + /// Inner value. + pub fn inner(&self) -> &T { + &self.0 + } +} + +/// One duty definition per validator, matching Go's `core.DutyDefinitionSet`. +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct DutyDefinitionSet(HashMap>) +where + T: Clone + Serialize + StdDebug; + +impl DutyDefinitionSet +where + T: Clone + Serialize + StdDebug, +{ + /// Create a new duty definition set. + pub fn new() -> Self { + Self(HashMap::default()) + } + + /// Get a duty definition by public key. + pub fn get(&self, pubkey: &PubKey) -> Option<&DutyDefinition> { + self.0.get(pubkey) + } + + /// Insert a duty definition. + pub fn insert(&mut self, pubkey: PubKey, duty_definition: DutyDefinition) { + self.0.insert(pubkey, duty_definition); + } + + /// Remove a duty definition by public key. + pub fn remove(&mut self, pubkey: &PubKey) -> Option> { + self.0.remove(pubkey) + } + + /// Iterate over all public keys in the set. + pub fn keys(&self) -> impl Iterator { + self.0.keys() + } -/// One duty definition per validator -pub type DutyDefinitionSet = HashMap>; + /// Inner map. + pub fn inner(&self) -> &HashMap> { + &self.0 + } +} /// Unsigned data type #[derive(Debug, Clone, PartialEq, Eq)] @@ -975,6 +1028,18 @@ mod tests { assert!(!all.contains(&DutyType::Unknown)); } + #[test] + fn duty_definition_set() { + let pubkey = PubKey::new([1u8; PK_LEN]); + let mut set = DutyDefinitionSet::new(); + set.insert(pubkey, DutyDefinition::new(DutyType::Proposer)); + assert_eq!( + set.get(&pubkey), + Some(&DutyDefinition::new(DutyType::Proposer)) + ); + assert_eq!(set.keys().count(), 1); + } + #[test] fn unsigned_data_set() { let mut unsigned_data_set = UnsignedDataSet::new(); From a0d642a26ea02b1c36d43455bd0f92e196af184e Mon Sep 17 00:00:00 2001 From: Maciej Skrzypkowski Date: Fri, 22 May 2026 16:28:36 +0200 Subject: [PATCH 3/3] inner mut --- crates/core/src/types.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 520e6111..d332ef30 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -477,6 +477,11 @@ where pub fn inner(&self) -> &HashMap> { &self.0 } + + /// Inner map (mutable). + pub fn inner_mut(&mut self) -> &mut HashMap> { + &mut self.0 + } } /// Unsigned data type