Skip to content

Commit

Permalink
fix: supported chains as enum and returning an updated attributes list
Browse files Browse the repository at this point in the history
  • Loading branch information
geekbrother committed Feb 9, 2024
1 parent 03b2468 commit 2d962a6
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 37 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ serde_json = "1.0"
serde_piecewise_default = "0.2"
serde-aux = "3.1"
validator = { version = "0.16", features = ["derive"] }
num_enum = "0.7"

# Storage
aws-config = "0.56"
Expand Down
7 changes: 4 additions & 3 deletions integration/names.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ describe('Account profile names', () => {

it('update name attributes', async () => {
// Prepare updated attributes payload
const randomBioString = Array.from({ length: 24 },
() => (Math.random().toString(36)[2] || '0')).join('')
const updatedAttributes = {
bio: 'integration test domain updated attribute',
bio: randomBioString,
};
const updateAttributesMessageObject = {
attributes: updatedAttributes,
Expand All @@ -152,7 +154,6 @@ describe('Account profile names', () => {
);

expect(resp.status).toBe(200)
expect(resp.data.name).toBe(name)
expect(resp.data.attributes['bio']).toBe(updatedAttributes['bio'])
expect(resp.data['bio']).toBe(updatedAttributes['bio'])
})
})
24 changes: 17 additions & 7 deletions src/database/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,27 @@ pub async fn update_name_attributes(
name: String,
attributes: HashMap<String, String>,
postgres: &PgPool,
) -> Result<sqlx::postgres::PgQueryResult, sqlx::error::Error> {
let insert_name_query = "
) -> Result<HashMap<String, String>, sqlx::error::Error> {
let update_attributes_query = "
UPDATE names SET attributes = $2::hstore, updated_at = NOW()
WHERE name = $1
WHERE name = $1
RETURNING attributes::json
";
sqlx::query::<Postgres>(insert_name_query)
let result: (serde_json::Value,) = sqlx::query_as(update_attributes_query)
.bind(&name)
// Convert JSON to String for hstore update
.bind(&utils::hashmap_to_hstore(&attributes))
.execute(postgres)
.await
.fetch_one(postgres)
.await?;

let updated_attributes_result: Result<HashMap<String, String>, sqlx::Error> =
serde_json::from_value(result.0.clone()).map_err(|e| {
sqlx::Error::Protocol(format!(
"Failed to convert serde_json::Value to HashMap<String, String>: {}",
e
))
});

updated_attributes_result
}

#[instrument(skip(postgres))]
Expand Down
40 changes: 15 additions & 25 deletions src/handlers/profile/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use {
super::{
super::HANDLER_TASK_METRICS,
utils::{check_attributes, is_timestamp_within_interval},
Eip155SupportedChains,
RegisterRequest,
UpdateAttributesPayload,
UNIXTIMESTAMP_SYNC_THRESHOLD,
Expand All @@ -18,7 +19,7 @@ use {
Json,
},
hyper::StatusCode,
sqlx::Error as SqlxError,
num_enum::TryFromPrimitive,
std::{str::FromStr, sync::Arc},
tracing::log::{error, info},
wc::future::FutureExt,
Expand All @@ -44,17 +45,17 @@ pub async fn handler_internal(
let payload = match serde_json::from_str::<UpdateAttributesPayload>(raw_payload) {
Ok(payload) => payload,
Err(e) => {
info!("Failed to deserialize register payload: {}", e);
info!("Failed to deserialize update attributes payload: {}", e);
return Ok((StatusCode::BAD_REQUEST, "").into_response());
}
};

// Check for the supported ENSIP-11 coin type
if request_payload.coin_type != 60 {
if Eip155SupportedChains::try_from_primitive(request_payload.coin_type).is_err() {
info!("Unsupported coin type {}", request_payload.coin_type);
return Ok((
StatusCode::BAD_REQUEST,
"Only Ethereum Mainnet (60) coin type is supported for name registration",
"Unsupported coin type for name attributes update",
)
.into_response());
}
Expand Down Expand Up @@ -107,7 +108,10 @@ pub async fn handler_internal(
}

// Check for the name address ownership and address from the signed payload
let name_owner = match name_addresses.addresses.get(&60) {
let name_owner = match name_addresses
.addresses
.get(&Eip155SupportedChains::Mainnet.into())
{
Some(address_entry) => match ethers::types::H160::from_str(&address_entry.address) {
Ok(owner) => owner,
Err(e) => {
Expand Down Expand Up @@ -146,25 +150,11 @@ pub async fn handler_internal(
.into_response());
}

let update_attributes_result =
update_name_attributes(name.clone(), payload.attributes, &state.postgres).await;
if let Err(e) = update_attributes_result {
error!("Failed to update attributes: {}", e);
return Ok((StatusCode::INTERNAL_SERVER_ERROR, "").into_response());
}

// Return the registered name, addresses and attributes
match get_name_and_addresses_by_name(name, &state.postgres.clone()).await {
Ok(response) => Ok(Json(response).into_response()),
Err(e) => match e {
SqlxError::RowNotFound => {
error!("New registered name is not found in the database: {}", e);
Ok((StatusCode::INTERNAL_SERVER_ERROR, "Name is not registered").into_response())
}
_ => {
error!("Error on lookup new registered name: {}", e);
Ok((StatusCode::INTERNAL_SERVER_ERROR, "Name is not registered").into_response())
}
},
match update_name_attributes(name.clone(), payload.attributes, &state.postgres).await {
Err(e) => {
error!("Failed to update attributes: {}", e);
Ok((StatusCode::INTERNAL_SERVER_ERROR, "").into_response())
}
Ok(attributes) => Ok(Json(attributes).into_response()),
}
}
8 changes: 8 additions & 0 deletions src/handlers/profile/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use {
num_enum::{IntoPrimitive, TryFromPrimitive},
once_cell::sync::Lazy,
regex::Regex,
serde::{Deserialize, Serialize},
Expand All @@ -11,6 +12,13 @@ pub mod register;
pub mod reverse;
pub mod utils;

/// List of supported Ethereum chains in ENSIP-11 format
#[repr(u32)]
#[derive(Debug, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
enum Eip155SupportedChains {
Mainnet = 60,
}

pub const UNIXTIMESTAMP_SYNC_THRESHOLD: u64 = 10;

/// Attributes value max length
Expand Down
6 changes: 4 additions & 2 deletions src/handlers/profile/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use {
super::{
super::HANDLER_TASK_METRICS,
utils::{check_attributes, is_timestamp_within_interval},
Eip155SupportedChains,
RegisterPayload,
RegisterRequest,
UNIXTIMESTAMP_SYNC_THRESHOLD,
Expand All @@ -21,6 +22,7 @@ use {
Json,
},
hyper::StatusCode,
num_enum::TryFromPrimitive,
sqlx::Error as SqlxError,
std::{collections::HashMap, str::FromStr, sync::Arc},
tracing::log::{error, info},
Expand Down Expand Up @@ -51,11 +53,11 @@ pub async fn handler_internal(
};

// Check for the supported ENSIP-11 coin type
if register_request.coin_type != 60 {
if Eip155SupportedChains::try_from_primitive(register_request.coin_type).is_err() {
info!("Unsupported coin type {}", register_request.coin_type);
return Ok((
StatusCode::BAD_REQUEST,
"Only Ethereum Mainnet (60) coin type is supported for name registration",
"Unsupported coin type for name registration",
)
.into_response());
}
Expand Down

0 comments on commit 2d962a6

Please sign in to comment.