Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Jurshsmith committed Apr 20, 2024
1 parent 91a07f5 commit 7dc974c
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 50 deletions.
12 changes: 12 additions & 0 deletions chaindexing/src/chains.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
/// Represents the chain network ID for contracts being indexed.
/// For example, `ChainId::Mainnet`, `ChainId::Polygon`, etc.
pub type ChainId = ethers::types::Chain;

/// Represents chain network for contracts being indexed
#[derive(Clone, Debug)]
pub struct Chain {
pub id: ChainId,
pub json_rpc_url: String,
}

impl Chain {
/// Builds the chain network
///
///
/// # Example
/// ```
/// use chaindexing::{Chain, ChainId};
///
/// Chain::new(ChainId::Polygon, "https://polygon-mainnet.g.alchemy.com/v2/...");
/// ```
pub fn new(id: ChainId, json_rpc_url: &str) -> Self {
Self {
id,
Expand Down
11 changes: 7 additions & 4 deletions chaindexing/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,20 @@ impl std::fmt::Debug for ConfigError {
}
}

/// Used to configure managing a chaindexing's node heartbeat
/// based on activities from one's Dapp to achieve ergonomic
/// ingesting to cut down RPC drastically
#[derive(Clone, Debug)]
pub struct OptimizationConfig {
pub(crate) node_heartbeat: NodeHeartbeat,
/// Optimization starts after the seconds specified here.
/// This is the typically the estimated time to complete initial indexing
/// i.e. the estimated time in seconds for chaindexing to reach
/// the current block for all chains being indexed.
pub(crate) start_after_in_secs: u64,
}

impl OptimizationConfig {
/// Optimization starts after the seconds specified here.
/// This is the typically the estimated time to complete initial indexing
/// i.e. the estimated time in seconds for chaindexing to reach
/// the current block for all chains being indexed.
pub fn new(node_heartbeat: &NodeHeartbeat, start_after_in_secs: u64) -> Self {
Self {
node_heartbeat: node_heartbeat.clone(),
Expand Down
6 changes: 4 additions & 2 deletions chaindexing/src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ impl ContractEvent {
}
}

/// Human Readable ABI defined for ingesting events.
/// For example, `event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)`
pub type EventAbi = &'static str;

/// Represents the specification for a given contract.
/// Represents the template/specification/interface for a given contract.
#[derive(Clone)]
pub struct Contract<S: Send + Sync + Clone> {
pub addresses: Vec<UnsavedContractAddress>,
Expand All @@ -45,7 +47,7 @@ pub struct Contract<S: Send + Sync + Clone> {
}

impl<S: Send + Sync + Clone> Contract<S> {
/// Builds the specification for a contract.
/// Builds the contract's template/spec/interface.
///
///
/// # Example
Expand Down
21 changes: 11 additions & 10 deletions chaindexing/src/events/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use uuid::Uuid;

use serde::Deserialize;

/// An event aka provider logs are emitted from smart contracts
/// to help infer their state
/// Events, aka. provider logs, are emitted from smart contracts
/// to help infer their states.
#[derive(Debug, Deserialize, Clone, Eq, Queryable, Insertable)]
#[diesel(table_name = chaindexing_events)]
pub struct Event {
Expand Down Expand Up @@ -99,35 +99,33 @@ impl Event {
self.abi.as_str()
}

/// Returns the event's block number
pub fn get_block_number(&self) -> u64 {
self.block_number as u64
}
/// Returns the event's block timestamp
pub fn get_block_timestamp(&self) -> u64 {
self.block_timestamp as u64
}
/// Returns the event's transaction index
pub fn get_transaction_index(&self) -> u32 {
self.transaction_index as u32
}
/// Returns the event's log index
pub fn get_log_index(&self) -> u32 {
self.log_index as u32
}

/// Returns the event's parameters
pub fn get_params(&self) -> EventParam {
EventParam::new(&self.parameters)
}

/// Returns the event's chain id
pub fn get_chain_id(&self) -> ChainId {
U64::from(self.chain_id).try_into().unwrap()
}

pub fn not_removed(&self) -> bool {
!self.removed
}

pub fn match_contract_address(&self, contract_address: &str) -> bool {
self.contract_address.to_lowercase() == *contract_address.to_lowercase()
}

fn log_params_to_parameters(log_params: &[LogParam]) -> HashMap<String, Token> {
log_params.iter().fold(HashMap::new(), |mut parameters, log_param| {
parameters.insert(log_param.name.to_string(), log_param.value.clone());
Expand All @@ -137,6 +135,9 @@ impl Event {
}
}

/// Represents the parameters parsed from an event/log.
/// Contains convenient parsers to convert or transform into useful primitives
/// as needed.
pub struct EventParam {
value: HashMap<String, Token>,
}
Expand Down
7 changes: 4 additions & 3 deletions chaindexing/src/handlers/pure_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ use super::handler_context::HandlerContext;
#[async_trait::async_trait]
pub trait PureHandler: Send + Sync {
/// The human-readable ABI of the event being handled.
/// For example, Uniswap's PoolCreated event's name is:
/// PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool)
/// The chain explorer's event section can also be used to easily infer this
/// For example, Uniswap's PoolCreated event's abi is:
/// `PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool)`.
/// The chain explorer's event section can also be used to infer this.
fn abi(&self) -> &'static str;
async fn handle_event<'a, 'b>(&self, context: PureHandlerContext<'a, 'b>);
}

/// Event's context in a pure event handler
#[derive(Clone)]
pub struct PureHandlerContext<'a, 'b> {
pub event: Event,
Expand Down
13 changes: 7 additions & 6 deletions chaindexing/src/handlers/side_effect_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@ use super::handler_context::HandlerContext;
/// SideEffectHandlers are event handlers that help handle side-effects for events.
/// This is useful for handling events only ONCE and can rely on a non-deterministic
/// shared state. Some use-cases are notifications, bridging etc. Chaindexing ensures
/// that the side-effect handlers are called once immutable regardless of resets.
/// However, one can dangerously reset including side effects with the new `reset_including_side_effects`
/// Config API.
/// that the side-effect handlers are called once immutably regardless of resets.
/// However, one can dangerously reset including side effects with the `reset_including_side_effects`
/// exposed in the Config API.
pub trait SideEffectHandler: Send + Sync {
type SharedState: Send + Sync + Clone + Debug;

/// The human-readable ABI of the event being handled.
/// For example, Uniswap's PoolCreated event's name is:
/// PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool)
/// The chain explorer's event section can also be used to easily infer this
/// For example, Uniswap's PoolCreated event's abi is:
/// `PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool)`.
/// The chain explorer's event section can also be used to infer this.
fn abi(&self) -> &'static str;
async fn handle_event<'a>(&self, context: SideEffectHandlerContext<'a, Self::SharedState>);
}

/// Event's context in a side effect handler
#[derive(Clone)]
pub struct SideEffectHandlerContext<'a, SharedState: Sync + Send + Clone> {
pub event: Event,
Expand Down
74 changes: 55 additions & 19 deletions chaindexing/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,92 @@
pub mod booting;
// TODO: Add back
// #![warn(
// missing_debug_implementations,
// missing_docs,
// rust_2018_idioms,
// unreachable_pub
// )]

//! # Chaindexing
//! Index any EVM chain and query in SQL.
//!
//! View working examples here: <https://github.com/chaindexing/chaindexing-examples/tree/main/rust>.
mod chain_reorg;
mod chains;
mod config;
mod contracts;
pub mod deferred_futures;
mod diesel;
pub mod events;
mod handlers;
pub mod ingester;
mod nodes;
mod pruning;
mod repos;
mod root;
pub mod states;

pub use chains::{Chain, ChainId};
pub use config::{Config, OptimizationConfig};
pub use contracts::{Contract, ContractAddress, ContractEvent, EventAbi, UnsavedContractAddress};
pub use contracts::{Contract, ContractAddress, EventAbi};
pub use events::{Event, EventParam};
pub use handlers::{
PureHandler as EventHandler, PureHandlerContext as EventContext, SideEffectHandler,
SideEffectHandlerContext as SideEffectContext,
};
pub use ingester::Provider as IngesterProvider;
pub use nodes::NodeHeartbeat as Heartbeat;

pub use ethers::types::{I256, U256};
use tokio::sync::Mutex;

/// Houses traits and structs for implementing states that can be indexed.
pub mod states;

/// Hexadecimal representation of addresses (such as contract addresses)
pub type Address = ethers::types::Address;
/// Represents bytes
pub type Bytes = Vec<u8>;
#[cfg(feature = "postgres")]
pub use repos::PostgresRepo;

#[doc(hidden)]
pub mod booting;
#[doc(hidden)]
pub mod deferred_futures;
#[doc(hidden)]
pub mod events;
#[doc(hidden)]
pub mod ingester;
#[doc(hidden)]
pub use contracts::{ContractEvent, UnsavedContractAddress};
#[doc(hidden)]
pub use ingester::Provider as IngesterProvider;
#[doc(hidden)]
pub use repos::*;

#[doc(hidden)]
#[cfg(feature = "postgres")]
pub use repos::{PostgresRepo, PostgresRepoConn, PostgresRepoPool};
pub use repos::{PostgresRepoConn, PostgresRepoPool};

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub type ChaindexingRepo = PostgresRepo;

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub type ChaindexingRepoPool = PostgresRepoPool;

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub type ChaindexingRepoConn<'a> = PostgresRepoConn<'a>;

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub type ChaindexingRepoClient = PostgresRepoClient;

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub type ChaindexingRepoTxnClient<'a> = PostgresRepoTxnClient<'a>;

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub use repos::PostgresRepoAsyncConnection as ChaindexingRepoAsyncConnection;

pub use ethers::types::{Address, U256, U256 as BigInt, U256 as Uint};
use tokio::sync::Mutex;

pub type Bytes = Vec<u8>;

use std::fmt::Debug;
use std::sync::Arc;
use std::time::Duration;
Expand All @@ -64,6 +99,7 @@ use crate::nodes::{NodeTask, NodeTasksRunner};

pub(crate) type ChaindexingRepoClientMutex = Arc<Mutex<PostgresRepoClient>>;

/// Errors from mis-configurations, database connections, internal errors, etc.
pub enum ChaindexingError {
Config(ConfigError),
}
Expand All @@ -84,7 +120,7 @@ impl Debug for ChaindexingError {
}
}

/// Starts processes to ingest and index states as configured
/// Starts processes for ingesting events and indexing states as configured.
pub async fn index_states<S: Send + Sync + Clone + Debug + 'static>(
config: &Config<S>,
) -> Result<(), ChaindexingError> {
Expand Down Expand Up @@ -129,14 +165,14 @@ pub async fn index_states<S: Send + Sync + Clone + Debug + 'static>(
Ok(())
}

/// Includes runtime-discovered contract addresses for indexing
/// Includes runtime-discovered contract addresses for indexing.
///
/// # Arguments
///
/// * `event_context` - context where the contract was discovered. Indexing starts
/// from this point onwards
/// * `name` - name of the contract specification as defined in the config
/// * `address` - address of the contract
/// * `event_context` - context where the contract was discovered.
/// N/B: Indexing for this contract starts from this point onwards
/// * `name` - name of the contract as defined in the config
/// * `address` - address of discovered contract
///
/// # Example
///
Expand Down
3 changes: 3 additions & 0 deletions chaindexing/src/nodes/node_heartbeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use std::fmt::Debug;
use std::sync::Arc;
use tokio::sync::Mutex;

/// A chaindexing node's heartbeat.
/// In a distributed environment, this is useful for managing the indexer's
/// processes such that RPC costs can be reduced based on triggering activities
#[derive(Clone, Debug)]
pub struct NodeHeartbeat {
/// Both in milliseconds
Expand Down
4 changes: 4 additions & 0 deletions chaindexing/src/repos.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(feature = "postgres")]
mod postgres_repo;

#[doc(hidden)]
#[cfg(feature = "postgres")]
pub use postgres_repo::{
Conn as PostgresRepoConn, Pool as PostgresRepoPool, PostgresRepo, PostgresRepoAsyncConnection,
Expand All @@ -9,8 +10,11 @@ pub use postgres_repo::{

mod repo;

#[doc(hidden)]
pub use repo::{ExecutesWithRawQuery, HasRawQueryClient, Repo, RepoError};

#[doc(hidden)]
pub(crate) use repo::{LoadsDataWithRawQuery, Migratable, RepoMigrations, SQLikeMigrations};

#[doc(hidden)]
pub mod streams;
1 change: 1 addition & 0 deletions chaindexing/src/repos/postgres_repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl From<DieselError> for RepoError {
}
}

/// Repo for Postgres databases
#[derive(Clone, Debug)]
pub struct PostgresRepo {
url: String,
Expand Down
1 change: 1 addition & 0 deletions chaindexing/src/repos/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
ContractAddress,
};

/// Errors from interacting the configured SQL database
#[derive(Debug, Display)]
pub enum RepoError {
NotConnected,
Expand Down
Loading

0 comments on commit 7dc974c

Please sign in to comment.