Skip to content

Commit

Permalink
feat: add quick search for dapps
Browse files Browse the repository at this point in the history
  • Loading branch information
lok52 committed Dec 12, 2024
1 parent d069312 commit 3a62e6a
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 43 deletions.
10 changes: 8 additions & 2 deletions multichain-aggregator/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 multichain-aggregator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ pretty_assertions = "1.3"
regex = "1.10"
reqwest = "0.12"
thiserror = "1.0"
url = { version = "2.4" }
4 changes: 4 additions & 0 deletions multichain-aggregator/multichain-aggregator-logic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ tracing = { workspace = true }
sea-orm = { workspace = true }
alloy-primitives = { workspace = true }
regex = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tonic = { workspace = true }
tokio = { workspace = true }
reqwest = { workspace = true }
url = { workspace = true }

[dev-dependencies]
blockscout-service-launcher = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use crate::error::ServiceError;
use serde::Deserialize;
use url::Url;

pub struct DappClient {
http: reqwest::Client,
url: Url,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Dapp {
pub id: String,
pub title: String,
pub logo: String,
pub short_description: String,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DappWithChainId {
pub dapp: Dapp,
pub chain_id: String,
}

impl DappClient {
pub fn new(url: Url) -> Self {
let http = reqwest::Client::new();
Self { http, url }
}

pub async fn search_dapps(&self, query: &str) -> Result<Vec<DappWithChainId>, ServiceError> {
let mut url = self.url.clone();
url.set_path("/api/v1/marketplace/dapps:search");
url.query_pairs_mut().append_pair("query", query);

self.http
.get(url)
.send()
.await
.map_err(|e| ServiceError::Internal(e.into()))?
.json::<Vec<DappWithChainId>>()
.await
.map_err(|e| ServiceError::Internal(e.into()))
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
pub mod api_key_manager;
pub mod dapp_client;
pub mod error;
mod import;
mod proto;
pub mod repository;
pub mod search;
mod types;
mod dapp_client;

pub use import::batch_import;
pub use types::{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ use alloy_primitives::Address as AddressAlloy;
use entity::addresses::{ActiveModel, Column, Entity, Model};
use regex::Regex;
use sea_orm::{
prelude::Expr,
sea_query::{OnConflict, PostgresQueryBuilder},
ActiveValue::NotSet,
ConnectionTrait, DbErr, EntityTrait, IntoSimpleExpr, Iterable, QueryFilter, QueryOrder,
QuerySelect, QueryTrait,
prelude::Expr, sea_query::OnConflict, ActiveValue::NotSet, ConnectionTrait, DbErr, EntityTrait,
IntoSimpleExpr, Iterable, QueryFilter, QueryOrder, QuerySelect,
};
use std::sync::OnceLock;

Expand Down Expand Up @@ -88,8 +85,10 @@ where
.limit(limit + 1);

if hex_regex().is_match(q) {
let prefix = format!("\\x{}", q.strip_prefix("0x").unwrap_or(q));
query = query.filter(Expr::cust_with_expr("hash LIKE $1", format!("{}%", prefix)));
query = query.filter(Expr::cust_with_expr(
"encode(hash, 'hex') LIKE $1",
format!("{}%", q.to_lowercase().strip_prefix("0x").unwrap_or(q)),
));
} else {
let ts_query = prepare_ts_query(q);
query = query.filter(Expr::cust_with_expr(
Expand All @@ -100,8 +99,6 @@ where
));
}

println!("{}", query.as_query().to_string(PostgresQueryBuilder));

let addresses = query
.all(db)
.await?
Expand Down
37 changes: 29 additions & 8 deletions multichain-aggregator/multichain-aggregator-logic/src/search.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use crate::{
dapp_client::DappClient,
error::ServiceError,
repository::{addresses, block_ranges, hashes},
types::{
chains::Chain,
dapp::MarketplaceDapp,
search_results::{ChainSearchResult, SearchResults},
ChainId,
},
};
use sea_orm::DatabaseConnection;
use std::collections::BTreeMap;
use tokio::try_join;
use tokio::join;

macro_rules! populate_search_results {
($target:expr, $explorers:expr, $from:expr, $field:ident) => {
Expand All @@ -28,27 +30,46 @@ macro_rules! populate_search_results {

pub async fn quick_search(
db: &DatabaseConnection,
dapp_client: &DappClient,
query: String,
chains: &[Chain],
) -> Result<SearchResults, ServiceError> {
let raw_query = query.trim();

let ((blocks, transactions), block_numbers, addresses) = try_join!(
let (hashes, block_numbers, addresses, dapps) = join!(
hashes::search_by_query(db, raw_query),
block_ranges::search_by_query(db, raw_query),
addresses::search_by_query(db, raw_query)
)?;
addresses::search_by_query(db, raw_query),
dapp_client.search_dapps(raw_query),
);

let explorers: BTreeMap<ChainId, String> = chains
.iter()
.filter_map(|c| c.explorer_url.as_ref().map(|url| (c.id, url.clone())))
.collect();

let mut results = SearchResults::default();
populate_search_results!(results, explorers, addresses, addresses);
populate_search_results!(results, explorers, blocks, blocks);
populate_search_results!(results, explorers, transactions, transactions);
populate_search_results!(results, explorers, block_numbers, block_numbers);

if let Ok((blocks, transactions)) = hashes {
populate_search_results!(results, explorers, blocks, blocks);
populate_search_results!(results, explorers, transactions, transactions);
}

if let Ok(block_numbers) = block_numbers {
populate_search_results!(results, explorers, block_numbers, block_numbers);
}

if let Ok(addresses) = addresses {
populate_search_results!(results, explorers, addresses, addresses);
}

if let Ok(dapps) = dapps {
let dapps: Vec<MarketplaceDapp> = dapps
.into_iter()
.filter_map(|d| d.try_into().ok())
.collect();
populate_search_results!(results, explorers, dapps, dapps);
}

Ok(results)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use super::ChainId;
use crate::{dapp_client::DappWithChainId, error::ParseError, proto};

#[derive(Debug)]
pub struct MarketplaceDapp {
pub id: String,
pub title: String,
pub logo: String,
pub short_description: String,
pub chain_id: ChainId,
}

impl TryFrom<DappWithChainId> for MarketplaceDapp {
type Error = ParseError;

fn try_from(v: DappWithChainId) -> Result<Self, Self::Error> {
Ok(Self {
id: v.dapp.id,
title: v.dapp.title,
logo: v.dapp.logo,
short_description: v.dapp.short_description,
chain_id: v.chain_id.parse()?,
})
}
}

impl From<MarketplaceDapp> for proto::MarketplaceDapp {
fn from(v: MarketplaceDapp) -> Self {
Self {
id: v.id,
title: v.title,
logo: v.logo,
short_description: v.short_description,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod api_keys;
pub mod batch_import_request;
pub mod block_ranges;
pub mod chains;
pub mod dapp;
pub mod hashes;
pub mod search_results;
pub type ChainId = i64;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{block_ranges::ChainBlockNumber, ChainId};
use crate::{
proto,
types::{addresses::Address, hashes::Hash},
types::{addresses::Address, dapp::MarketplaceDapp, hashes::Hash},
};
use std::collections::BTreeMap;

Expand All @@ -12,6 +12,7 @@ pub struct ChainSearchResult {
pub blocks: Vec<Hash>,
pub transactions: Vec<Hash>,
pub block_numbers: Vec<ChainBlockNumber>,
pub dapps: Vec<MarketplaceDapp>,
}

impl From<ChainSearchResult> for proto::quick_search_response::ChainSearchResult {
Expand All @@ -22,6 +23,7 @@ impl From<ChainSearchResult> for proto::quick_search_response::ChainSearchResult
blocks: v.blocks.into_iter().map(|b| b.into()).collect(),
transactions: v.transactions.into_iter().map(|t| t.into()).collect(),
block_numbers: v.block_numbers.into_iter().map(|b| b.into()).collect(),
dapps: v.dapps.into_iter().map(|d| d.into()).collect(),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ message Hash {
HashType hash_type = 2;
}

message MarketplaceDapp {
string id = 1;
string title = 2;
string logo = 4;
string short_description = 5;
}

message BatchImportRequest {
string chain_id = 1;
repeated Address addresses = 2;
Expand All @@ -75,6 +82,7 @@ message QuickSearchResponse {
repeated Hash blocks = 3;
repeated Hash transactions = 4;
repeated ChainBlockNumber block_numbers = 5;
repeated MarketplaceDapp dapps = 6;
}

map<string, ChainSearchResult> items = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ definitions:
items:
type: object
$ref: '#/definitions/QuickSearchResponseChainBlockNumber'
dapps:
type: array
items:
type: object
$ref: '#/definitions/v1MarketplaceDapp'
protobufAny:
type: object
properties:
Expand Down Expand Up @@ -254,6 +259,17 @@ definitions:
$ref: '#/definitions/v1Address'
pagination:
$ref: '#/definitions/v1Pagination'
v1MarketplaceDapp:
type: object
properties:
id:
type: string
title:
type: string
logo:
type: string
short_description:
type: string
v1Pagination:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ tokio = { workspace = true }
tonic = { workspace = true }
tracing = { workspace = true }
env-collector = { workspace = true }
url = { workspace = true, features = ["serde"] }

[dev-dependencies]
blockscout-service-launcher = { workspace = true, features = [ "test-server","test-database"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
use blockscout_chains::BlockscoutChainsClient;
use blockscout_service_launcher::{database, launcher, launcher::LaunchSettings};
use migration::Migrator;
use multichain_aggregator_logic::repository;
use multichain_aggregator_logic::{dapp_client::DappClient, repository};
use std::sync::Arc;

const SERVICE_NAME: &str = "multichain_aggregator";
Expand Down Expand Up @@ -69,10 +69,13 @@ pub async fn run(settings: Settings) -> Result<(), anyhow::Error> {
.collect::<Vec<_>>();
repository::chains::upsert_many(&db, blockscout_chains.clone()).await?;

let dapp_client = DappClient::new(settings.service.dapp_client.url);

let multichain_aggregator = Arc::new(MultichainAggregator::new(
db,
blockscout_chains,
settings.service,
dapp_client,
settings.service.max_page_size,
));

let router = Router {
Expand Down
Loading

0 comments on commit 3a62e6a

Please sign in to comment.