feat: Add cryptography-related statistics (#8293)

This adds `number_of_transports`, `key_version`, `key_algorithm`,
`pubkey_size`.
This commit is contained in:
Hocuri
2026-06-02 10:26:53 +02:00
committed by GitHub
parent 4a94a34c6d
commit 50e83f2072
2 changed files with 45 additions and 6 deletions

View File

@@ -18,7 +18,7 @@ use crate::config::Config;
use crate::constants::{Chattype, DC_VERSION_STR};
use crate::contact::{Contact, ContactId, Origin, import_vcard, mark_contact_id_as_verified};
use crate::context::Context;
use crate::key::load_self_public_keyring;
use crate::key::{DcKey, load_self_public_key};
use crate::log::LogExt;
use crate::message::{Message, Viewtype};
use crate::securejoin::QrInvite;
@@ -33,7 +33,13 @@ const MESSAGE_STATS_UPDATE_INTERVAL_SECONDS: i64 = 4 * 60; // 4 minutes (less th
#[derive(Serialize)]
struct Statistics {
core_version: String,
number_of_transports: usize,
key_create_timestamps: Vec<u32>,
/// OpenPGP version of the key.
key_version: u8,
key_algorithm: String,
/// Size of the public key in bytes (encoded in binary, not base64).
pubkey_size: usize,
stats_id: String,
is_chatmail: bool,
contact_stats: Vec<ContactStat>,
@@ -345,11 +351,10 @@ async fn get_stats(context: &Context) -> Result<String> {
.get_config_u32(Config::StatsLastOldContactId)
.await?;
let key_create_timestamps: Vec<u32> = load_self_public_keyring(context)
.await?
.iter()
.map(|k| k.created_at().as_secs())
.collect();
let self_public_key = load_self_public_key(context).await?;
// `key_create_timestamps` is a `Vec` for historical reasons,
// support for using multiple keys is being phased out.
let key_create_timestamps: Vec<u32> = vec![self_public_key.created_at().as_secs()];
let sending_enabled_timestamps =
get_timestamps(context, "stats_sending_enabled_events").await?;
@@ -358,7 +363,11 @@ async fn get_stats(context: &Context) -> Result<String> {
let stats = Statistics {
core_version: DC_VERSION_STR.to_string(),
number_of_transports: context.count_transports().await?,
key_create_timestamps,
key_version: self_public_key.primary_key.version().into(),
key_algorithm: format!("{:?}", self_public_key.algorithm()),
pubkey_size: DcKey::to_bytes(&self_public_key).len(),
stats_id: stats_id(context).await?,
is_chatmail: context.is_chatmail().await?,
contact_stats: get_contact_stats(context, last_old_contact).await?,

View File

@@ -595,3 +595,33 @@ async fn test_stats_enable_disable_timestamps() -> Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_cryptography_stats() -> Result<()> {
let alice = &TestContext::new_alice().await;
let stats = get_stats(alice).await.unwrap();
let stats: serde_json::Value = serde_json::from_str(&stats)?;
let number_of_transports: u64 = stats.get("number_of_transports").unwrap().as_u64().unwrap();
assert_eq!(number_of_transports, 1);
let key_version = stats.get("key_version").unwrap().as_u64().unwrap();
// Alice's key is v4
assert_eq!(key_version, 4);
let key_algorithm = stats.get("key_algorithm").unwrap().as_str().unwrap();
assert_eq!(key_algorithm, "EdDSALegacy");
let pubkey_size = stats.get("pubkey_size").unwrap().as_u64().unwrap();
assert_eq!(pubkey_size, 583);
crate::transport::add_pseudo_transport(alice, "alice@ten.testrun.org").await?;
let stats = get_stats(alice).await.unwrap();
let stats: serde_json::Value = serde_json::from_str(&stats)?;
let number_of_transports: u64 = stats.get("number_of_transports").unwrap().as_u64().unwrap();
assert_eq!(number_of_transports, 2);
Ok(())
}