diff --git a/Cargo.lock b/Cargo.lock index 951f142cdc..e150dafeeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5816,6 +5816,7 @@ dependencies = [ "penumbra-shielded-pool", "penumbra-stake", "serde_json", + "sqlx", "tokio", "tracing", ] @@ -7349,6 +7350,7 @@ dependencies = [ "atoi", "byteorder", "bytes", + "chrono", "crc", "crossbeam-queue", "dotenvy", @@ -7432,6 +7434,7 @@ dependencies = [ "bitflags 2.6.0", "byteorder", "bytes", + "chrono", "crc", "digest 0.10.7", "dotenvy", @@ -7473,6 +7476,7 @@ dependencies = [ "base64 0.21.7", "bitflags 2.6.0", "byteorder", + "chrono", "crc", "dotenvy", "etcetera", @@ -7509,6 +7513,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" dependencies = [ "atoi", + "chrono", "flume", "futures-channel", "futures-core", diff --git a/crates/bin/pindexer/Cargo.toml b/crates/bin/pindexer/Cargo.toml index 958b49ddd5..e32566c4c4 100644 --- a/crates/bin/pindexer/Cargo.toml +++ b/crates/bin/pindexer/Cargo.toml @@ -1,24 +1,25 @@ [package] name = "pindexer" -version = {workspace = true} -authors = {workspace = true} -edition = {workspace = true} -repository = {workspace = true} -homepage = {workspace = true} -license = {workspace = true} +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cometindex = {workspace = true} -penumbra-shielded-pool = {workspace = true, default-features = false} -penumbra-stake = {workspace = true, default-features = false} -penumbra-app = {workspace = true, default-features = false} -penumbra-num = {workspace = true, default-features = false} -penumbra-asset = {workspace = true, default-features = false} -penumbra-proto = {workspace = true, default-features = false} -tokio = {workspace = true, features = ["full"]} -anyhow = {workspace = true} -serde_json = {workspace = true} -tracing = {workspace = true} +sqlx = { workspace = true, features = ["chrono"] } +cometindex = { workspace = true } +penumbra-shielded-pool = { workspace = true, default-features = false } +penumbra-stake = { workspace = true, default-features = false } +penumbra-app = { workspace = true, default-features = false } +penumbra-num = { workspace = true, default-features = false } +penumbra-asset = { workspace = true, default-features = false } +penumbra-proto = { workspace = true, default-features = false } +tokio = { workspace = true, features = ["full"] } +anyhow = { workspace = true } +serde_json = { workspace = true } +tracing = { workspace = true } diff --git a/crates/bin/pindexer/src/block.rs b/crates/bin/pindexer/src/block.rs new file mode 100644 index 0000000000..585d78f95e --- /dev/null +++ b/crates/bin/pindexer/src/block.rs @@ -0,0 +1,57 @@ +use cometindex::{async_trait, sqlx, AppView, ContextualizedEvent, PgTransaction}; +use penumbra_proto::{core::component::sct::v1 as pb, event::ProtoEvent}; +use sqlx::types::chrono::DateTime; + +#[derive(Debug)] +pub struct Block {} + +#[async_trait] +impl AppView for Block { + async fn init_chain( + &self, + dbtx: &mut PgTransaction, + _: &serde_json::Value, + ) -> Result<(), anyhow::Error> { + sqlx::query( + // table name is module path + struct name + " +CREATE TABLE IF NOT EXISTS block_details ( + id SERIAL PRIMARY KEY, + root BYTEA NOT NULL, + height INT8 NOT NULL, + timestamp TIMESTAMPTZ NOT NULL +); +", + ) + .execute(dbtx.as_mut()) + .await?; + Ok(()) + } + + fn is_relevant(&self, type_str: &str) -> bool { + type_str == "penumbra.core.component.sct.v1.EventBlockRoot" + } + + async fn index_event( + &self, + dbtx: &mut PgTransaction, + event: &ContextualizedEvent, + ) -> Result<(), anyhow::Error> { + let pe = pb::EventBlockRoot::from_event(event.as_ref())?; + let timestamp = pe.timestamp.expect("Block has no timestamp"); + + sqlx::query( + " + INSERT INTO block_details (height, timestamp, root) + VALUES ($1, $2, $3) + ", + ) + .bind(pe.height as i64) + .bind(DateTime::from_timestamp(timestamp.seconds, timestamp.nanos as u32).unwrap()) + .bind(pe.root.unwrap().inner) + .execute(dbtx.as_mut()) + .await?; + + Ok(()) + } +} diff --git a/crates/bin/pindexer/src/lib.rs b/crates/bin/pindexer/src/lib.rs index 11b0ac6603..bacfb8f57c 100644 --- a/crates/bin/pindexer/src/lib.rs +++ b/crates/bin/pindexer/src/lib.rs @@ -2,7 +2,6 @@ pub use cometindex::{AppView, Indexer}; mod indexer_ext; pub use indexer_ext::IndexerExt; - +pub mod block; pub mod shielded_pool; - pub mod stake; diff --git a/crates/bin/pindexer/src/main.rs b/crates/bin/pindexer/src/main.rs index 081a3ea274..8653858351 100644 --- a/crates/bin/pindexer/src/main.rs +++ b/crates/bin/pindexer/src/main.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use pindexer::block::Block; use pindexer::{Indexer, IndexerExt as _}; #[tokio::main] @@ -6,6 +7,7 @@ async fn main() -> Result<()> { Indexer::new() .with_default_tracing() .with_default_penumbra_app_views() + .with_index(Block {}) .run() .await?; diff --git a/crates/core/component/sct/Cargo.toml b/crates/core/component/sct/Cargo.toml index d6ae5c696c..da99b806e4 100644 --- a/crates/core/component/sct/Cargo.toml +++ b/crates/core/component/sct/Cargo.toml @@ -44,7 +44,7 @@ serde = {workspace = true, features = ["derive"]} tendermint = {workspace = true} tonic = {workspace = true, optional = true} tracing = {workspace = true} -chrono = { workspace = true, default-features = false, features = ["serde"] } +chrono = { workspace = true, default-features = false, features = ["serde", "now"] } [dev-dependencies] getrandom = {workspace = true} \ No newline at end of file