Skip to content

Commit

Permalink
fix: properly encode/decode started_at_ms in QueryTrace object (#1591)
Browse files Browse the repository at this point in the history
  • Loading branch information
KolbyML authored Nov 27, 2024
1 parent 3013310 commit f03fe8b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
39 changes: 34 additions & 5 deletions ethportal-api/src/types/query_trace.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::{collections::HashMap, time::SystemTime};
use std::{
collections::HashMap,
time::{Duration, SystemTime, UNIX_EPOCH},
};

use alloy::primitives::B256;
use discv5::enr::NodeId;
Expand Down Expand Up @@ -26,7 +29,7 @@ pub struct QueryTrace {
/// Contains a map from node ID to the metadata object for that node.
pub metadata: HashMap<NodeId, NodeInfo>,
/// Timestamp when the query was started.
pub started_at_ms: SystemTime,
pub started_at_ms: u64,
/// Target content ID
pub target_id: ContentId,
/// List of pending requests that were unresolved when the content was found.
Expand All @@ -35,13 +38,21 @@ pub struct QueryTrace {

impl QueryTrace {
pub fn new(local_enr: &Enr, target_id: ContentId) -> Self {
let started_at_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis();

// Convert to u64, as JSON serialization does not support u128.
let started_at_ms = u64::try_from(started_at_ms).unwrap_or(u64::MAX);

QueryTrace {
received_from: None,
origin: local_enr.into(),
responses: HashMap::new(),
failures: HashMap::new(),
metadata: HashMap::new(),
started_at_ms: SystemTime::now(),
started_at_ms,
cancelled: Vec::new(),
target_id,
}
Expand Down Expand Up @@ -112,11 +123,15 @@ impl QueryTrace {
}

/// Returns milliseconds since the time provided.
fn timestamp_millis_u64(since: SystemTime) -> u64 {
fn timestamp_millis_u64(since: u64) -> u64 {
// Convert `since` (milliseconds) to a `SystemTime`
let since_time = UNIX_EPOCH + Duration::from_millis(since);

let timestamp_millis_u128 = SystemTime::now()
.duration_since(since)
.duration_since(since_time)
.unwrap_or_default()
.as_millis();

// JSON serialization does not support u128. u64 can hold a few million years worth of
// milliseconds.
u64::try_from(timestamp_millis_u128).unwrap_or(u64::MAX)
Expand Down Expand Up @@ -367,4 +382,18 @@ mod tests {
"0x0000000000000000000000000000000000000000000000000000000000223765"
);
}

#[rstest::rstest]
#[case(5)]
#[case(534543)]
#[case(64574556345)]
#[case(5435345345)]
fn test_started_at_ms_time_is_serialized_to_json_properly(#[case] number: u64) {
let (_, local_enr) = generate_random_remote_enr();
let target_id = B256::ZERO;
let mut tracer = QueryTrace::new(&local_enr, target_id);
tracer.started_at_ms = number;
let json_tracer: Value = json!(&tracer);
assert_eq!(json_tracer["startedAtMs"], number);
}
}
8 changes: 6 additions & 2 deletions ethportal-peertest/src/scenarios/find.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::time::SystemTime;
use std::time::{SystemTime, UNIX_EPOCH};

use discv5::enr::NodeId;
use jsonrpsee::async_client::Client;
Expand Down Expand Up @@ -94,7 +94,11 @@ pub async fn test_trace_get_content(peertest: &Peertest) {

assert!(store_result);

let query_start_time = SystemTime::now();
let query_start_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64;

let trace_content_info = HistoryNetworkApiClient::trace_get_content(
&peertest.nodes[0].ipc_client,
content_key.clone(),
Expand Down

0 comments on commit f03fe8b

Please sign in to comment.