-
Notifications
You must be signed in to change notification settings - Fork 35
feat: add iota-names-indexer
crate
#6975
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
Merged
thibault-martinez
merged 18 commits into
feat/iota-names-indexer
from
feat/custom-indexer-iota-names
May 26, 2025
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
69c3bf6
feat: add `iota-names-indexer` crate
thibault-martinez 6aa20a2
set up IndexerExecutor and FileProgressStore
thibault-martinez 89d7084
add first IotaNamesMetrics served through prometheus
thibault-martinez e167753
use gauge add
thibault-martinez f224022
Add prometheus config and count total_name_records
Thoralf-M 3a1985a
Merge branch 'develop' into feat/custom-indexer-iota-names
thibault-martinez 7e30b31
split into modules
thibault-martinez 550eb23
use Ipv4Addr::LOCALHOST
thibault-martinez 224e2f7
build config only once
thibault-martinez 0e0d827
add process_event()
thibault-martinez c385238
add process_ptb()
thibault-martinez abdd8b9
start_prometheus_server func
thibault-martinez ec60c9e
remove backfill file
thibault-martinez 6ce7513
nits
thibault-martinez 7eb8918
Merge branch 'develop' into feat/custom-indexer-iota-names
thibault-martinez 3c7e628
dprint
thibault-martinez 11b420d
clippy
thibault-martinez 1eaa52e
add crate filter and codeowner
thibault-martinez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
progress_store |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[package] | ||
name = "iota-names-indexer" | ||
version.workspace = true | ||
authors = ["IOTA Foundation <[email protected]>"] | ||
edition = "2021" | ||
license = "Apache-2.0" | ||
publish = false | ||
|
||
[dependencies] | ||
# external dependencies | ||
anyhow.workspace = true | ||
async-trait.workspace = true | ||
prometheus.workspace = true | ||
tokio.workspace = true | ||
tokio-util.workspace = true | ||
|
||
# internal dependencies | ||
iota-data-ingestion-core.workspace = true | ||
iota-metrics.workspace = true | ||
iota-names.workspace = true | ||
iota-types.workspace = true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# IOTA-Names indexer | ||
|
||
Indexer to collect metrics about IOTA-Names. | ||
|
||
## Testing | ||
|
||
### Run a local network | ||
|
||
```bash | ||
iota start --force-regenesis --with-faucet --committee-size 2 | ||
``` | ||
|
||
### Deploy the IOTA-Names packages | ||
|
||
https://github.com/iotaledger/iota-names/tree/develop/scripts#setup-iota-names-locally | ||
In the `iota-names` directory, run: | ||
|
||
```bash | ||
pnpm ts-node init/init.ts localnet | ||
``` | ||
|
||
### Start the indexer | ||
|
||
```bash | ||
cargo run | ||
``` | ||
|
||
### Start prometheus | ||
|
||
```bash | ||
# Create persistent volume for your data | ||
docker volume create prometheus-data | ||
# Start Prometheus container | ||
docker run \ | ||
-p 9090:9090 \ | ||
-v "$(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml" \ | ||
-v prometheus-data:/prometheus \ | ||
prom/prometheus | ||
``` | ||
|
||
### Start Grafana | ||
|
||
```bash | ||
sudo /bin/systemctl start grafana-server | ||
``` | ||
|
||
Set env variables: | ||
|
||
JSON_FILE="./localnet.json" | ||
|
||
export IOTA_NAMES_PACKAGE_ADDRESS=$(jq -r '.packageId' "$JSON_FILE") | ||
export IOTA_NAMES_OBJECT_ID=$(jq -r '.iotaNames' "$JSON_FILE") | ||
export IOTA_NAMES_PAYMENTS_PACKAGE_ADDRESS=$(jq -r '.paymentsPackageId' "$JSON_FILE") | ||
export IOTA_NAMES_REGISTRY_ID=$(jq -r '.registryTableId' "$JSON_FILE") | ||
export IOTA_NAMES_REVERSE_REGISTRY_ID=$(jq -r '.reverseRegistryTableId' "$JSON_FILE") | ||
|
||
echo "IOTA_NAMES_PACKAGE_ADDRESS=$IOTA_NAMES_PACKAGE_ADDRESS" | ||
echo "IOTA_NAMES_OBJECT_ID=$IOTA_NAMES_OBJECT_ID" | ||
echo "IOTA_NAMES_PAYMENTS_PACKAGE_ADDRESS=$IOTA_NAMES_PAYMENTS_PACKAGE_ADDRESS" | ||
echo "IOTA_NAMES_REGISTRY_ID=$IOTA_NAMES_REGISTRY_ID" | ||
echo "IOTA_NAMES_REVERSE_REGISTRY_ID=$IOTA_NAMES_REVERSE_REGISTRY_ID" | ||
|
||
cargo run --features=iota-names name register test.iota |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
scrape_configs: | ||
- job_name: "iota_names" | ||
static_configs: | ||
- targets: ["172.17.0.1:9184"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (c) 2025 IOTA Stiftung | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
mod metrics; | ||
mod worker; | ||
|
||
use std::{path::PathBuf, sync::Arc}; | ||
|
||
use anyhow::Result; | ||
use iota_data_ingestion_core::{ | ||
DataIngestionMetrics, FileProgressStore, IndexerExecutor, ReaderOptions, WorkerPool, | ||
}; | ||
use iota_names::config::IotaNamesConfig; | ||
use tokio_util::sync::CancellationToken; | ||
|
||
use self::{ | ||
metrics::{IotaNamesMetrics, METRICS, start_prometheus_server}, | ||
worker::IotaNamesWorker, | ||
}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
let registry = start_prometheus_server(); | ||
|
||
METRICS.get_or_init(|| Arc::new(IotaNamesMetrics::new(®istry))); | ||
let metrics = DataIngestionMetrics::new(®istry); | ||
|
||
let progress_store = FileProgressStore::new("./progress_store").await?; | ||
|
||
let cancel_token = CancellationToken::new(); | ||
let mut executor = IndexerExecutor::new(progress_store, 1, metrics, cancel_token); | ||
|
||
let worker = IotaNamesWorker::new(IotaNamesConfig::from_env().unwrap_or_default()); | ||
let worker_pool = WorkerPool::new( | ||
worker, | ||
"iota_names_reader".to_string(), | ||
1, | ||
Default::default(), | ||
); | ||
|
||
executor.register(worker_pool).await.unwrap(); | ||
executor | ||
.run( | ||
PathBuf::from("./chk".to_string()), /* path to a local directory where checkpoints | ||
* are stored. */ | ||
Some("http://localhost:9000/api/v1".to_string()), | ||
vec![], // optional remote store access options. | ||
ReaderOptions::default(), // remote_read_batch_size. | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
// To get the metrics open: http://localhost:9184/metrics | ||
|
||
Ok(()) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) 2025 IOTA Stiftung | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use std::{ | ||
net::{IpAddr, Ipv4Addr, SocketAddr}, | ||
sync::{Arc, OnceLock}, | ||
}; | ||
|
||
use prometheus::{IntGauge, Registry, register_int_gauge_with_registry}; | ||
|
||
pub(crate) struct IotaNamesMetrics { | ||
pub total_name_records: IntGauge, | ||
} | ||
|
||
impl IotaNamesMetrics { | ||
pub fn new(registry: &Registry) -> Self { | ||
Self { | ||
total_name_records: register_int_gauge_with_registry!( | ||
"total_name_records", | ||
"The total number of name records in the registry", | ||
registry, | ||
) | ||
.unwrap(), | ||
} | ||
} | ||
} | ||
|
||
pub(crate) static METRICS: OnceLock<Arc<IotaNamesMetrics>> = OnceLock::new(); | ||
|
||
pub(crate) fn start_prometheus_server() -> Registry { | ||
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 9184); | ||
|
||
iota_metrics::start_prometheus_server(addr).default_registry() | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Copyright (c) 2025 IOTA Stiftung | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use std::sync::Arc; | ||
|
||
use anyhow::Result; | ||
use async_trait::async_trait; | ||
use iota_data_ingestion_core::Worker; | ||
use iota_names::config::IotaNamesConfig; | ||
use iota_types::{ | ||
Identifier, | ||
effects::{TransactionEffects, TransactionEffectsAPI}, | ||
event::Event, | ||
execution_status::ExecutionStatus, | ||
full_checkpoint_content::CheckpointData, | ||
transaction::{ProgrammableTransaction, TransactionData, TransactionKind}, | ||
}; | ||
|
||
use crate::metrics::METRICS; | ||
|
||
pub(crate) struct IotaNamesWorker { | ||
config: IotaNamesConfig, | ||
} | ||
|
||
impl IotaNamesWorker { | ||
pub(crate) fn new(config: IotaNamesConfig) -> Self { | ||
Self { config } | ||
} | ||
|
||
fn process_event(&self, event: &Event) -> Result<(), anyhow::Error> { | ||
if event.type_.address == self.config.package_address.into() { | ||
// TODO temporarily allowed until there are more even types | ||
#[allow(clippy::collapsible_if)] | ||
if event.type_.name == Identifier::new("IotaNamesRegistryEvent")? { | ||
// TODO: init from prometheus storage to not always start from 0 | ||
METRICS | ||
.get() | ||
.expect("metrics global should be initialized") | ||
.total_name_records | ||
.add(1); | ||
// TODO: deserialize to get the name lengths | ||
// let register_event = | ||
// bcs::from_bytes::<IotaNamesRegistryEvent>(& | ||
// event_bcs_bytes)?; | ||
// println!("Register event: {register_event:#?}"); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
fn process_ptb(&self, _ptb: &ProgrammableTransaction) -> Result<(), anyhow::Error> { | ||
let _module = Identifier::new("payment")?; // TODO: Make const | ||
let _function = Identifier::new("register")?; | ||
|
||
// if ptb.commands.iter().any(|cmd| { | ||
// if let Command::MoveCall(call) = cmd { | ||
// call.package == ObjectID::from(self.config.package_address) | ||
// && call.module == module | ||
// && call.function == function | ||
// } else { | ||
// false | ||
// } | ||
// }) {} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl Worker for IotaNamesWorker { | ||
type Message = (); | ||
type Error = anyhow::Error; | ||
|
||
async fn process_checkpoint( | ||
&self, | ||
checkpoint: Arc<CheckpointData>, // TODO change to &? | ||
) -> Result<Self::Message, Self::Error> { | ||
println!( | ||
"Processing checkpoint: {}", | ||
checkpoint.checkpoint_summary.sequence_number | ||
); | ||
|
||
for transaction in &checkpoint.transactions { | ||
let TransactionEffects::V1(effects) = &transaction.effects; | ||
|
||
if *effects.status() != ExecutionStatus::Success { | ||
continue; | ||
} | ||
|
||
if let Some(events) = &transaction.events { | ||
for event in events.data.iter() { | ||
self.process_event(event)?; | ||
} | ||
} | ||
|
||
let TransactionData::V1(data) = &transaction.transaction.intent_message().value; | ||
|
||
if let TransactionKind::ProgrammableTransaction(ptb) = &data.kind { | ||
self.process_ptb(ptb)?; | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.