Skip to content

Commit

Permalink
Merge pull request #268 from anoma/tiago/token-supplies
Browse files Browse the repository at this point in the history
Index token supplies
  • Loading branch information
sug0 authored Feb 7, 2025
2 parents 5c732f5 + af04490 commit 6a295ba
Show file tree
Hide file tree
Showing 23 changed files with 484 additions and 13 deletions.
1 change: 1 addition & 0 deletions 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namada_ibc = { git = "https://github.com/anoma/namada", tag = "libs-v0.47.0" }
namada_token = { git = "https://github.com/anoma/namada", tag = "libs-v0.47.0" }
namada_parameters = { git = "https://github.com/anoma/namada", tag = "libs-v0.47.0" }
namada_proof_of_stake = { git = "https://github.com/anoma/namada", tag = "libs-v0.47.0" }
num-bigint = "0.4.6"
tendermint = "0.38.0"
tendermint-config = "0.38.0"
tendermint-rpc = { version = "0.38.0", features = ["http-client"] }
Expand Down
16 changes: 16 additions & 0 deletions chain/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use shared::checksums::Checksums;
use shared::crawler::crawl;
use shared::crawler_state::ChainCrawlerState;
use shared::error::{AsDbError, AsRpcError, ContextDbInteractError, MainError};
use shared::futures::AwaitContainer;
use shared::id::Id;
use shared::token::Token;
use shared::utils::BalanceChange;
Expand Down Expand Up @@ -235,6 +236,16 @@ async fn crawling_fn(
));
let addresses = block.addresses_with_balance_change(&native_token);

let native_token_supplies = first_block_in_epoch
.eq(&block_height)
.then(|| {
namada_service::get_token_supplies(&client, &native_token, epoch)
})
.future()
.await
.transpose()
.into_rpc_error()?;

let validators_addresses = if first_block_in_epoch.eq(&block_height) {
namada_service::get_all_consensus_validators_addresses_at(
&client,
Expand Down Expand Up @@ -411,6 +422,11 @@ async fn crawling_fn(
ibc_tokens,
)?;

repository::balance::insert_token_supplies(
transaction_conn,
native_token_supplies,
)?;

repository::block::upsert_block(
transaction_conn,
block,
Expand Down
34 changes: 32 additions & 2 deletions chain/src/repository/balance.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use anyhow::Context;
use diesel::{PgConnection, RunQueryDsl};
use orm::balances::BalanceChangesInsertDb;
use orm::schema::{balance_changes, ibc_token, token};
use orm::schema::{
balance_changes, ibc_token, token, token_supplies_per_epoch,
};
use orm::token::{IbcTokenInsertDb, TokenInsertDb};
use shared::balance::Balances;
use orm::token_supplies_per_epoch::TokenSuppliesInsertDb;
use shared::balance::{Balances, TokenSupply};
use shared::token::Token;
use shared::tuple_len::TupleLen;

Expand Down Expand Up @@ -70,6 +73,33 @@ pub fn insert_tokens(
anyhow::Ok(())
}

pub fn insert_token_supplies<S>(
transaction_conn: &mut PgConnection,
supplies: S,
) -> anyhow::Result<()>
where
S: IntoIterator<Item = TokenSupply>,
{
let supplies: Vec<_> = supplies
.into_iter()
.map(TokenSuppliesInsertDb::from)
.collect();

if supplies.is_empty() {
return anyhow::Ok(());
}

tracing::debug!(?supplies, "Adding new token supplies to db");

diesel::insert_into(token_supplies_per_epoch::table)
.values(supplies)
.on_conflict_do_nothing()
.execute(transaction_conn)
.context("Failed to update token supplies in db")?;

anyhow::Ok(())
}

#[cfg(test)]
mod tests {

Expand Down
46 changes: 45 additions & 1 deletion chain/src/services/namada.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use namada_sdk::rpc::{
use namada_sdk::state::Key;
use namada_sdk::token::Amount as NamadaSdkAmount;
use namada_sdk::{borsh, rpc, token};
use shared::balance::{Amount, Balance, Balances};
use shared::balance::{Amount, Balance, Balances, TokenSupply};
use shared::block::{BlockHeight, Epoch};
use shared::bond::{Bond, BondAddresses, Bonds};
use shared::id::Id;
Expand All @@ -42,6 +42,30 @@ pub async fn get_native_token(client: &HttpClient) -> anyhow::Result<Id> {
Ok(Id::from(native_token))
}

pub async fn query_native_token_total_supply(
client: &HttpClient,
) -> anyhow::Result<Amount> {
let native_token = RPC
.shell()
.native_token(client)
.await
.context("Failed to query native token")?;

rpc::get_token_total_supply(client, &native_token)
.await
.map(Amount::from)
.context("Failed to query total supply of native token")
}

pub async fn query_native_token_effective_supply(
client: &HttpClient,
) -> anyhow::Result<Amount> {
rpc::get_effective_native_supply(client)
.await
.map(Amount::from)
.context("Failed to query effective supply of native token")
}

pub async fn get_first_block_in_epoch(
client: &HttpClient,
) -> anyhow::Result<BlockHeight> {
Expand Down Expand Up @@ -797,3 +821,23 @@ pub async fn get_pgf_receipients(
})
.collect::<HashSet<_>>()
}

pub async fn get_token_supplies(
client: &HttpClient,
native_token: &Id,
epoch: u32,
) -> anyhow::Result<TokenSupply> {
let total_supply_fut = query_native_token_total_supply(client);
let effective_supply_fut = query_native_token_effective_supply(client);

let (total_supply, effective_supply) =
futures::try_join!(total_supply_fut, effective_supply_fut)
.context("Failed to query native token supplies")?;

anyhow::Ok(TokenSupply {
address: native_token.to_string(),
epoch: epoch as _,
total: total_supply.into(),
effective: Some(effective_supply.into()),
})
}
4 changes: 2 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ toolchains:
@echo {{ RUST_STABLE }}
@echo {{ RUST_NIGTHLY }}

build:
cargo +{{ RUST_STABLE }} build --all
build *BIN:
cargo +{{ RUST_STABLE }} build {{ if BIN != "" { prepend("--bin ", BIN) } else { "--all" } }}

check:
cargo +{{ RUST_STABLE }} check --all
Expand Down
11 changes: 11 additions & 0 deletions orm/migrations/2025-02-06-093718_token_supplies/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- This file should undo anything in `up.sql`

-- Drop the foreign key constraint on the address column
ALTER TABLE token_supplies_per_epoch
DROP CONSTRAINT fk_token_supplies_per_epoch_address;

-- Drop the trigger for enforcing the effective constraint
DROP TRIGGER enforce_effective_constraint ON token_supplies_per_epoch;

-- Drop the table itself
DROP TABLE token_supplies_per_epoch;
39 changes: 39 additions & 0 deletions orm/migrations/2025-02-06-093718_token_supplies/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- Your SQL goes here

CREATE TABLE token_supplies_per_epoch (
id SERIAL PRIMARY KEY,
address VARCHAR(45) NOT NULL,
epoch INT NOT NULL,
-- `2^256 - 1` will fit in `NUMERIC(78, 0)`
total NUMERIC(78, 0) NOT NULL,
effective NUMERIC(78, 0),
-- reference the `address` column in the `token` table
CONSTRAINT fk_token_supplies_per_epoch_address
FOREIGN KEY(address) REFERENCES token(address) ON DELETE CASCADE
);

ALTER TABLE token_supplies_per_epoch ADD UNIQUE (address, epoch);

CREATE OR REPLACE FUNCTION check_effective_for_token_type()
RETURNS TRIGGER AS $$
BEGIN
-- Check if the referenced token_type is 'native'
IF EXISTS (
SELECT 1
FROM token
WHERE token.address = NEW.address AND token.token_type = 'native'
) THEN
-- If token_type is 'native', ensure token_supplies_per_epoch.effective is not NULL
IF NEW.effective IS NULL THEN
RAISE EXCEPTION 'token_supplies_per_epoch.effective cannot be NULL when token.token_type is ''native''';
END IF;
END IF;
-- Allow the insert or update to proceed
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER enforce_effective_constraint
BEFORE INSERT OR UPDATE ON token_supplies_per_epoch
FOR EACH ROW
EXECUTE FUNCTION check_effective_for_token_type();
1 change: 1 addition & 0 deletions orm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod pos_rewards;
pub mod revealed_pk;
pub mod schema;
pub mod token;
pub mod token_supplies_per_epoch;
pub mod transactions;
pub mod unbond;
pub mod validators;
Expand Down
13 changes: 13 additions & 0 deletions orm/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,17 @@ diesel::table! {
}
}

diesel::table! {
token_supplies_per_epoch (id) {
id -> Int4,
#[max_length = 45]
address -> Varchar,
epoch -> Int4,
total -> Numeric,
effective -> Nullable<Numeric>,
}
}

diesel::table! {
use diesel::sql_types::*;
use super::sql_types::HistoryKind;
Expand Down Expand Up @@ -397,6 +408,7 @@ diesel::joinable!(ibc_token -> token (address));
diesel::joinable!(inner_transactions -> wrapper_transactions (wrapper_id));
diesel::joinable!(pos_rewards -> validators (validator_id));
diesel::joinable!(public_good_funding -> governance_proposals (proposal_id));
diesel::joinable!(token_supplies_per_epoch -> token (address));
diesel::joinable!(transaction_history -> inner_transactions (inner_tx_id));
diesel::joinable!(unbonds -> validators (validator_id));
diesel::joinable!(wrapper_transactions -> blocks (block_height));
Expand All @@ -419,6 +431,7 @@ diesel::allow_tables_to_appear_in_same_query!(
public_good_funding,
revealed_pk,
token,
token_supplies_per_epoch,
transaction_history,
unbonds,
validators,
Expand Down
44 changes: 44 additions & 0 deletions orm/src/token_supplies_per_epoch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use bigdecimal::BigDecimal;
use diesel::{Insertable, Queryable, Selectable};
use shared::balance::TokenSupply as SharedTokenSupply;

use crate::schema::token_supplies_per_epoch;

#[derive(Debug, Clone, Queryable, Selectable)]
#[diesel(table_name = token_supplies_per_epoch)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct TokenSuppliesDb {
pub id: i32,
pub address: String,
pub epoch: i32,
pub total: BigDecimal,
pub effective: Option<BigDecimal>,
}

#[derive(Debug, Clone, Queryable, Selectable, Insertable)]
#[diesel(table_name = token_supplies_per_epoch)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct TokenSuppliesInsertDb {
pub address: String,
pub epoch: i32,
pub total: BigDecimal,
pub effective: Option<BigDecimal>,
}

impl From<SharedTokenSupply> for TokenSuppliesInsertDb {
fn from(supply: SharedTokenSupply) -> Self {
let SharedTokenSupply {
address,
epoch,
total,
effective,
} = supply;

Self {
address,
epoch,
total,
effective,
}
}
}
3 changes: 2 additions & 1 deletion shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namada_proof_of_stake.workspace = true
namada_ibc.workspace = true
namada_sdk.workspace = true
namada_tx.workspace = true
num-bigint.workspace = true
serde.workspace = true
serde_json.workspace = true
subtle-encoding.workspace = true
Expand All @@ -39,4 +40,4 @@ tokio.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true
fake.workspace = true
rand.workspace = true
rand.workspace = true
Loading

0 comments on commit 6a295ba

Please sign in to comment.