Skip to content

Commit

Permalink
feat(ens): adding timestamp threshold check (#491)
Browse files Browse the repository at this point in the history
  • Loading branch information
geekbrother authored Jan 25, 2024
1 parent 50437c4 commit 58bed27
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
2 changes: 1 addition & 1 deletion integration/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ describe('blockchain api', () => {
const messageObject = {
name,
address,
timestamp: Date.now()
timestamp: Math.round(Date.now() / 1000)
};
const message = JSON.stringify(messageObject);

Expand Down
52 changes: 51 additions & 1 deletion src/handlers/profile/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
use {
ethers::types::H160,
serde::{Deserialize, Serialize},
std::str::FromStr,
std::{
str::FromStr,
time::{SystemTime, UNIX_EPOCH},
},
tap::TapFallible,
};

pub mod lookup;
pub mod register;
pub mod reverse;

pub const UNIXTIMESTAMP_SYNC_THRESHOLD: u64 = 10;

/// Payload to register domain name that should be serialized to JSON
/// and passed to the RegisterRequest.message
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
Expand Down Expand Up @@ -47,6 +53,19 @@ pub fn verify_message_signature(
}
}

/// Check if the given unixtimestamp is within the threshold interval relative
/// to the current time
#[tracing::instrument(level = "debug")]
pub fn is_timestamp_within_interval(unix_timestamp: u64, threshold_interval: u64) -> bool {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.tap_err(|_| tracing::error!("SystemTime before UNIX EPOCH!"))
.unwrap_or_default()
.as_secs();

unix_timestamp >= (now - threshold_interval) && unix_timestamp <= (now + threshold_interval)
}

#[cfg(test)]
mod tests {
use {super::*, ethers::types::H160, std::str::FromStr};
Expand Down Expand Up @@ -84,4 +103,35 @@ mod tests {
assert!(result.is_ok());
assert!(!result.unwrap());
}

#[test]
fn test_verify_is_timestamp_within_interval_valid() {
let threshold_interval = 10;
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.tap_err(|_| tracing::error!("SystemTime before UNIX EPOCH!"))
.unwrap_or_default()
.as_secs();
assert!(is_timestamp_within_interval(now, threshold_interval));
}

#[test]
fn test_verify_is_timestamp_within_interval_invalid() {
let threshold_interval = 10;
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.tap_err(|_| tracing::error!("SystemTime before UNIX EPOCH!"))
.unwrap_or_default()
.as_secs();
// Upper bound reached
assert!(!is_timestamp_within_interval(
now + threshold_interval + 1,
threshold_interval
));
// Lower bound reached
assert!(!is_timestamp_within_interval(
now - threshold_interval - 1,
threshold_interval
));
}
}
11 changes: 10 additions & 1 deletion src/handlers/profile/register.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use {
super::{
super::HANDLER_TASK_METRICS,
is_timestamp_within_interval,
verify_message_signature,
RegisterPayload,
RegisterRequest,
UNIXTIMESTAMP_SYNC_THRESHOLD,
},
crate::{
database::{
Expand Down Expand Up @@ -85,7 +87,14 @@ pub async fn handler_internal(
return Ok((StatusCode::BAD_REQUEST, "Name is already registered").into_response());
};

// TODO: Check the timestamp within 5-10 minutes ttl
// Check the timestamp is within the sync threshold interval
if !is_timestamp_within_interval(payload.timestamp, UNIXTIMESTAMP_SYNC_THRESHOLD) {
return Ok((
StatusCode::BAD_REQUEST,
"Timestamp is too old or in the future",
)
.into_response());
}

let owner = match ethers::types::H160::from_str(&register_request.address) {
Ok(owner) => owner,
Expand Down

0 comments on commit 58bed27

Please sign in to comment.