From b1e88ff26132c6d2d7df6a896944e22d361b3a23 Mon Sep 17 00:00:00 2001 From: Dagur Valberg Johannsson Date: Wed, 13 Nov 2024 11:16:24 +0100 Subject: [PATCH] rpc: Add pool history call --- src/db/cauldron/pool.rs | 56 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 ++ src/rpc/pool.rs | 28 ++++++++++++++++++++- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/db/cauldron/pool.rs b/src/db/cauldron/pool.rs index 9dfd449..95969cf 100644 --- a/src/db/cauldron/pool.rs +++ b/src/db/cauldron/pool.rs @@ -8,6 +8,7 @@ use std::{ sync::atomic::AtomicI64, }; +use crate::def::PoolID; use anyhow::Result; use bitcoin_hashes::hex::{FromHex, ToHex}; use log::{debug, info, warn}; @@ -387,3 +388,58 @@ pub fn get_pool_period_snapshot( Ok(pools) } + +#[derive(Serialize)] +pub struct PoolHistoryEntry { + txid: String, + sats: u64, + token_amount: u64, + timestamp: u64, + k: u128, +} + +pub fn db_pool_history( + conn: &Connection, + pool: &PoolID, + start_time: u64, +) -> Result> { + let query = "SELECT + phe.txid, + phe.sats, + phe.token_amount, + COALESCE(phe.first_seen_timestamp, phe.mtp_timestamp) as timestamp + FROM + pool_history_entry phe + WHERE + phe.pool = ?1 + AND timestamp >= ?2 + ORDER BY + phe.sequence ASC; + "; + + let mut stmt = conn.prepare(query)?; + let mut rows = stmt.query(params![pool.to_hex(), start_time])?; + + let from_row = |row: &Row<'_>| -> Result { + let sats = row.get(1)?; + let token_amount = row.get(2)?; + + let k = sats as u128 * token_amount as u128; + + Ok(PoolHistoryEntry { + txid: row.get(0)?, + sats, + token_amount, + timestamp: row.get(3)?, + k, + }) + }; + + let mut history: Vec = Vec::default(); + + while let Some(row) = rows.next()? { + history.push(from_row(row)?); + } + + Ok(history) +} diff --git a/src/main.rs b/src/main.rs index db81013..1001301 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,6 +53,7 @@ mod cashaddr; mod chain; mod crc20; mod db; +mod def; mod electrum; mod index; mod rpc; @@ -295,6 +296,7 @@ fn launch() -> _ { rpc::price::price_at, rpc::pool::list_pools_by_apy, rpc::pool::list_active_pools, + rpc::pool::pool_history, rpc::apy::aggregate_apy, rpc::contract::contract_count_token, rpc::contract::contract_count_all, diff --git a/src/rpc/pool.rs b/src/rpc/pool.rs index 58b56af..e929a8a 100644 --- a/src/rpc/pool.rs +++ b/src/rpc/pool.rs @@ -5,10 +5,12 @@ use crate::{ cashaddr::{self, version_byte_flags}, - db::DB, + db::{cauldron::pool::db_pool_history, DB}, + def::PoolID, timeutil::time_now, }; use anyhow::{Context, Result}; +use bitcoin_hashes::hex::FromHex; use rocket::{get, http::Status, response::status::Custom, serde::json::Json, State}; use rusqlite::{params, Connection}; use serde::Serialize; @@ -268,3 +270,27 @@ pub fn list_active_pools( "active": active, }))) } + +#[get("/pool/history/?")] +pub fn pool_history( + pool_id: &str, + start: Option, + conn: &State, +) -> Result, Custom> { + let db = conn + .cauldron_r + .get() + .map_err(|e| Custom(Status::InternalServerError, format!("Error: {}", e)))?; + + let start = start.unwrap_or(time_now() as u64 - (30 * 3600 * 24) /* 30 days ago */); + + let pool_id = PoolID::from_hex(pool_id) + .map_err(|e| Custom(Status::BadRequest, format!("Invalid pool ID: {}", e)))?; + + let history = db_pool_history(&db, &pool_id, start) + .map_err(|e| Custom(Status::InternalServerError, format!("Error: {}", e)))?; + + Ok(Json(json!({ + "history": history, + }))) +}