Skip to content

Commit

Permalink
feat(bens): subgraph deployer (#960)
Browse files Browse the repository at this point in the history
* chore: add more logs

* feat: add deployer for easy deployment of subgraphs

* chore: update dev docker startup

* config: change prod and staging default configs

* config: update dev.json config

* fix: allow `use_protocols` to be empty vector

* fix: do not create cache view if already exists
  • Loading branch information
sevenzing authored Jun 28, 2024
1 parent b406c7b commit 43bef59
Show file tree
Hide file tree
Showing 20 changed files with 482 additions and 145 deletions.
4 changes: 2 additions & 2 deletions blockscout-ens/bens-logic/examples/resolve_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ async fn main() -> Result<(), anyhow::Error> {
1,
Network {
blockscout_client: Arc::new(eth_client),
use_protocols: nonempty!["ens".to_string()],
use_protocols: vec!["ens".to_string()],
},
),
(
30,
Network {
blockscout_client: Arc::new(rootstock_client),
use_protocols: nonempty!["rns".to_string()],
use_protocols: vec!["rns".to_string()],
},
),
]);
Expand Down
30 changes: 15 additions & 15 deletions blockscout-ens/bens-logic/src/protocols/protocoler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Protocoler {
#[derive(Debug, Clone)]
pub struct Network {
pub blockscout_client: Arc<BlockscoutClient>,
pub use_protocols: NonEmpty<String>,
pub use_protocols: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
Expand Down Expand Up @@ -155,22 +155,22 @@ impl Protocoler {
})
.collect::<Vec<_>>();
let net_protocols = if let Some(filter) = maybe_filter {
NonEmpty::collect(
filter
.into_iter()
.map(|f| {
net_protocols
.iter()
.find(|&p| p.protocol.info.slug == f)
.copied()
.ok_or_else(|| ProtocolError::ProtocolNotFound(f))
})
.collect::<Result<Vec<_>, _>>()?,
)
.expect("build from nonempty iterator")
filter
.into_iter()
.map(|f| {
net_protocols
.iter()
.find(|&p| p.protocol.info.slug == f)
.copied()
.ok_or_else(|| ProtocolError::ProtocolNotFound(f))
})
.collect::<Result<Vec<_>, _>>()?
} else {
NonEmpty::from_vec(net_protocols).expect("build from nonempty iterator")
net_protocols
};
let net_protocols = NonEmpty::from_vec(net_protocols).ok_or_else(|| {
ProtocolError::ProtocolNotFound("no protocols found for network".to_string())
})?;
Ok(net_protocols)
}

Expand Down
20 changes: 8 additions & 12 deletions blockscout-ens/bens-logic/src/subgraphs_reader/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub struct SubgraphReader {
}

impl SubgraphReader {
#[instrument(name = "SubgraphReader::initialize", skip_all, err, level = "info")]
pub async fn initialize(
pool: Arc<PgPool>,
networks: HashMap<i64, Network>,
Expand Down Expand Up @@ -94,25 +95,18 @@ impl SubgraphReader {
.collect::<HashMap<_, _>>();

let networks = networks.into_iter()
.filter_map(|(chain_id, network)| {
.map(|(chain_id, network)| {
let (found_protocols, unknown_protocols): (Vec<_>, _) = network
.use_protocols
.into_iter()
.partition(|protocol_name| protocols.contains_key(protocol_name));
if !unknown_protocols.is_empty() {
tracing::warn!("found unknown protocols for network with id={chain_id}: {unknown_protocols:?}")
}
if let Some(use_protocols) = NonEmpty::collect(found_protocols) {
Some(
(chain_id, Network {
blockscout_client: network.blockscout_client,
use_protocols,
})
)
} else {
tracing::warn!("skip network with id={chain_id} since no protocols found");
None
}
(chain_id, Network {
blockscout_client: network.blockscout_client,
use_protocols: found_protocols,
})
})
.collect::<HashMap<_, _>>();

Expand Down Expand Up @@ -155,10 +149,12 @@ impl SubgraphReader {
Ok(())
}

#[instrument(skip_all, err, level = "info")]
pub async fn init_cache(&self) -> Result<(), anyhow::Error> {
for protocol in self.iter_protocols() {
let schema = &protocol.subgraph_schema;
let address_resolve_technique = &protocol.info.address_resolve_technique;
tracing::info!("start initializing cache table for schema {schema}");
match address_resolve_technique {
AddressResolveTechnique::ReverseRegistry => {
sql::AddrReverseNamesView::create_view(self.pool.as_ref(), schema)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::Context;
use sqlx::{Executor, PgPool};
use sqlx::{Executor, PgPool, Row};

mod addr_reverse_names;
mod address_names;
Expand All @@ -21,6 +21,20 @@ pub trait CachedView {
let unique_field = Self::unique_field();
let table_sql = Self::table_sql(schema);
let mut tx = pool.begin().await?;

// https://stackoverflow.com/questions/20582500/how-to-check-if-a-table-exists-in-a-given-schema
let exists = tx
.fetch_one(sqlx::query(&format!(
"SELECT to_regclass('{schema}.{view_table_name}') is not null;",
)))
.await?
.try_get::<bool, _>(0)
.context("checking if view exists")?;
if exists {
tracing::info!("view {} already exists, skipping creation", view_table_name);
return Ok(());
}

tx.execute(sqlx::query(&format!(
r#"
CREATE MATERIALIZED VIEW IF NOT EXISTS {schema}.{view_table_name} AS
Expand Down
2 changes: 1 addition & 1 deletion blockscout-ens/bens-logic/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub async fn mocked_networks_and_protocols(
1,
Network {
blockscout_client: Arc::new(client),
use_protocols: nonempty!["ens".to_string()],
use_protocols: vec!["ens".to_string()],
},
)]);

Expand Down
21 changes: 11 additions & 10 deletions blockscout-ens/bens-server/config/dev.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
{
"subgraphs_reader": {
"networks": {
"5": {
"11155111": {
"blockscout": {
"url": "https://eth-goerli.blockscout.com"
"url": "https://eth-sepolia.blockscout.com"
},
"use_protocols": [
"ens"
]
}
},
"protocols": {
"ens": {
"tld_list": [
"eth"
],
"subgraph_name": "ens-subgraph",
"ens-sepolia": {
"tld_list": ["eth"],
"network_id": 11155111,
"subgraph_name": "ens-sepolia-subgraph",
"address_resolve_technique": "reverse_registry",
"native_token_contract": "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",
"meta": {
"short_name": "ENS",
"title": "Ethereum Name Service",
"description": "The Ethereum Name Service (ENS) is a distributed, open, and extensible naming system based on the Ethereum blockchain."
"short_name": "ENS (Testnet)",
"title": "Ethereum Name Service (Testnet)",
"description": "The Ethereum Name Service (ENS) is a distributed, open, and extensible naming system based on the Ethereum blockchain.",
"icon_url": "https://i.imgur.com/GOfUwCb.jpeg",
"docs_url": "https://docs.ens.domains/"
}
}
}
Expand Down
92 changes: 91 additions & 1 deletion blockscout-ens/bens-server/config/prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
"rns"
]
},
"31": {
"blockscout": {
"url": "https://rootstock-testnet.blockscout.com"
},
"use_protocols": [
"rns-testnet"
]
},
"100": {
"blockscout": {
"url": "https://gnosis.blockscout.com/"
Expand All @@ -50,6 +58,14 @@
"ens"
]
},
"10200": {
"blockscout": {
"url": "https://gnosis-chiado.blockscout.com"
},
"use_protocols": [
"genome-chiado"
]
},
"17069": {
"blockscout": {
"url": "https://explorer.garnetchain.com/"
Expand All @@ -74,6 +90,14 @@
"mode"
]
},
"919": {
"blockscout": {
"url": "https://sepolia.explorer.mode.network"
},
"use_protocols": [
"mode-sepolia"
]
},
"1890": {
"blockscout": {
"url": "https://phoenix.lightlink.io"
Expand All @@ -90,6 +114,14 @@
"ens"
]
},
"11155111": {
"blockscout": {
"url": "https://eth-sepolia.blockscout.com"
},
"use_protocols": [
"ens-sepolia"
]
},
"7777777": {
"blockscout": {
"url": "https://explorer.zora.energy/"
Expand All @@ -116,6 +148,20 @@
"docs_url": "https://docs.ens.domains/"
}
},
"ens-sepolia": {
"tld_list": ["eth"],
"network_id": 11155111,
"subgraph_name": "ens-sepolia-subgraph",
"address_resolve_technique": "reverse_registry",
"native_token_contract": "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85",
"meta": {
"short_name": "ENS (Testnet)",
"title": "Ethereum Name Service (Testnet)",
"description": "The Ethereum Name Service (ENS) is a distributed, open, and extensible naming system based on the Ethereum blockchain.",
"icon_url": "https://i.imgur.com/GOfUwCb.jpeg",
"docs_url": "https://docs.ens.domains/"
}
},
"genome": {
"tld_list": [
"gno"
Expand All @@ -133,6 +179,21 @@
"docs_url": "https://genomedomains.com/"
}
},
"genome-chiado": {
"tld_list": ["gno"],
"network_id": 10200,
"subgraph_name": "genome-chiado-subgraph",
"address_resolve_technique": "reverse_registry",
"empty_label_hash": "0x1a13b687a5ff1d8ab1a9e189e1507a6abe834a9296cc8cff937905e3dee0c4f6",
"native_token_contract": "0xfd3d666dB2557983F3F04d61f90E35cc696f6D60",
"meta": {
"short_name": "Genome (Testnet)",
"title": "Genome Domains (Testnet)",
"description": "GNO Domains Connecting gnosis chain",
"icon_url": "https://i.imgur.com/xlDoPfF.png",
"docs_url": "https://genomedomains.com/"
}
},
"rns": {
"tld_list": [
"rsk"
Expand All @@ -149,6 +210,20 @@
"docs_url": "https://dev.rootstock.io/rif/rns/"
}
},
"rns-testnet": {
"tld_list": ["rsk"],
"network_id": 31,
"subgraph_name": "rns-testnet-subgraph",
"address_resolve_technique": "all_domains",
"native_token_contract": "0xca0a477e19bac7e0e172ccfd2e3c28a7200bdb71",
"meta": {
"short_name": "RNS (Testnet)",
"title": "Rootstock Name Service (Testnet)",
"description": "Rootstock Name Service (RNS) is a decentralized naming service, which allows users to have a readable domain name for their addresses.",
"icon_url": "https://i.imgur.com/o0MATMs.png",
"docs_url": "https://dev.rootstock.io/rif/rns/"
}
},
"base-name-service": {
"tld_list": [
"base"
Expand Down Expand Up @@ -182,6 +257,21 @@
"docs_url": "https://docs.modedomains.xyz/"
}
},
"mode-sepolia": {
"tld_list": ["mode"],
"network_id": 919,
"subgraph_name": "mode-sepolia-subgraph",
"address_resolve_technique": "reverse_registry",
"native_token_contract": "0xCa3a57e014937C29526De98e4A8A334a7D04792b",
"empty_label_hash": "0xea1eb1136f380e6643b69866632ce3b493100790c9c84416f2769d996a1c38b1",
"meta": {
"short_name": "MNS (Testnet)",
"title": "Mode Name Service (Testnet)",
"description": "Mode Name Service (MNS) is a decentralized naming service, which allows users to have a readable domain name for their addresses.",
"icon_url": "https://i.imgur.com/6QXp70g.png",
"docs_url": "https://docs.modedomains.xyz/"
}
},
"lightlink": {
"tld_list": [
"ll"
Expand Down Expand Up @@ -216,4 +306,4 @@
}
}
}
}
}
Loading

0 comments on commit 43bef59

Please sign in to comment.