From 75b5d790c4ca5e9b9e2291bc7098571185d92be8 Mon Sep 17 00:00:00 2001 From: Ameer Ghani Date: Fri, 22 Nov 2024 15:33:32 -0600 Subject: [PATCH] deps: replace derivative with educe (#3506) * deps: replace derivative with educe * PR review --- Cargo.lock | 51 ++++++++++--- Cargo.toml | 2 +- aggregator/Cargo.toml | 2 +- .../src/aggregator/aggregation_job_driver.rs | 18 ++--- .../src/aggregator/collection_job_driver.rs | 8 +- aggregator/src/aggregator/key_rotator.rs | 8 +- aggregator/src/binaries/aggregator.rs | 8 +- aggregator/src/config.rs | 8 +- aggregator/src/diagnostic.rs | 10 +-- aggregator/src/metrics/tokio_runtime.rs | 26 +++---- aggregator_api/Cargo.toml | 2 +- aggregator_api/src/models.rs | 26 +++---- aggregator_core/Cargo.toml | 2 +- aggregator_core/src/datastore/models.rs | 76 ++++++++++--------- aggregator_core/src/lib.rs | 8 +- aggregator_core/src/task.rs | 31 ++++---- aggregator_core/src/taskprov.rs | 14 ++-- client/Cargo.toml | 2 +- client/src/lib.rs | 10 +-- collector/Cargo.toml | 2 +- collector/src/lib.rs | 24 +++--- core/Cargo.toml | 2 +- core/src/auth_tokens.rs | 25 +++--- core/src/dp.rs | 3 +- core/src/hpke.rs | 8 +- core/src/vdaf.rs | 6 +- integration_tests/Cargo.toml | 2 +- .../tests/integration/simulation/run.rs | 8 +- interop_binaries/Cargo.toml | 2 +- .../src/commands/janus_interop_client.rs | 10 +-- .../src/commands/janus_interop_collector.rs | 8 +- interop_binaries/src/lib.rs | 10 +-- messages/Cargo.toml | 2 +- messages/src/lib.rs | 40 +++++----- messages/src/taskprov.rs | 4 +- tools/Cargo.toml | 1 - 36 files changed, 247 insertions(+), 222 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f42862e40..31d4d3aea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1477,6 +1477,18 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "either" version = "1.12.0" @@ -1523,6 +1535,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -2552,7 +2584,7 @@ dependencies = [ "console-subscriber", "deadpool", "deadpool-postgres", - "derivative", + "educe", "fixed", "futures", "hex", @@ -2631,7 +2663,7 @@ dependencies = [ "assert_matches", "async-trait", "base64 0.22.1", - "derivative", + "educe", "futures", "git-version", "janus_aggregator_core", @@ -2670,7 +2702,7 @@ dependencies = [ "clap", "deadpool", "deadpool-postgres", - "derivative", + "educe", "futures", "hex", "http", @@ -2717,7 +2749,7 @@ dependencies = [ "assert_matches", "backoff", "bhttp", - "derivative", + "educe", "hex-literal", "http", "itertools 0.13.0", @@ -2744,7 +2776,7 @@ dependencies = [ "backoff", "base64 0.22.1", "chrono", - "derivative", + "educe", "fixed", "hpke-dispatch", "janus_collector", @@ -2775,7 +2807,7 @@ dependencies = [ "chrono", "clap", "constcat", - "derivative", + "educe", "fixed", "futures", "hex", @@ -2823,8 +2855,8 @@ dependencies = [ "base64 0.22.1", "chrono", "clap", - "derivative", "divviup-client", + "educe", "futures", "hex", "http", @@ -2867,7 +2899,7 @@ dependencies = [ "backoff", "base64 0.22.1", "clap", - "derivative", + "educe", "fixed", "futures", "hex", @@ -2923,7 +2955,7 @@ dependencies = [ "anyhow", "assert_matches", "base64 0.22.1", - "derivative", + "educe", "hex", "num_enum", "pretty_assertions", @@ -2944,7 +2976,6 @@ dependencies = [ "base64 0.22.1", "cfg-if", "clap", - "derivative", "fixed", "janus_collector", "janus_core", diff --git a/Cargo.toml b/Cargo.toml index 5efa6fe8d..37e021eae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,8 +40,8 @@ console-subscriber = "0.4.1" constcat = "0.5" deadpool = "0.12.1" deadpool-postgres = "0.14.0" -derivative = "2.2.0" divviup-client = "0.4" +educe = { version = "0.6.0", default-features = false, features = ["Debug"] } fixed = "1.27" futures = "0.3.31" git-version = "0.3.9" diff --git a/aggregator/Cargo.toml b/aggregator/Cargo.toml index 02e6a6977..4885cc901 100644 --- a/aggregator/Cargo.toml +++ b/aggregator/Cargo.toml @@ -48,7 +48,7 @@ clap.workspace = true console-subscriber = { workspace = true, optional = true } deadpool = { workspace = true, features = ["rt_tokio_1"] } deadpool-postgres = { workspace = true } -derivative.workspace = true +educe.workspace = true fixed = { workspace = true, optional = true } futures = { workspace = true } hex = { workspace = true, features = ["serde"] } diff --git a/aggregator/src/aggregator/aggregation_job_driver.rs b/aggregator/src/aggregator/aggregation_job_driver.rs index 6f5587541..3a3d74624 100644 --- a/aggregator/src/aggregator/aggregation_job_driver.rs +++ b/aggregator/src/aggregator/aggregation_job_driver.rs @@ -16,7 +16,7 @@ use crate::{ use anyhow::{anyhow, Result}; use backoff::backoff::Backoff; use bytes::Bytes; -use derivative::Derivative; +use educe::Educe; use futures::future::BoxFuture; use janus_aggregator_core::{ datastore::{ @@ -59,8 +59,8 @@ use tracing::{debug, error, info, info_span, trace_span, warn, Span}; #[cfg(test)] mod tests; -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] pub struct AggregationJobDriver { // Configuration. batch_aggregation_shard_count: u64, @@ -70,17 +70,17 @@ pub struct AggregationJobDriver { http_client: reqwest::Client, backoff: B, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_success_counter: Counter, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregate_step_failure_counter: Counter, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregated_report_share_dimension_histogram: Histogram, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] job_cancel_counter: Counter, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] job_retry_counter: Counter, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] http_request_duration_histogram: Histogram, } diff --git a/aggregator/src/aggregator/collection_job_driver.rs b/aggregator/src/aggregator/collection_job_driver.rs index e4a90c55f..8cb77f8dd 100644 --- a/aggregator/src/aggregator/collection_job_driver.rs +++ b/aggregator/src/aggregator/collection_job_driver.rs @@ -8,7 +8,7 @@ use crate::aggregator::{ use anyhow::bail; use backoff::backoff::Backoff; use bytes::Bytes; -use derivative::Derivative; +use educe::Educe; use futures::future::{try_join_all, BoxFuture}; use janus_aggregator_core::{ datastore::{ @@ -42,13 +42,13 @@ use tokio::try_join; use tracing::{error, info, warn}; /// Drives a collection job. -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] pub struct CollectionJobDriver { // Dependencies. http_client: reqwest::Client, backoff: B, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] metrics: CollectionJobDriverMetrics, // Configuration. diff --git a/aggregator/src/aggregator/key_rotator.rs b/aggregator/src/aggregator/key_rotator.rs index 2b461f65b..162e95683 100644 --- a/aggregator/src/aggregator/key_rotator.rs +++ b/aggregator/src/aggregator/key_rotator.rs @@ -2,7 +2,7 @@ use crate::aggregator::Config as AggregatorConfig; // used in doccomment. use crate::cache::HpkeKeypairCache; use anyhow::{anyhow, Error}; -use derivative::Derivative; +use educe::Educe; use futures::{future::try_join_all, FutureExt}; use janus_aggregator_core::datastore::{ models::{HpkeKeyState, HpkeKeypair}, @@ -153,14 +153,14 @@ fn duration_since(clock: &C, time: &Time) -> Duration { } /// In-memory representation of the `hpke_keys` table. -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] struct HpkeKeyRotator<'a, C: Clock> { clock: C, config: &'a HpkeKeyRotatorConfig, // Data structures for intermediate state. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] available_ids: Box + Send + Sync>, keypairs: HashMap, initially_empty: bool, diff --git a/aggregator/src/binaries/aggregator.rs b/aggregator/src/binaries/aggregator.rs index f0c8ab6f4..62cbeae5f 100644 --- a/aggregator/src/binaries/aggregator.rs +++ b/aggregator/src/binaries/aggregator.rs @@ -13,7 +13,7 @@ use crate::{ }; use anyhow::{anyhow, Context, Result}; use clap::Parser; -use derivative::Derivative; +use educe::Educe; use janus_aggregator_api::{self, aggregator_api_handler}; use janus_aggregator_core::datastore::Datastore; use janus_core::{auth_tokens::AuthenticationToken, time::RealClock, TokioRuntime}; @@ -239,9 +239,9 @@ impl BinaryOptions for Options { } /// Options for serving the aggregator API. -#[derive(Clone, Derivative, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Educe, PartialEq, Eq, Serialize, Deserialize)] #[serde(deny_unknown_fields)] -#[derivative(Debug)] +#[educe(Debug)] pub struct AggregatorApi { /// Address on which this server should listen for connections to the Janus aggregator API /// and serve its API endpoints, independently from the address on which the DAP API is @@ -255,7 +255,7 @@ pub struct AggregatorApi { pub path_prefix: Option, /// Resource location at which the DAP service managed by this aggregator api can be found /// on the public internet. Required. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub public_dap_url: Url, } diff --git a/aggregator/src/config.rs b/aggregator/src/config.rs index e126624e9..3520440e0 100644 --- a/aggregator/src/config.rs +++ b/aggregator/src/config.rs @@ -2,7 +2,7 @@ use crate::{metrics::MetricsConfiguration, trace::TraceConfiguration}; use backoff::{ExponentialBackoff, ExponentialBackoffBuilder}; -use derivative::Derivative; +use educe::Educe; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{ fmt::Debug, @@ -77,12 +77,12 @@ pub trait BinaryConfig: Debug + DeserializeOwned { } /// Configuration for a Janus server using a database. -#[derive(Clone, Derivative, PartialEq, Eq, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq, Serialize, Deserialize)] +#[educe(Debug)] #[serde(deny_unknown_fields)] pub struct DbConfig { /// URL at which to connect to the database. - #[derivative(Debug(format_with = "format_database_url"))] + #[educe(Debug(method(format_database_url)))] pub url: Url, /// Timeout in seconds to apply when creating, waiting for, or recycling diff --git a/aggregator/src/diagnostic.rs b/aggregator/src/diagnostic.rs index 1358fc832..835ad4d6b 100644 --- a/aggregator/src/diagnostic.rs +++ b/aggregator/src/diagnostic.rs @@ -1,15 +1,15 @@ //! Writing diagnostic files to disk. use anyhow::Context; -use derivative::Derivative; +use educe::Educe; use janus_messages::{AggregationJobId, ReportId, TaskId}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::{fs::File, path::Path, time::SystemTime}; use uuid::Uuid; /// Represents an illegal attempt to mutate an aggregation job. -#[derive(Derivative, Clone, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Educe, Clone, Serialize, Deserialize)] +#[educe(Debug)] pub struct AggregationJobInitForbiddenMutationEvent { /// The ID of the task. #[serde(with = "serialize_task_id")] @@ -21,7 +21,7 @@ pub struct AggregationJobInitForbiddenMutationEvent { /// The SHA-256 of the request that created the aggregation job. #[serde(with = "serialize_hash_option")] - #[derivative(Debug(format_with = "fmt_hash_option"))] + #[educe(Debug(method(fmt_hash_option)))] pub original_request_hash: Option<[u8; 32]>, /// The ordered report metadatas from the request that created the aggregation job. @@ -36,7 +36,7 @@ pub struct AggregationJobInitForbiddenMutationEvent { /// The SHA-256 of the request that attempted to mutate the aggregation job. #[serde(with = "serialize_hash_option")] - #[derivative(Debug(format_with = "fmt_hash_option"))] + #[educe(Debug(method(fmt_hash_option)))] pub mutating_request_hash: Option<[u8; 32]>, /// The ordered report metadatas from the request that attempted to mutate the aggregation job. diff --git a/aggregator/src/metrics/tokio_runtime.rs b/aggregator/src/metrics/tokio_runtime.rs index 28d885701..4c6300ea0 100644 --- a/aggregator/src/metrics/tokio_runtime.rs +++ b/aggregator/src/metrics/tokio_runtime.rs @@ -2,7 +2,7 @@ use std::time::Duration; use std::time::SystemTime; -use derivative::Derivative; +use educe::Educe; use opentelemetry::{metrics::MetricsError, InstrumentationLibrary, KeyValue}; #[cfg(tokio_unstable)] use opentelemetry_sdk::metrics::data::{Histogram, HistogramDataPoint, Sum, Temporality}; @@ -62,20 +62,20 @@ pub(crate) fn configure_runtime( } } -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] pub(super) struct TokioRuntimeMetrics { runtime_metrics: RuntimeMetrics, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] scope: InstrumentationLibrary, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] start_time: SystemTime, num_workers: usize, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] attributes_global_queue: Vec, #[cfg(tokio_unstable)] @@ -83,26 +83,26 @@ pub(super) struct TokioRuntimeMetrics { } #[cfg(tokio_unstable)] -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] struct UnstableTokioRuntimeMetrics { poll_time_histogram_num_buckets: usize, poll_time_histogram_bucket_bounds: Vec, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] attributes_local: Vec, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] attributes_local_overflow: Vec, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] attributes_remote: Vec, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] attributes_local_queue_worker: Vec>, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] attributes_blocking_queue: Vec, } diff --git a/aggregator_api/Cargo.toml b/aggregator_api/Cargo.toml index 2ef2735cc..e834cd05d 100644 --- a/aggregator_api/Cargo.toml +++ b/aggregator_api/Cargo.toml @@ -12,7 +12,7 @@ version.workspace = true anyhow.workspace = true async-trait = { workspace = true } base64.workspace = true -derivative.workspace = true +educe.workspace = true git-version.workspace = true janus_aggregator_core.workspace = true janus_core.workspace = true diff --git a/aggregator_api/src/models.rs b/aggregator_api/src/models.rs index 0b6e82006..4d391fc2c 100644 --- a/aggregator_api/src/models.rs +++ b/aggregator_api/src/models.rs @@ -1,5 +1,5 @@ use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; -use derivative::Derivative; +use educe::Educe; use janus_aggregator_core::{ datastore::models::{HpkeKeyState, HpkeKeypair, TaskAggregationCounter, TaskUploadCounter}, task::{AggregatorTask, BatchMode}, @@ -25,11 +25,11 @@ pub(crate) enum AggregatorRole { Helper, } -#[derive(Serialize, PartialEq, Eq, Derivative)] -#[derivative(Debug)] +#[derive(Serialize, PartialEq, Eq, Educe)] +#[educe(Debug)] pub(crate) struct AggregatorApiConfig { pub protocol: &'static str, - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub dap_url: Url, pub role: AggregatorRole, pub vdafs: Vec, @@ -56,12 +56,12 @@ pub(crate) struct GetTaskIdsResp { pub(crate) pagination_token: Option, } -#[derive(Derivative, PartialEq, Eq, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Educe, PartialEq, Eq, Serialize, Deserialize)] +#[educe(Debug)] pub(crate) struct PostTaskReq { /// URL relative to which this task's peer aggregator's DAP API can be found. The peer /// aggregator plays the DAP role opposite to the one in the `role` field. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub(crate) peer_aggregator_endpoint: Url, /// DAP batch mode for this task. pub(crate) batch_mode: BatchMode, @@ -98,14 +98,14 @@ pub(crate) struct PatchTaskReq { pub(crate) task_end: Option>, } -#[derive(Clone, Derivative, PartialEq, Eq, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq, Serialize, Deserialize)] +#[educe(Debug)] pub(crate) struct TaskResp { /// ID of the DAP Task. pub(crate) task_id: TaskId, /// URL relative to which this task's peer aggregator's DAP API can be found. The peer /// aggregator plays the DAP role opposite to the one in the `role` field. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub(crate) peer_aggregator_endpoint: Url, /// DAP batch mode for this task. pub(crate) batch_mode: BatchMode, @@ -197,10 +197,10 @@ pub(crate) struct PatchHpkeConfigReq { pub(crate) state: HpkeKeyState, } -#[derive(Derivative, PartialEq, Eq, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Educe, PartialEq, Eq, Serialize, Deserialize)] +#[educe(Debug)] pub(crate) struct TaskprovPeerAggregatorResp { - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub(crate) endpoint: Url, pub(crate) role: Role, pub(crate) collector_hpke_config: HpkeConfig, diff --git a/aggregator_core/Cargo.toml b/aggregator_core/Cargo.toml index 9157a6744..99156f9cf 100644 --- a/aggregator_core/Cargo.toml +++ b/aggregator_core/Cargo.toml @@ -30,7 +30,7 @@ chrono.workspace = true clap.workspace = true deadpool = { workspace = true, features = ["rt_tokio_1"] } deadpool-postgres = { workspace = true } -derivative.workspace = true +educe.workspace = true futures = { workspace = true } hex = { workspace = true, features = ["serde"], optional = true } http.workspace = true diff --git a/aggregator_core/src/datastore/models.rs b/aggregator_core/src/datastore/models.rs index cc85efc98..46e262578 100644 --- a/aggregator_core/src/datastore/models.rs +++ b/aggregator_core/src/datastore/models.rs @@ -4,7 +4,7 @@ use crate::{datastore::Error, task}; use base64::{display::Base64Display, engine::general_purpose::URL_SAFE_NO_PAD}; use chrono::NaiveDateTime; use clap::ValueEnum; -use derivative::Derivative; +use educe::Educe; use janus_core::{ auth_tokens::{AuthenticationToken, AuthenticationTokenHash}, hpke::{self, HpkeCiphersuite}, @@ -97,20 +97,21 @@ impl From<&AuthenticationTokenHash> for AuthenticationTokenType { /// Represents a report as it is stored in the Leader's database, corresponding to an unscrubbed row /// in `client_reports`. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] pub struct LeaderStoredReport where A: vdaf::Aggregator, { task_id: TaskId, metadata: ReportMetadata, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] public_share: A::PublicShare, + #[educe(Debug(ignore))] leader_private_extensions: Vec, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] leader_input_share: A::InputShare, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] helper_encrypted_input_share: HpkeCiphertext, } @@ -380,8 +381,8 @@ impl AggregatorRole { } /// AggregationJob represents an aggregation job from the DAP specification. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] pub struct AggregationJob> { /// The ID of the task this aggregation job belongs to. @@ -389,7 +390,7 @@ pub struct AggregationJob> { StartLeader { /// The sequence of public extensions from this report's metadata. + #[educe(Debug(ignore))] public_extensions: Vec, /// Public share for this report. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] public_share: A::PublicShare, /// The sequence of extensions from the Leader's input share for this report. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] leader_private_extensions: Vec, /// The Leader's input share for this report. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] leader_input_share: A::InputShare, /// The Helper's encrypted input share for this report. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] helper_encrypted_input_share: HpkeCiphertext, }, WaitingLeader { /// Most recent transition for this report aggregation. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] transition: PingPongTransition, }, WaitingHelper { /// Helper's current preparation state - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] prepare_state: A::PrepareState, }, Finished, @@ -1223,8 +1225,8 @@ impl ReportAggregationMetadata { /// `aggregation_parameter`. This is the finest-grained possible aggregate share we can emit for /// this task. The aggregate share constructed to service a collect or aggregate share request /// consists of one or more `BatchAggregation`s merged together. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] pub struct BatchAggregation< const SEED_SIZE: usize, B: BatchMode, @@ -1235,7 +1237,7 @@ pub struct BatchAggregation< /// The identifier of the batch being aggregated over. batch_identifier: B::BatchIdentifier, /// The VDAF aggregation parameter used to prepare and accumulate input shares. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_parameter: A::AggregationParam, /// The index of this batch aggregation among all batch aggregations for /// this (task_id, batch_identifier, aggregation_parameter). @@ -1449,18 +1451,18 @@ where } /// Represents the state of a batch aggregation. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] pub enum BatchAggregationState> { Aggregating { /// The aggregate over all the input shares that have been prepared so far by this /// aggregator. Will only be None if there are no reports. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregate_share: Option, /// The number of reports currently included in this aggregate share. report_count: u64, /// Checksum over the aggregated report shares. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] checksum: ReportIdChecksum, /// The number of aggregation jobs that have been created for this batch. aggregation_jobs_created: u64, @@ -1471,12 +1473,12 @@ pub enum BatchAggregationState, /// The number of reports currently included in this aggregate share. report_count: u64, /// Checksum over the aggregated report shares. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] checksum: ReportIdChecksum, /// The number of aggregation jobs that have been created for this batch. aggregation_jobs_created: u64, @@ -1683,8 +1685,8 @@ where /// CollectionJob represents a row in the `collection_jobs` table, used by leaders to represent /// running collection jobs and store the results of completed ones. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] pub struct CollectionJob> { /// The task ID for this collection job. task_id: TaskId, @@ -1693,7 +1695,7 @@ pub struct CollectionJob, /// The VDAF aggregation parameter used to prepare and aggregate input shares. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_parameter: A::AggregationParam, /// The batch interval covered by the collection job. batch_identifier: B::BatchIdentifier, @@ -1810,8 +1812,8 @@ where { } -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] pub enum CollectionJobState> { Start, Finished { @@ -1823,7 +1825,7 @@ pub enum CollectionJobState); +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] +pub struct SecretBytes(#[educe(Debug(ignore))] Vec); impl SecretBytes { pub fn new(buf: Vec) -> Self { diff --git a/aggregator_core/src/task.rs b/aggregator_core/src/task.rs index ab81e773f..359a1190e 100644 --- a/aggregator_core/src/task.rs +++ b/aggregator_core/src/task.rs @@ -2,7 +2,7 @@ use crate::SecretBytes; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; -use derivative::Derivative; +use educe::Educe; use janus_core::{ auth_tokens::{AuthenticationToken, AuthenticationTokenHash}, time::TimeExt, @@ -64,9 +64,9 @@ impl TryFrom<&taskprov::Query> for BatchMode { /// A verification key for a VDAF, with a fixed length. It must be kept secret from clients to /// maintain robustness, and it must be shared between aggregators. -#[derive(Derivative, Clone, Copy)] -#[derivative(Debug)] -pub struct VerifyKey(#[derivative(Debug = "ignore")] [u8; SEED_SIZE]); +#[derive(Educe, Clone, Copy)] +#[educe(Debug)] +pub struct VerifyKey(#[educe(Debug(ignore))] [u8; SEED_SIZE]); impl VerifyKey { pub fn new(array: [u8; SEED_SIZE]) -> VerifyKey { @@ -88,8 +88,7 @@ impl TryFrom<&SecretBytes> for VerifyKey { } /// Task parameters common to all views of a DAP task. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] struct CommonTaskParameters { /// Unique identifier for the task. task_id: TaskId, @@ -206,13 +205,13 @@ impl CommonTaskParameters { } /// An aggregator's view of the task's parameters. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub struct AggregatorTask { /// Common task parameters common_parameters: CommonTaskParameters, /// URL relative to which the peer aggregator's API endpoints are found. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] peer_aggregator_endpoint: Url, /// Parameters specific to either aggregator role aggregator_parameters: AggregatorTaskParameters, @@ -470,8 +469,8 @@ impl AggregatorTask { } /// Role-specific task parameters for the aggregator DAP roles. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub enum AggregatorTaskParameters { /// Task parameters held exclusively by the DAP leader. Leader { @@ -720,7 +719,7 @@ pub mod test_util { }, SecretBytes, }; - use derivative::Derivative; + use educe::Educe; use janus_core::{ auth_tokens::{AuthenticationToken, AuthenticationTokenHash}, hpke::HpkeKeypair, @@ -736,16 +735,16 @@ pub mod test_util { use url::Url; /// All parameters and secrets for a task, for all participants. - #[derive(Clone, Derivative, PartialEq, Eq)] - #[derivative(Debug)] + #[derive(Clone, Educe, PartialEq, Eq)] + #[educe(Debug)] pub struct Task { /// Common task parameters common_parameters: CommonTaskParameters, /// URL relative to which the leader aggregator's API endpoints are found. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] leader_aggregator_endpoint: Url, /// URL relative to which the leader aggregator's API endpoints are found. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] helper_aggregator_endpoint: Url, /// HPKE configuration and private key used by the collector to decrypt aggregate shares. collector_hpke_keypair: HpkeKeypair, diff --git a/aggregator_core/src/taskprov.rs b/aggregator_core/src/taskprov.rs index 94e5e1507..a6337ef1a 100644 --- a/aggregator_core/src/taskprov.rs +++ b/aggregator_core/src/taskprov.rs @@ -1,6 +1,6 @@ use crate::{task::Error, SecretBytes}; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; -use derivative::Derivative; +use educe::Educe; use janus_core::{auth_tokens::AuthenticationToken, vdaf::VdafInstance}; use janus_messages::{Duration, HpkeConfig, Role, TaskId}; use rand::{distributions::Standard, prelude::Distribution}; @@ -12,9 +12,9 @@ use serde::{ use std::{fmt, str::FromStr, sync::OnceLock}; use url::Url; -#[derive(Derivative, Clone, Copy, PartialEq, Eq)] -#[derivative(Debug)] -pub struct VerifyKeyInit(#[derivative(Debug = "ignore")] [u8; Self::LEN]); +#[derive(Educe, Clone, Copy, PartialEq, Eq)] +#[educe(Debug)] +pub struct VerifyKeyInit(#[educe(Debug(ignore))] [u8; Self::LEN]); impl VerifyKeyInit { pub const LEN: usize = 32; @@ -92,12 +92,12 @@ impl FromStr for VerifyKeyInit { /// Represents another aggregator that is peered with our aggregator for taskprov purposes. Contains /// data that needs to be identical between both aggregators for the taskprov flow to work. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub struct PeerAggregator { /// The URL at which the peer aggregator can be reached. This, along with `role`, is used to /// uniquely represent the peer aggregator. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] endpoint: Url, /// The role that the peer aggregator takes in DAP. Must be [`Role::Leader`] or [`Role::Helper`]. diff --git a/client/Cargo.toml b/client/Cargo.toml index f9779ec64..82239b945 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -19,7 +19,7 @@ ohttp = ["dep:ohttp", "dep:bhttp"] [dependencies] backoff = { workspace = true, features = ["tokio"] } bhttp = { workspace = true, features = ["bhttp", "http"], optional = true } -derivative.workspace = true +educe.workspace = true http.workspace = true itertools.workspace = true janus_core.workspace = true diff --git a/client/src/lib.rs b/client/src/lib.rs index 6ad90265a..c0768ba1a 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -42,7 +42,7 @@ use backoff::ExponentialBackoff; #[cfg(feature = "ohttp")] use bhttp::{ControlData, Message, Mode}; -use derivative::Derivative; +use educe::Educe; #[cfg(feature = "ohttp")] use http::{header::ACCEPT, HeaderValue}; use http::{header::CONTENT_TYPE, StatusCode}; @@ -136,16 +136,16 @@ const OHTTP_REQUEST_MEDIA_TYPE: &str = "message/ohttp-req"; const OHTTP_RESPONSE_MEDIA_TYPE: &str = "message/ohttp-res"; /// The DAP client's view of task parameters. -#[derive(Clone, Derivative)] -#[derivative(Debug)] +#[derive(Clone, Educe)] +#[educe(Debug)] struct ClientParameters { /// Unique identifier for the task. task_id: TaskId, /// URL relative to which the Leader's API endpoints are found. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] leader_aggregator_endpoint: Url, /// URL relative to which the Helper's API endpoints are found. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] helper_aggregator_endpoint: Url, /// The time precision of the task. This value is shared by all parties in the protocol, and is /// used to compute report timestamps. diff --git a/collector/Cargo.toml b/collector/Cargo.toml index 849bf6ffe..c06e1ab96 100644 --- a/collector/Cargo.toml +++ b/collector/Cargo.toml @@ -20,7 +20,7 @@ test-util = [] [dependencies] backoff = { workspace = true, features = ["tokio"] } chrono.workspace = true -derivative.workspace = true +educe.workspace = true fixed = { workspace = true, optional = true } hpke-dispatch = { workspace = true, features = ["serde"] } janus_core.workspace = true diff --git a/collector/src/lib.rs b/collector/src/lib.rs index 53d2a7cae..b0923dd09 100644 --- a/collector/src/lib.rs +++ b/collector/src/lib.rs @@ -67,7 +67,7 @@ use backoff::backoff::Backoff; pub use backoff::ExponentialBackoff; use chrono::{DateTime, Duration, TimeZone, Utc}; pub use credential::PrivateCollectorCredential; -use derivative::Derivative; +use educe::Educe; pub use janus_core::auth_tokens::AuthenticationToken; use janus_core::{ hpke::{self, HpkeApplicationInfo, HpkeKeypair}, @@ -159,8 +159,8 @@ pub fn default_http_client() -> Result { } /// Collector state related to a collection job that is in progress. -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] pub struct CollectionJob where B: BatchMode, @@ -170,7 +170,7 @@ where /// The collection request's query. query: Query, /// The aggregation parameter used in this collection request. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_parameter: P, } @@ -204,8 +204,8 @@ impl CollectionJob { } } -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] /// The result of a collection request poll operation. This will either provide the collection /// result or indicate that the collection is still being processed. pub enum PollResult @@ -213,7 +213,7 @@ where B: BatchMode, { /// The collection result from a completed collection request. - CollectionResult(#[derivative(Debug = "ignore")] Collection), + CollectionResult(#[educe(Debug(ignore))] Collection), /// The collection request is not yet ready. If present, the [`RetryAfter`] object is the time /// at which the leader recommends retrying the request. NotReady(Option), @@ -386,24 +386,24 @@ impl CollectorBuilder { } /// A DAP collector. -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] pub struct Collector { /// Unique identifier for the task. task_id: TaskId, /// The base URL of the leader's aggregator API endpoints. - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] leader_endpoint: Url, /// The authentication information needed to communicate with the leader aggregator. authentication: AuthenticationToken, /// HPKE keypair used for decryption of aggregate shares. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] hpke_keypair: HpkeKeypair, /// An implementation of the task's VDAF. vdaf: V, /// HTTPS client. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] http_client: reqwest::Client, /// Parameters to use when retrying HTTP requests. http_request_retry_parameters: ExponentialBackoff, diff --git a/core/Cargo.toml b/core/Cargo.toml index 0b7ef7c55..8285509dd 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -42,7 +42,7 @@ bytes.workspace = true chrono = { workspace = true, features = ["clock"] } clap.workspace = true constcat.workspace = true -derivative.workspace = true +educe.workspace = true fixed = { workspace = true, optional = true } futures = { workspace = true } hex = { workspace = true } diff --git a/core/src/auth_tokens.rs b/core/src/auth_tokens.rs index 2381db7e9..0b3940a6b 100644 --- a/core/src/auth_tokens.rs +++ b/core/src/auth_tokens.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; -use derivative::Derivative; +use educe::Educe; use http::{header::AUTHORIZATION, HeaderValue}; use rand::{distributions::Standard, prelude::Distribution}; use regex::Regex; @@ -19,8 +19,7 @@ pub const DAP_AUTH_HEADER: &str = "DAP-Auth-Token"; /// Different modes of authentication supported by Janus for either sending requests (e.g., leader /// to helper) or receiving them (e.g., collector to leader). -#[derive(Clone, Derivative, Serialize, Deserialize, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(tag = "type", content = "token")] #[non_exhaustive] pub enum AuthenticationToken { @@ -129,10 +128,10 @@ impl Distribution for Standard { /// /// This opaque type ensures it's impossible to construct an [`AuthenticationToken`] whose contents /// are invalid. -#[derive(Clone, Derivative, Serialize)] -#[derivative(Debug)] +#[derive(Clone, Educe, Serialize)] +#[educe(Debug)] #[serde(transparent)] -pub struct DapAuthToken(#[derivative(Debug = "ignore")] String); +pub struct DapAuthToken(#[educe(Debug(ignore))] String); impl DapAuthToken { /// Returns the token as a string. @@ -228,10 +227,10 @@ impl Distribution for Standard { /// /// This opaque type ensures it's impossible to construct an [`AuthenticationToken`] whose contents /// are invalid. -#[derive(Clone, Derivative, Serialize)] -#[derivative(Debug)] +#[derive(Clone, Educe, Serialize)] +#[educe(Debug)] #[serde(transparent)] -pub struct BearerToken(#[derivative(Debug = "ignore")] String); +pub struct BearerToken(#[educe(Debug(ignore))] String); impl BearerToken { /// Returns the token as a string. @@ -328,8 +327,8 @@ impl Distribution for Standard { /// The hash of an authentication token, which may be used to validate tokens in incoming requests /// but not to authenticate outgoing requests. -#[derive(Clone, Derivative, Deserialize, Serialize, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, Deserialize, Serialize, Eq)] +#[educe(Debug)] #[serde(tag = "type", content = "hash")] #[non_exhaustive] pub enum AuthenticationTokenHash { @@ -340,7 +339,7 @@ pub enum AuthenticationTokenHash { /// /// [1]: https://datatracker.ietf.org/doc/html/rfc6750#section-2.1 Bearer( - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] #[serde( serialize_with = "AuthenticationTokenHash::serialize_contents", deserialize_with = "AuthenticationTokenHash::deserialize_contents" @@ -357,7 +356,7 @@ pub enum AuthenticationTokenHash { /// [3]: https://datatracker.ietf.org/doc/html/draft-dcook-ppm-dap-interop-test-design-03#section-4.4.2 /// [4]: https://datatracker.ietf.org/doc/html/draft-ietf-ppm-dap-01#name-https-sender-authentication DapAuth( - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] #[serde( serialize_with = "AuthenticationTokenHash::serialize_contents", deserialize_with = "AuthenticationTokenHash::deserialize_contents" diff --git a/core/src/dp.rs b/core/src/dp.rs index 8a179d343..09f39d2f4 100644 --- a/core/src/dp.rs +++ b/core/src/dp.rs @@ -1,4 +1,3 @@ -use derivative::Derivative; #[cfg(feature = "fpvec_bounded_l2")] use fixed::traits::Fixed; #[cfg(feature = "fpvec_bounded_l2")] @@ -33,7 +32,7 @@ impl DifferentialPrivacyDistribution for NoDistribution {} /// A "no-op" differential privacy strategy. Tasks which don't require differential privacy should /// use this type as their `DifferentialPrivacyStrategy`. -#[derive(Debug, Derivative, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct NoDifferentialPrivacy; impl DifferentialPrivacyStrategy for NoDifferentialPrivacy { type Budget = NoBudget; diff --git a/core/src/hpke.rs b/core/src/hpke.rs index d5bef83f8..99e9f55c6 100644 --- a/core/src/hpke.rs +++ b/core/src/hpke.rs @@ -2,7 +2,7 @@ use crate::DAP_VERSION_IDENTIFIER; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; use constcat::concat; -use derivative::Derivative; +use educe::Educe; use hpke_dispatch::{HpkeError, Kem, Keypair}; use janus_messages::{ HpkeAeadId, HpkeCiphertext, HpkeConfig, HpkeConfigId, HpkeKdfId, HpkeKemId, HpkePublicKey, Role, @@ -92,9 +92,9 @@ impl HpkeApplicationInfo { /// An HPKE private key, serialized using the `SerializePrivateKey` function as /// described in RFC 9180, §4 and §7.1.2. // TODO(#230): refactor HpkePrivateKey to simplify usage -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] -pub struct HpkePrivateKey(#[derivative(Debug = "ignore")] Vec); +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] +pub struct HpkePrivateKey(#[educe(Debug(ignore))] Vec); impl HpkePrivateKey { /// Construct a private key from its serialized form. diff --git a/core/src/vdaf.rs b/core/src/vdaf.rs index aa6e76f3e..e49aed07b 100644 --- a/core/src/vdaf.rs +++ b/core/src/vdaf.rs @@ -1,5 +1,4 @@ use crate::DAP_VERSION_IDENTIFIER; -use derivative::Derivative; use janus_messages::{taskprov, TaskId}; use prio::{ field::Field64, @@ -38,7 +37,7 @@ pub fn vdaf_application_context( /// Bitsize parameter for the `Prio3FixedPointBoundedL2VecSum` VDAF. #[cfg(feature = "fpvec_bounded_l2")] -#[derive(Debug, Derivative, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub enum Prio3FixedPointBoundedL2VecSumBitSize { BitSize16, BitSize32, @@ -104,8 +103,7 @@ pub mod vdaf_dp_strategies { /// [draft-irtf-cfrg-vdaf-03][1] and implementations in [`prio::vdaf::prio3`]. /// /// [1]: https://datatracker.ietf.org/doc/draft-irtf-cfrg-vdaf/03/ -#[derive(Derivative, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[non_exhaustive] pub enum VdafInstance { /// A `Prio3` counter. diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index 2a704a179..832cdf379 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -46,8 +46,8 @@ uuid.workspace = true [dev-dependencies] chrono.workspace = true -derivative.workspace = true divviup-client = { workspace = true, features = ["admin"] } +educe.workspace = true janus_collector = { workspace = true, features = ["test-util"] } opentelemetry.workspace = true quickcheck.workspace = true diff --git a/integration_tests/tests/integration/simulation/run.rs b/integration_tests/tests/integration/simulation/run.rs index 2dfc4f56e..4c42f2b37 100644 --- a/integration_tests/tests/integration/simulation/run.rs +++ b/integration_tests/tests/integration/simulation/run.rs @@ -6,7 +6,7 @@ use std::{ time::{Duration as StdDuration, Instant}, }; -use derivative::Derivative; +use educe::Educe; use futures::future::join_all; use janus_aggregator::aggregator; use janus_aggregator_core::{ @@ -498,13 +498,13 @@ impl Simulation { } } -#[derive(Derivative)] -#[derivative(Debug)] +#[derive(Educe)] +#[educe(Debug)] pub(super) struct State { pub(super) stopper: Stopper, pub(super) clock: MockClock, pub(super) meter: Meter, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] pub(super) runtime_manager: TestRuntimeManager<&'static str>, pub(super) vdaf_instance: VdafInstance, pub(super) vdaf: Prio3Histogram, diff --git a/interop_binaries/Cargo.toml b/interop_binaries/Cargo.toml index 0da11098d..4e89acf1c 100644 --- a/interop_binaries/Cargo.toml +++ b/interop_binaries/Cargo.toml @@ -21,7 +21,7 @@ anyhow.workspace = true backoff = { workspace = true, features = ["tokio"] } base64.workspace = true clap.workspace = true -derivative.workspace = true +educe.workspace = true fixed = { workspace = true, optional = true } futures = { workspace = true } hex = { workspace = true, optional = true } diff --git a/interop_binaries/src/commands/janus_interop_client.rs b/interop_binaries/src/commands/janus_interop_client.rs index 7d5fb6371..5a1d29399 100644 --- a/interop_binaries/src/commands/janus_interop_client.rs +++ b/interop_binaries/src/commands/janus_interop_client.rs @@ -6,7 +6,7 @@ use crate::{ use anyhow::Context; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; use clap::Parser; -use derivative::Derivative; +use educe::Educe; #[cfg(feature = "fpvec_bounded_l2")] use fixed::{ types::extra::{U15, U31}, @@ -54,13 +54,13 @@ where ) } -#[derive(Derivative, Deserialize)] -#[derivative(Debug)] +#[derive(Educe, Deserialize)] +#[educe(Debug)] struct UploadRequest { task_id: String, - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] leader: Url, - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] helper: Url, vdaf: VdafObject, measurement: serde_json::Value, diff --git a/interop_binaries/src/commands/janus_interop_collector.rs b/interop_binaries/src/commands/janus_interop_collector.rs index edc0dcef4..941501a81 100644 --- a/interop_binaries/src/commands/janus_interop_collector.rs +++ b/interop_binaries/src/commands/janus_interop_collector.rs @@ -7,7 +7,7 @@ use anyhow::Context; use backoff::ExponentialBackoffBuilder; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; use clap::Parser; -use derivative::Derivative; +use educe::Educe; #[cfg(feature = "fpvec_bounded_l2")] use fixed::types::extra::{U15, U31}; #[cfg(feature = "fpvec_bounded_l2")] @@ -42,11 +42,11 @@ use trillium::{Conn, Handler}; use trillium_api::{api, Json, State}; use trillium_router::Router; -#[derive(Derivative, Deserialize)] -#[derivative(Debug)] +#[derive(Educe, Deserialize)] +#[educe(Debug)] struct AddTaskRequest { task_id: String, - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] leader: Url, vdaf: VdafObject, collector_authentication_token: String, diff --git a/interop_binaries/src/lib.rs b/interop_binaries/src/lib.rs index 34a60083a..87388afe0 100644 --- a/interop_binaries/src/lib.rs +++ b/interop_binaries/src/lib.rs @@ -1,5 +1,5 @@ use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; -use derivative::Derivative; +use educe::Educe; use janus_aggregator_core::task::{test_util::Task, BatchMode}; #[cfg(feature = "fpvec_bounded_l2")] use janus_core::vdaf::Prio3FixedPointBoundedL2VecSumBitSize; @@ -281,13 +281,13 @@ impl From for Role { } } -#[derive(Derivative, Serialize, Deserialize)] -#[derivative(Debug)] +#[derive(Educe, Serialize, Deserialize)] +#[educe(Debug)] pub struct AggregatorAddTaskRequest { pub task_id: TaskId, // uses unpadded base64url - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub leader: Url, - #[derivative(Debug(format_with = "std::fmt::Display::fmt"))] + #[educe(Debug(method(std::fmt::Display::fmt)))] pub helper: Url, pub vdaf: VdafObject, pub leader_authentication_token: String, diff --git a/messages/Cargo.toml b/messages/Cargo.toml index c72becc5f..403cb0e73 100644 --- a/messages/Cargo.toml +++ b/messages/Cargo.toml @@ -15,7 +15,7 @@ test-util = [] [dependencies] anyhow.workspace = true base64.workspace = true -derivative.workspace = true +educe.workspace = true hex = { workspace = true } num_enum = { workspace = true } # Make sure not to enable default-features on prio, as we want clients to be diff --git a/messages/src/lib.rs b/messages/src/lib.rs index a7ed9157f..fd873225b 100644 --- a/messages/src/lib.rs +++ b/messages/src/lib.rs @@ -7,7 +7,7 @@ use self::batch_mode::{BatchMode, LeaderSelected, TimeInterval}; use anyhow::anyhow; use base64::{display::Base64Display, engine::general_purpose::URL_SAFE_NO_PAD, Engine}; use core::slice; -use derivative::Derivative; +use educe::Educe; use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive}; use prio::{ codec::{ @@ -951,16 +951,16 @@ impl Decode for ExtensionType { } /// DAP protocol message representing an HPKE ciphertext. -#[derive(Clone, Derivative, Eq, PartialEq)] -#[derivative(Debug)] +#[derive(Clone, Educe, Eq, PartialEq)] +#[educe(Debug)] pub struct HpkeCiphertext { /// An identifier of the HPKE configuration used to seal the message. config_id: HpkeConfigId, /// An encapsulated HPKE key. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] encapsulated_key: Vec, /// An HPKE ciphertext. - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] payload: Vec, } @@ -1525,11 +1525,11 @@ impl Decode for Query { /// DAP protocol message representing a request from the collector to the leader to provide /// aggregate shares for a given batch. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub struct CollectionReq { query: Query, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_parameter: Vec, } @@ -1933,11 +1933,11 @@ impl Decode for AggregateShareAad { } /// DAP protocol message representing one aggregator's share of a single client report. -#[derive(Derivative, Clone, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Educe, Clone, PartialEq, Eq)] +#[educe(Debug)] pub struct ReportShare { metadata: ReportMetadata, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] public_share: Vec, encrypted_input_share: HpkeCiphertext, } @@ -2102,11 +2102,11 @@ impl Decode for PrepareResp { /// DAP protocol message representing result-type-specific data associated with a preparation step /// in a VDAF evaluation. Included in a PrepareResp message. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub enum PrepareStepResult { Continue { - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] message: PingPongMessage, }, Finished, @@ -2302,10 +2302,10 @@ impl Distribution for Standard { /// DAP protocol message representing an aggregation job initialization request from leader to /// helper. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub struct AggregationJobInitializeReq { - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_parameter: Vec, partial_batch_selector: PartialBatchSelector, prepare_inits: Vec, @@ -2605,11 +2605,11 @@ impl Decode for BatchSelector { /// DAP protocol message representing a request from the leader to a helper to provide an /// encrypted aggregate of its share of data for a given batch interval. -#[derive(Clone, Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, Educe, PartialEq, Eq)] +#[educe(Debug)] pub struct AggregateShareReq { batch_selector: BatchSelector, - #[derivative(Debug = "ignore")] + #[educe(Debug(ignore))] aggregation_parameter: Vec, report_count: u64, checksum: ReportIdChecksum, diff --git a/messages/src/taskprov.rs b/messages/src/taskprov.rs index cec6ac801..181dab233 100644 --- a/messages/src/taskprov.rs +++ b/messages/src/taskprov.rs @@ -4,7 +4,6 @@ use crate::{Duration, Error, Time, Url}; use anyhow::anyhow; -use derivative::Derivative; use prio::codec::{ decode_u16_items, decode_u8_items, encode_u16_items, encode_u8_items, CodecError, Decode, Encode, @@ -288,8 +287,7 @@ impl Decode for VdafConfig { } } -#[derive(Clone, PartialEq, Eq, Derivative)] -#[derivative(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] #[repr(u32)] #[non_exhaustive] pub enum VdafType { diff --git a/tools/Cargo.toml b/tools/Cargo.toml index b9c22517f..9440031c1 100644 --- a/tools/Cargo.toml +++ b/tools/Cargo.toml @@ -15,7 +15,6 @@ fpvec_bounded_l2 = ["dep:fixed", "janus_collector/fpvec_bounded_l2", "prio/exper anyhow = { workspace = true } base64.workspace = true clap.workspace = true -derivative.workspace = true fixed = { workspace = true, optional = true } janus_collector.workspace = true janus_core.workspace = true