Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BENS] Perform to_checksum to response addresses #833

Merged
merged 3 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 40 additions & 21 deletions blockscout-ens/bens-server/src/conversion/domain.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::ConversionError;
use super::{address_from_str_logic, checksummed, ConversionError};
use crate::conversion::order_direction_from_inner;
use bens_logic::{
entity::subgraph::domain::Domain,
Expand All @@ -9,7 +9,7 @@ use bens_logic::{
};
use bens_proto::blockscout::bens::v1 as proto;
use ethers::types::Address;
use std::str::FromStr;
use std::{collections::BTreeMap, str::FromStr};

const DEFAULT_PAGE_SIZE: u32 = 50;

Expand Down Expand Up @@ -87,26 +87,43 @@ pub fn batch_resolve_from_inner(
})
}

pub fn batch_resolve_from_logic(
output: BTreeMap<String, String>,
chain_id: i64,
) -> Result<proto::BatchResolveAddressNamesResponse, ConversionError> {
let names = output
.into_iter()
.map(|(address, name)| {
let address = address_from_str_logic(&address, chain_id)?.hash;
Ok((address, name))
})
.collect::<Result<_, _>>()?;
Ok(proto::BatchResolveAddressNamesResponse { names })
}

pub fn detailed_domain_from_logic(
output: GetDomainOutput,
chain_id: i64,
) -> Result<proto::DetailedDomain, ConversionError> {
let domain = output.domain;
let owner = Some(proto::Address { hash: domain.owner });
let owner = Some(address_from_str_logic(&domain.owner, chain_id)?);
let resolved_address = domain
.resolved_address
.map(|resolved_address| proto::Address {
hash: resolved_address,
});
let wrapped_owner = domain.wrapped_owner.map(|wrapped_owner| proto::Address {
hash: wrapped_owner,
});
.map(|resolved_address| address_from_str_logic(&resolved_address, chain_id))
.transpose()?;

let wrapped_owner = domain
.wrapped_owner
.map(|wrapped_owner| address_from_str_logic(&wrapped_owner, chain_id))
.transpose()?;
let registrant = domain
.registrant
.map(|registrant| proto::Address { hash: registrant });
.map(|registrant| address_from_str_logic(&registrant, chain_id))
.transpose()?;
let tokens = output
.tokens
.into_iter()
.map(domain_token_from_logic)
.map(|t| domain_token_from_logic(t, chain_id))
.collect();
Ok(proto::DetailedDomain {
id: domain.id,
Expand All @@ -122,14 +139,16 @@ pub fn detailed_domain_from_logic(
})
}

pub fn domain_from_logic(d: Domain) -> Result<proto::Domain, ConversionError> {
let owner = Some(proto::Address { hash: d.owner });
let resolved_address = d.resolved_address.map(|resolved_address| proto::Address {
hash: resolved_address,
});
let wrapped_owner = d.wrapped_owner.map(|wrapped_owner| proto::Address {
hash: wrapped_owner,
});
pub fn domain_from_logic(d: Domain, chain_id: i64) -> Result<proto::Domain, ConversionError> {
let owner = Some(address_from_str_logic(&d.owner, chain_id)?);
let resolved_address = d
.resolved_address
.map(|resolved_address| address_from_str_logic(&resolved_address, chain_id))
.transpose()?;
let wrapped_owner = d
.wrapped_owner
.map(|wrapped_owner| address_from_str_logic(&wrapped_owner, chain_id))
.transpose()?;
Ok(proto::Domain {
id: d.id,
name: d.name.unwrap_or_default(),
Expand Down Expand Up @@ -174,10 +193,10 @@ fn date_from_logic(d: chrono::DateTime<chrono::Utc>) -> String {
d.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)
}

fn domain_token_from_logic(t: DomainToken) -> proto::Token {
fn domain_token_from_logic(t: DomainToken, chain_id: i64) -> proto::Token {
proto::Token {
id: t.id,
contract_hash: format!("{:#x}", t.contract),
contract_hash: checksummed(&t.contract, chain_id),
r#type: domain_token_type_from_logic(t._type).into(),
}
}
Expand Down
13 changes: 7 additions & 6 deletions blockscout-ens/bens-server/src/conversion/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bens_logic::{
};
use bens_proto::blockscout::bens::v1 as proto;

use super::{order_direction_from_inner, ConversionError};
use super::{address_from_logic, order_direction_from_inner, ConversionError};

pub fn list_domain_events_from_inner(
inner: proto::ListDomainEventsRequest,
Expand All @@ -20,10 +20,11 @@ pub fn list_domain_events_from_inner(
})
}

pub fn event_from_logic(e: DomainEvent) -> Result<proto::DomainEvent, ConversionError> {
let from_address = Some(proto::Address {
hash: hex(e.from_address),
});
pub fn event_from_logic(
e: DomainEvent,
chain_id: i64,
) -> Result<proto::DomainEvent, ConversionError> {
let from_address = Some(address_from_logic(&e.from_address, chain_id));
Ok(proto::DomainEvent {
transaction_hash: hex(e.transaction_hash),
timestamp: e.timestamp,
Expand All @@ -36,7 +37,7 @@ pub fn event_sort_from_inner(inner: &str) -> Result<EventSort, ConversionError>
match inner {
"" | "timestamp" => Ok(EventSort::BlockNumber),
_ => Err(ConversionError::UserRequest(format!(
"unknow sort field '{inner}'"
"unknown sort field '{inner}'"
))),
}
}
42 changes: 35 additions & 7 deletions blockscout-ens/bens-server/src/conversion/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use bens_logic::subgraphs_reader::Order;
use bens_proto::blockscout::bens::v1 as proto;
use ethers::{addressbook::Address, utils::to_checksum};
use std::str::FromStr;
use thiserror::Error;

mod domain;
Expand All @@ -8,6 +10,16 @@ mod events;
pub use domain::*;
pub use events::*;

#[derive(Error, Debug)]
pub enum ConversionError {
#[error("invalid argument: {0}")]
UserRequest(String),
#[error("internal error: {0}")]
#[allow(dead_code)]
LogicOutput(String),
}

#[inline]
pub fn order_direction_from_inner(inner: proto::Order) -> Order {
match inner {
proto::Order::Unspecified => Order::Desc,
Expand All @@ -16,11 +28,27 @@ pub fn order_direction_from_inner(inner: proto::Order) -> Order {
}
}

#[derive(Error, Debug)]
pub enum ConversionError {
#[error("invalid argument: {0}")]
UserRequest(String),
#[error("internal error: {0}")]
#[allow(dead_code)]
LogicOutput(String),
#[inline]
pub fn checksummed(address: &Address, chain_id: i64) -> String {
match chain_id {
30 | 31 => to_checksum(address, Some(chain_id as u8)),
_ => to_checksum(address, None),
}
}

#[inline]
pub fn address_from_logic(address: &Address, chain_id: i64) -> proto::Address {
proto::Address {
hash: checksummed(address, chain_id),
}
}

#[inline]
pub fn address_from_str_logic(
addr: &str,
chain_id: i64,
) -> Result<proto::Address, ConversionError> {
let addr = Address::from_str(addr)
.map_err(|e| ConversionError::LogicOutput(format!("invalid address '{addr}': {e}")))?;
Ok(address_from_logic(&addr, chain_id))
}
31 changes: 20 additions & 11 deletions blockscout-ens/bens-server/src/services/domain_extractor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::conversion::{self, batch_resolve_from_inner, pagination_from_logic, ConversionError};
use crate::conversion::{
self, batch_resolve_from_inner, batch_resolve_from_logic, pagination_from_logic,
ConversionError,
};
use async_trait::async_trait;
use bens_logic::{
entity,
Expand Down Expand Up @@ -29,14 +32,15 @@ impl DomainsExtractor for DomainsExtractorService {
request: tonic::Request<GetDomainRequest>,
) -> Result<tonic::Response<DetailedDomain>, tonic::Status> {
let request = request.into_inner();
let chain_id = request.chain_id;
let input =
conversion::get_domain_input_from_inner(request).map_err(map_convertion_error)?;
let domain = self
.subgraph_reader
.get_domain(input)
.await
.map_err(map_subgraph_error)?
.map(conversion::detailed_domain_from_logic)
.map(|d| conversion::detailed_domain_from_logic(d, chain_id))
.transpose()
.map_err(map_convertion_error)?
.ok_or_else(|| tonic::Status::not_found("domain not found"))?;
Expand All @@ -48,6 +52,7 @@ impl DomainsExtractor for DomainsExtractorService {
request: tonic::Request<ListDomainEventsRequest>,
) -> Result<tonic::Response<ListDomainEventsResponse>, tonic::Status> {
let request = request.into_inner();
let chain_id = request.chain_id;
let input =
conversion::list_domain_events_from_inner(request).map_err(map_convertion_error)?;
let items: Vec<DomainEvent> = self
Expand All @@ -56,7 +61,7 @@ impl DomainsExtractor for DomainsExtractorService {
.await
.map_err(map_subgraph_error)?
.into_iter()
.map(conversion::event_from_logic)
.map(|e| conversion::event_from_logic(e, chain_id))
.collect::<Result<_, _>>()
.map_err(map_convertion_error)?;
let response = ListDomainEventsResponse { items };
Expand All @@ -68,6 +73,7 @@ impl DomainsExtractor for DomainsExtractorService {
request: tonic::Request<LookupDomainNameRequest>,
) -> Result<tonic::Response<LookupDomainNameResponse>, tonic::Status> {
let request = request.into_inner();
let chain_id = request.chain_id;
let input =
conversion::lookup_domain_name_from_inner(request).map_err(map_convertion_error)?;
let page_size = input.pagination.page_size;
Expand All @@ -76,7 +82,7 @@ impl DomainsExtractor for DomainsExtractorService {
.lookup_domain_name(input)
.await
.map_err(map_subgraph_error)?;
let domains = from_resolved_domains_result(result.items)?;
let domains = from_resolved_domains_result(result.items, chain_id)?;
let response = LookupDomainNameResponse {
items: domains,
next_page_params: pagination_from_logic(result.next_page_token, page_size),
Expand All @@ -89,14 +95,15 @@ impl DomainsExtractor for DomainsExtractorService {
request: tonic::Request<LookupAddressRequest>,
) -> Result<tonic::Response<LookupAddressResponse>, tonic::Status> {
let request = request.into_inner();
let chain_id = request.chain_id;
let input = conversion::lookup_address_from_inner(request).map_err(map_convertion_error)?;
let page_size = input.pagination.page_size;
let result = self
.subgraph_reader
.lookup_address(input)
.await
.map_err(map_subgraph_error)?;
let items = from_resolved_domains_result(result.items)?;
let items = from_resolved_domains_result(result.items, chain_id)?;
let response = LookupAddressResponse {
items,
next_page_params: pagination_from_logic(result.next_page_token, page_size),
Expand All @@ -109,22 +116,22 @@ impl DomainsExtractor for DomainsExtractorService {
request: tonic::Request<GetAddressRequest>,
) -> Result<tonic::Response<GetAddressResponse>, tonic::Status> {
let request = request.into_inner();
let network_id = request.chain_id;
let chain_id = request.chain_id;
let address =
conversion::address_from_str_inner(&request.address).map_err(map_convertion_error)?;

let domain = self
.subgraph_reader
.get_address(network_id, address)
.get_address(chain_id, address)
.await
.map_err(map_subgraph_error)?
.map(conversion::detailed_domain_from_logic)
.map(|d| conversion::detailed_domain_from_logic(d, chain_id))
.transpose()
.map_err(map_convertion_error)?;

let resolved_domains_count = self
.subgraph_reader
.count_domains_by_address(network_id, address, true, false)
.count_domains_by_address(chain_id, address, true, false)
.await
.map_err(map_subgraph_error)? as i32;
Ok(tonic::Response::new(GetAddressResponse {
Expand All @@ -138,13 +145,14 @@ impl DomainsExtractor for DomainsExtractorService {
request: tonic::Request<BatchResolveAddressNamesRequest>,
) -> Result<tonic::Response<BatchResolveAddressNamesResponse>, tonic::Status> {
let request = request.into_inner();
let chain_id = request.chain_id;
let input = batch_resolve_from_inner(request).map_err(map_convertion_error)?;
let names = self
.subgraph_reader
.batch_resolve_address_names(input)
.await
.map_err(map_subgraph_error)?;
let response = BatchResolveAddressNamesResponse { names };
let response = batch_resolve_from_logic(names, chain_id).map_err(map_convertion_error)?;
Ok(tonic::Response::new(response))
}
}
Expand All @@ -170,10 +178,11 @@ fn map_convertion_error(err: ConversionError) -> tonic::Status {

fn from_resolved_domains_result(
result: impl IntoIterator<Item = entity::subgraph::domain::Domain>,
chain_id: i64,
) -> Result<Vec<Domain>, tonic::Status> {
result
.into_iter()
.map(conversion::domain_from_logic)
.map(|d| conversion::domain_from_logic(d, chain_id))
.collect::<Result<_, _>>()
.map_err(map_convertion_error)
}
Loading
Loading