diff --git a/Cargo.toml b/Cargo.toml index c1c91d3..c4b0526 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ reqwest = { version = "0.11", default-features = false, features = [ http = "0.2.6" toml = "0.5.9" base64 = "0.21.4" -diesel = { version = "2.0.0", features = [ +diesel = { version = "2.1.3", features = [ "postgres", "numeric", "chrono", @@ -40,7 +40,7 @@ diesel = { version = "2.0.0", features = [ "r2d2", "serde_json", ] } -diesel-derive-enum = { version = "2.0.0", features = ["postgres"] } +diesel-derive-enum = { version = "2.1.0", features = ["postgres"] } bigdecimal = { version = "0.4.0", features = ["serde"] } chrono = { version = "0.4.19", features = ["serde"] } config = { version = "0.13.0", default-features = false, features = [ diff --git a/diesel.toml b/diesel.toml index 98ba5a1..6d581ea 100644 --- a/diesel.toml +++ b/diesel.toml @@ -3,3 +3,4 @@ [print_schema] file = "src/dbsync/schema.rs" +custom_type_derives = ["diesel::query_builder::QueryId"] \ No newline at end of file diff --git a/src/bin/server.rs b/src/bin/server.rs index 0ce3344..5686e45 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] pub type Error = Box; pub type Result = std::result::Result; diff --git a/src/blockfrost/mod.rs b/src/blockfrost.rs similarity index 95% rename from src/blockfrost/mod.rs rename to src/blockfrost.rs index ed470a8..84c83ef 100644 --- a/src/blockfrost/mod.rs +++ b/src/blockfrost.rs @@ -141,13 +141,13 @@ impl super::provider::CardanoDataProvider for BlockfrostProvider { Ok(api::pool_delegations(self, pool, epoch)?) } - async fn deligations_per_pool_epoch_intervall( + async fn delegations_per_pool_epoch_intervall( &self, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderError> { - Ok(api::deligations_per_pool_for_epochs( + Ok(api::delegations_per_pool_for_epochs( self, pool, start_epoch, @@ -290,6 +290,20 @@ impl super::provider::CardanoDataProvider for BlockfrostProvider { Ok(api::pool_blocks_current_epoch(self, pool_hash)?) } + async fn pool_reward_recipients( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_reward_recipients(self, pool_hash)?) + } + + async fn pool_last_reward_earned_epoch( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_last_reward_earned_epoch(self, pool_hash)?) + } + async fn pool_declared_pledge( &self, pool_hash: &str, diff --git a/src/blockfrost/api.rs b/src/blockfrost/api.rs index 78690d2..848ef38 100644 --- a/src/blockfrost/api.rs +++ b/src/blockfrost/api.rs @@ -24,7 +24,7 @@ pub fn select_addr_of_first_transaction( bfp: &BlockfrostProvider, stake_address_in: &str, ) -> Result { - Ok("".to_owned()) + todo!() } /// get all utxos of an address @@ -33,9 +33,7 @@ pub fn utxo_by_dataumhash( addr: &str, datumhash: &Vec, ) -> Result { - Err(DataProviderBlockfrostError::Custom( - "not implemented".to_string(), - )) + todo!() } /// returns Utxo of a certain datumhash on an address @@ -44,9 +42,7 @@ pub fn utxo_by_txid( txhash: &Vec, index: i16, ) -> Result { - Err(DataProviderBlockfrostError::Custom( - "not implemented".to_string(), - )) + todo!() } /// get all utxos of an address @@ -137,7 +133,7 @@ pub fn pool_delegations( todo!(); } -pub fn deligations_per_pool_for_epochs( +pub fn delegations_per_pool_for_epochs( bfp: &BlockfrostProvider, pool: &str, start_epoch: i64, @@ -151,7 +147,7 @@ pub fn pool_total_stake( pool: &str, epoch: i32, ) -> Result { - Ok(0) + todo!() } pub async fn current_epoch(bfp: &BlockfrostProvider) -> Result { @@ -164,7 +160,7 @@ pub fn fingerprint( policy: &str, tokenname: &str, ) -> Result { - Ok("".to_owned()) + todo!() } pub fn token_info( @@ -193,7 +189,7 @@ pub fn check_stakeaddr_registered( bfp: &BlockfrostProvider, stake_addr_in: &str, ) -> Result { - Ok(false) + todo!() } pub fn lookup_token_holders( @@ -215,23 +211,14 @@ pub fn mint_metadata( bfp: &BlockfrostProvider, fingerprint_in: &str, ) -> Result { - Ok(TokenInfoView { - fingerprint: "".to_owned(), - policy: hex::encode(""), - tokenname: "".to_string(), - meta_key: None, - json: None, - txhash: None, - quantity: None, - mint_slot: None, - }) + todo!() } pub fn pool_valid( bfp: &BlockfrostProvider, pool_id: &str, ) -> Result { - Ok(true) + todo!() } pub fn txhash_spent( @@ -240,7 +227,7 @@ pub fn txhash_spent( ) -> Result { let txh_b = hex::decode(txhash)?; - Ok(false) + todo!() } pub fn retrieve_staked_amount ( @@ -248,14 +235,14 @@ pub fn retrieve_staked_amount ( epoch: i32, stake_addr: &str, ) -> Result { - Ok(BigDecimal::from(0)) + todo!() } pub fn retrieve_generated_rewards ( bfp: &BlockfrostProvider, stake_addr: &str, ) -> Result, DataProviderError> { - Ok(vec![]) + todo!() } @@ -280,6 +267,20 @@ pub fn pool_blocks_current_epoch( todo!() } +pub fn pool_reward_recipients( + bfp: &BlockfrostProvider, + pool_hash: &str, +) -> Result { + todo!() +} + +pub fn pool_last_reward_earned_epoch( + bfp: &BlockfrostProvider, + pool_hash: &str, +) -> Result { + todo!() +} + pub fn pool_declared_pledge( bfp: &BlockfrostProvider, pool_hash: &str, diff --git a/src/carb/mod.rs b/src/carb.rs similarity index 95% rename from src/carb/mod.rs rename to src/carb.rs index 0532044..1fa4919 100644 --- a/src/carb/mod.rs +++ b/src/carb.rs @@ -129,13 +129,13 @@ impl super::provider::CardanoDataProvider for CarbProvider { Ok(api::stakers_on_pool(self, pool, epoch)?) } - async fn deligations_per_pool_epoch_intervall( + async fn delegations_per_pool_epoch_intervall( &self, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderError> { - Ok(api::deligations_per_pool_for_epochs( + Ok(api::delegations_per_pool_for_epochs( self, pool, start_epoch, @@ -278,6 +278,20 @@ impl super::provider::CardanoDataProvider for CarbProvider { Ok(api::pool_blocks_current_epoch(self, pool_hash)?) } + async fn pool_reward_recipients( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_reward_recipients(self, pool_hash)?) + } + + async fn pool_last_reward_earned_epoch( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_last_reward_earned_epoch(self, pool_hash)?) + } + async fn pool_declared_pledge( &self, pool_hash: &str, diff --git a/src/carb/api.rs b/src/carb/api.rs index 6cabc61..b32e570 100644 --- a/src/carb/api.rs +++ b/src/carb/api.rs @@ -22,7 +22,7 @@ pub fn select_addr_of_first_transaction( bfp: &CarbProvider, stake_address_in: &str, ) -> Result { - Ok("".to_owned()) + todo!() } /// get all utxos of an address @@ -31,7 +31,7 @@ pub fn utxo_by_dataumhash( addr: &str, datumhash: &Vec, ) -> Result { - Err(DataProviderCarbError::Custom("not implemented".to_string())) + todo!() } /// returns Utxo of a certain datumhash on an address @@ -40,7 +40,7 @@ pub fn utxo_by_txid( txhash: &Vec, index: i16, ) -> Result { - Err(DataProviderCarbError::Custom("not implemented".to_string())) + todo!() } /// get all utxos of an address @@ -48,7 +48,7 @@ pub fn get_address_utxos( bfp: &CarbProvider, addr: &str, ) -> Result { - Ok(dcslc::TransactionUnspentOutputs::new()) + todo!() } /// Get all utxos of a stake address @@ -56,7 +56,7 @@ pub fn get_stake_address_utxos( bfp: &CarbProvider, stake_addr: &str, ) -> Result { - Ok(dcslc::TransactionUnspentOutputs::new()) + todo!() } /// Get all utxos of a stake address @@ -64,18 +64,18 @@ pub fn asset_utxos_on_addr( bfp: &CarbProvider, addr: &str, ) -> Result { - Ok(dcslc::TransactionUnspentOutputs::new()) + todo!() } pub fn find_datums_for_tx( bfp: &CarbProvider, txid: &Vec, ) -> Result, DataProviderError> { - todo!(); + todo!() } pub fn slot(bfp: &CarbProvider) -> Result { - Ok(0) + todo!() } pub fn stakers_on_pool( @@ -83,16 +83,16 @@ pub fn stakers_on_pool( pool: &str, epoch: i32, ) -> Result, DataProviderCarbError> { - todo!(); + todo!() } -pub fn deligations_per_pool_for_epochs( +pub fn delegations_per_pool_for_epochs( bfp: &CarbProvider, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderCarbError> { - todo!(); + todo!() } pub fn pool_total_stake( @@ -112,7 +112,7 @@ pub fn fingerprint( policy: &str, tokenname: &str, ) -> Result { - Ok("".to_owned()) + todo!() } pub fn token_info( @@ -141,7 +141,7 @@ pub fn check_stakeaddr_registered( bfp: &CarbProvider, stake_addr_in: &str, ) -> Result { - Ok(false) + todo!() } pub fn lookup_token_holders( @@ -163,26 +163,17 @@ pub fn mint_metadata( bfp: &CarbProvider, fingerprint_in: &str, ) -> Result { - Ok(TokenInfoView { - fingerprint: "".to_owned(), - policy: hex::encode(""), - tokenname: "".to_owned(), - meta_key: None, - json: None, - txhash: None, - quantity: None, - mint_slot: None, - }) + todo!() } pub fn pool_valid(bfp: &CarbProvider, pool_id: &str) -> Result { - Ok(true) + todo!() } pub fn txhash_spent(bfp: &CarbProvider, txhash: &str) -> Result { let txh_b = hex::decode(txhash)?; - Ok(false) + todo!() } pub fn retrieve_staked_amount ( @@ -190,14 +181,14 @@ pub fn retrieve_staked_amount ( epoch: i32, stake_addr: &str, ) -> Result { - Ok(BigDecimal::from(0)) + todo!() } pub fn retrieve_generated_rewards ( bfp: &CarbProvider, stake_addr: &str, ) -> Result, DataProviderError> { - Ok(vec![]) + todo!() } pub fn pool_vrf_key_hash ( @@ -221,6 +212,20 @@ pub fn pool_blocks_current_epoch( todo!() } +pub fn pool_reward_recipients( + bfp: &CarbProvider, + pool_hash: &str, +) -> Result { + todo!() +} + +pub fn pool_last_reward_earned_epoch( + bfp: &CarbProvider, + pool_hash: &str, +) -> Result { + todo!() +} + pub fn pool_declared_pledge( bfp: &CarbProvider, pool_hash: &str, diff --git a/src/dbsync/mod.rs b/src/dbsync.rs similarity index 95% rename from src/dbsync/mod.rs rename to src/dbsync.rs index 5b01496..7d6339f 100644 --- a/src/dbsync/mod.rs +++ b/src/dbsync.rs @@ -137,13 +137,13 @@ impl super::provider::CardanoDataProvider for DBSyncProvider { Ok(api::stakers_on_pool(self, pool, epoch)?) } - async fn deligations_per_pool_epoch_intervall( + async fn delegations_per_pool_epoch_intervall( &self, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderError> { - Ok(api::deligations_per_pool_for_epochs( + Ok(api::delegations_per_pool_for_epochs( self, pool, start_epoch, @@ -286,6 +286,20 @@ impl super::provider::CardanoDataProvider for DBSyncProvider { Ok(api::pool_blocks_current_epoch(self, pool_hash).await?) } + async fn pool_reward_recipients( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_reward_recipients(self, pool_hash).await?) + } + + async fn pool_last_reward_earned_epoch( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_last_reward_earned_epoch(self, pool_hash).await?) + } + async fn pool_declared_pledge( &self, pool_hash: &str, diff --git a/src/dbsync/api.rs b/src/dbsync/api.rs index 1cfef1a..41284eb 100644 --- a/src/dbsync/api.rs +++ b/src/dbsync/api.rs @@ -1,6 +1,7 @@ use super::error::DataProviderDBSyncError; -use super::models::{PoolHash, PoolRetire, Rewardtype, UnspentUtxo, UtxoView}; +use super::models::{PoolHash, PoolRetire, UnspentUtxo, UtxoView}; use super::schema::*; +use super::models::RewardType; use crate::models::{ CDPDatum, CardanoNativeAssetView, DelegationView, HoldingWalletView, PoolView, RewardView, ScriptView, StakeDelegationView, StakeDeregistrationView, StakeRegistrationView, TokenInfoView, @@ -10,6 +11,7 @@ use crate::models::{ use crate::DBSyncProvider; use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive}; use dcslc::TransactionUnspentOutputs; +use diesel::dsl::count_star; use diesel::prelude::*; use log::debug; use std::str::FromStr; @@ -433,7 +435,7 @@ pub fn stakers_on_pool( Ok(pool_stake) } -pub fn deligations_per_pool_for_epochs( +pub fn delegations_per_pool_for_epochs( dbs: &DBSyncProvider, pool: &str, start_epoch: i64, @@ -1878,21 +1880,41 @@ pub async fn pool_blocks_current_epoch( ) } -/// The quantity of delegators that are currently delegating -/// to the given stake pool. -pub async fn pool_live_delegators( +/// The quantity of delegators that received rewards last time +/// the given pool was a slot leader. This can be used as an +/// estimation of how many are currently delegating on the +/// given pool. +pub async fn pool_reward_recipients( dbs: &DBSyncProvider, pool_hash: &str, ) -> Result { Ok( reward::table - .inner_join(pool_hash::table.on(pool_hash::id.nullable().eq(reward::pool_id))) + .filter(reward::pool_id.is_not_null()) + .inner_join(pool_hash::table.on(pool_hash::id.eq(reward::pool_id.assume_not_null()))) .filter(pool_hash::view.eq(pool_hash.to_string())) - .filter(reward::earned_epoch.eq(current_epoch(dbs).unwrap() as i64)) - // .filter(reward::type_.eq(Rewardtype::Member)) TODO: FixMe + .filter(reward::earned_epoch.eq( + pool_last_reward_earned_epoch(dbs, pool_hash).await? + )) + .filter(reward::type_.eq(RewardType::Member)) .count() - .get_result::(&mut dbs.connect().unwrap() - ).unwrap() + .get_result::(&mut dbs.connect()?)? + ) +} + +/// When was the last time (epoch) the given pool was a slot leader? +pub async fn pool_last_reward_earned_epoch( + dbs: &DBSyncProvider, + pool_hash: &str, +) -> Result { + Ok( + reward::table + .filter(reward::pool_id.is_not_null()) + .inner_join(pool_hash::table.on(pool_hash::id.eq(reward::pool_id.assume_not_null()))) + .filter(pool_hash::view.eq(pool_hash.to_string())) + .order(reward::earned_epoch.desc()) + .select(reward::earned_epoch) + .first::(&mut dbs.connect()?)? ) } @@ -2125,30 +2147,32 @@ pub async fn pool_description( #[cfg(test)] mod tests { - use crate::{dbsync::DataProviderDBSyncError, provider::CardanoDataProvider}; + use crate::{dbsync::DataProviderDBSyncError, provider::CardanoDataProvider, DataProvider, DBSyncProvider}; + use crate::dbsync; use bigdecimal::BigDecimal; use itertools::Itertools; use serde_json::json; use std::str::FromStr; + fn data_provider() -> DataProvider { + let dp = DataProvider::new(DBSyncProvider::new(crate::Config { + db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), + })); + dp + } + #[tokio::test] async fn test_tx_history() { let r = vec!["addr_test1qqt86eq9972q3qttj6ztje97llasktzfzvhmdccqjlqjaq2cer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qy6q5t2","addr_test1qpg8ehvgj9zxrx59et72yjn2p02xwsm3l89jwj8ujcj63ujcer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qw23emu","addr_test1qqdp3cry5vc2gfjljctdu638tvkcqfx40fjunht9hrmru5zcer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qnaxxgs","addr_test1qr2mw080ujz0unmpn9lx5ftfuewc6htyr6v3a0svul2zgezcer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qgryf7t","addr_test1qr7tqh7tsg4lut3jv6tsfwlv464m6knjjw90ugyz8uzgr6zcer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qt0jxzj","addr_test1qrscurjp292sxv24sepj7ghq4ydkkekzaz53zwfswcna6ljcer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6q8pu3l5","addr_test1qqssrphse6qmp9h0ksu5vfmsx99tfl2lc6rhvy2spd5wr86cer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qw59j4j","addr_test1qqgagc0fy6nm0qe4h8zqxsg952tqjeg7l7j0agd0cx4u25zcer3t74yn0dm8xqnr7rtwhkqcrpsmphwcf0mlmn39ry6qxvept2"]; - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let t = dp.tx_history(&r, None).await.unwrap(); + let t = data_provider().tx_history(&r, None).await.unwrap(); println!("{t:?}"); } #[tokio::test] async fn test_discover_transaction() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let t = crate::dbsync::discover_transaction( - dp.provider(), + let t = dbsync::discover_transaction( + data_provider().provider(), "1b07f1152e52ce0a9dbb561aa2e2d1750ca3a1a4141150a8bad342947a66a3a6", ) .await; @@ -2157,19 +2181,13 @@ mod tests { #[tokio::test] async fn test_get_pools() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let t = crate::dbsync::get_pools(dp.provider()).await; + let t = dbsync::get_pools(data_provider().provider()).await; println!("{t:?}"); } #[tokio::test] async fn test_epoch_nonce() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let t = crate::dbsync::epoch_nonce(dp.provider(), 205) + let t = dbsync::epoch_nonce(data_provider().provider(), 205) .await .unwrap(); println!("Nonce: {}\nEntropy: {:?}", hex::encode(&t.0), t.1); @@ -2177,11 +2195,8 @@ mod tests { #[tokio::test] async fn test_is_nft() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let t = crate::dbsync::is_nft( - dp.provider(), + let t = dbsync::is_nft( + data_provider().provider(), &[ "asset1a0q0grruzd3dm2c9ev890zfaytty8tfcl4qt3a", "asset1h3pg9m9arlwl4l8z3dwg3lwg54j70zqdrjhy88", @@ -2196,11 +2211,8 @@ mod tests { #[tokio::test] async fn test_supply() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let t = crate::dbsync::token_supply( - dp.provider(), + let t = dbsync::token_supply( + data_provider().provider(), "asset1m099azmatp3f3xehsu4sqvr45jzqafxmm0dra0", ) .await @@ -2213,23 +2225,19 @@ mod tests { // make projection accurate for higher epoch values. #[tokio::test] async fn reward_projection() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let pool_hash = "pool1ayc7a29ray6yv4hn7ge72hpjafg9vvpmtscnq9v8r0zh7azas9c"; let stake_addr = "stake_test1upvv3c4l2jfhkannqf3lp4htmqvpscdsmhvyhalaecj3jdqtfcgvh"; // stake_test1upvv3c4l2jfhkannqf3lp4htmqvpscdsmhvyhalaecj3jdqtfcgvh let current_epoch = 25; let func_value = super::personal_delegator_rewards_next_epoch( - dp.provider(), + data_provider().provider(), pool_hash, current_epoch, stake_addr, ) .unwrap(); let real_value = - super::earned_reward(dp.provider(), stake_addr, current_epoch as i64).unwrap(); + super::earned_reward(data_provider().provider(), stake_addr, current_epoch as i64).unwrap(); println!("correct_reward: {}", real_value); println!("projected reward: {}", func_value); @@ -2238,13 +2246,10 @@ mod tests { #[tokio::test] async fn retrieve_staked_amount() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let epoch = 275; let stake_addr = "stake_test1upvv3c4l2jfhkannqf3lp4htmqvpscdsmhvyhalaecj3jdqtfcgvh"; - let func_value = super::retrieve_staked_amount(dp.provider(), epoch, stake_addr).unwrap(); + let func_value = super::retrieve_staked_amount(data_provider().provider(), epoch, stake_addr).unwrap(); let real_value = BigDecimal::from_str("10305915710").unwrap(); assert_eq!(func_value, real_value); @@ -2252,11 +2257,8 @@ mod tests { #[tokio::test] async fn mint_metadata() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let fingerprint_in = "asset1kngmwlxpfzc6pk027zvhsfpprp452gt3enhhxh"; - let func_value = super::mint_metadata(dp.provider(), fingerprint_in).unwrap(); + let func_value = super::mint_metadata(data_provider().provider(), fingerprint_in).unwrap(); let real_value = super::TokenInfoView { fingerprint: "asset1kngmwlxpfzc6pk027zvhsfpprp452gt3enhhxh".to_string(), policy: "994cf4c18f5613ca49c275f63d464b6d95123bfa8985e82b24b5680b".to_string(), @@ -2284,11 +2286,8 @@ mod tests { #[tokio::test] #[allow(non_snake_case)] async fn mint_metadata_bug_CMW_78() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let fingerprint_in = "asset162kdtwq54e5khz5y6naa55xqvk0zk5fpce8c76"; // contains non-UTF8 characters - let func_value = super::mint_metadata(dp.provider(), fingerprint_in).unwrap(); + let func_value = super::mint_metadata(data_provider().provider(), fingerprint_in).unwrap(); let real_value = super::TokenInfoView { fingerprint: "asset162kdtwq54e5khz5y6naa55xqvk0zk5fpce8c76".to_string(), policy: "8cbe56131657c928cee716677bd3eac885f9fcad10f9fa70e533f635".to_string(), @@ -2314,12 +2313,8 @@ mod tests { #[tokio::test] #[allow(non_snake_case)] async fn get_txo_tokens_CMW_81() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let utxo_tokens = super::get_txo_tokens( - dp.provider(), + data_provider().provider(), 3312750, 0 ).unwrap(); @@ -2334,7 +2329,7 @@ mod tests { println!("utxo_tokens[0]: {:?}", utxo_tokens[0]); let utxo_tokens = super::get_txo_tokens( - dp.provider(), + data_provider().provider(), 3312750, 1 ).unwrap(); @@ -2415,12 +2410,8 @@ mod tests { #[tokio::test] #[allow(non_snake_case)] async fn get_utxo_tokens_CMW_81() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); - let utxo_tokens = super::get_utxo_tokens( - dp.provider(), + data_provider().provider(), 3317731, 0 ).unwrap(); @@ -2444,7 +2435,7 @@ mod tests { assert_eq!(hex::encode(utxo_tokens[2].name.clone()), "7441726b"); let utxo_tokens = super::get_utxo_tokens( - dp.provider(), + data_provider().provider(), 3317731, 1 ).unwrap(); @@ -2470,205 +2461,127 @@ mod tests { #[tokio::test] async fn pool_vrf_key_hash() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1uh5xdjv70q5eyl5z644p23mvhd3dx0gwr8pjnlj9pwd3jgkvd0e"; - let _func_value = hex::encode(super::pool_vrf_key_hash(dp.provider(), pool_hash).await.unwrap()); + let _func_value = hex::encode(super::pool_vrf_key_hash(data_provider().provider(), pool_hash).await.unwrap()); let _manual_value = "335399acf3228243efb0fec0e43f18d61a496d4fd740fd800f9b91b5fa7d0540"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_blocks_minted() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1uh5xdjv70q5eyl5z644p23mvhd3dx0gwr8pjnlj9pwd3jgkvd0e"; - let _func_value = super::pool_blocks_minted(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_blocks_minted(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = 13; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_blocks_current_epoch() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool14u22dyym8k2g2twvgct86njg3m9cc7j2fc74yamy6672s6up7a0"; - let _func_value = super::pool_blocks_current_epoch(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_blocks_current_epoch(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = 25; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] - async fn pool_live_delegators() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); + async fn pool_reward_recipients() { let pool_hash = "pool1rk2y9gx6vll8lawzdqlky5p2a3ypzsxg07arg8gmhkjj2905035"; - let _func_value = super::pool_live_delegators(dp.provider(), pool_hash).await.unwrap(); // TODO:: FixMe - let _manual_value = 104; + let _func_value = super::pool_reward_recipients(data_provider().provider(), pool_hash).await.unwrap(); + let _manual_value = 207; + } - // assert_eq!(_func_value, _manual_value); // TODO: make this unit test work + #[tokio::test] + async fn pool_last_reward_earned_epoch() { + let pool_hash = "pool1rk2y9gx6vll8lawzdqlky5p2a3ypzsxg07arg8gmhkjj2905035"; + let _func_value = super::pool_last_reward_earned_epoch(data_provider().provider(), pool_hash).await.unwrap(); + let _manual_value = 349; } #[tokio::test] async fn pool_declared_pledge() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1vezalga3ge0mt0xf4txz66ctufk6nrmemhhpshwkhedk5jf0stw"; - let _func_value = super::pool_declared_pledge(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_declared_pledge(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = BigDecimal::from_str("125000000000").unwrap(); - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_margin_cost() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1vezalga3ge0mt0xf4txz66ctufk6nrmemhhpshwkhedk5jf0stw"; - let _func_value = super::pool_margin_cost(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_margin_cost(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = 0.075; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_fixed_cost() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1vezalga3ge0mt0xf4txz66ctufk6nrmemhhpshwkhedk5jf0stw"; - let _func_value = super::pool_fixed_cost(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_fixed_cost(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = BigDecimal::from_str("340000000").unwrap(); - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_reward_address() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1vezalga3ge0mt0xf4txz66ctufk6nrmemhhpshwkhedk5jf0stw"; - let _func_value = super::pool_reward_address(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_reward_address(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "stake_test1uz5ah77y8xvnxs6cyp979hg7fhxezjw39jfrpardqymnz7sg7ea8y"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_owner() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1vezalga3ge0mt0xf4txz66ctufk6nrmemhhpshwkhedk5jf0stw"; - let _func_value = super::pool_owner(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_owner(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "stake_test1uz5ah77y8xvnxs6cyp979hg7fhxezjw39jfrpardqymnz7sg7ea8y"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_registration() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1vezalga3ge0mt0xf4txz66ctufk6nrmemhhpshwkhedk5jf0stw"; - let _func_value = super::pool_registration(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_registration(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = 175; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_retirement() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool17hsjytkcntlh6py4gnmk4695cux28tpcxrggs9ln97mvvtplr2m"; - let func_value = super::pool_retirement(dp.provider(), pool_hash).await.unwrap(); + let func_value = super::pool_retirement(data_provider().provider(), pool_hash).await.unwrap(); let manual_value = 26; - - assert_eq!(func_value, manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_url() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool17hsjytkcntlh6py4gnmk4695cux28tpcxrggs9ln97mvvtplr2m"; - let _func_value = super::pool_url(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_url(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "https://armadacardano.io/metadata.json"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_ticker() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1l5u4zh84na80xr56d342d32rsdw62qycwaw97hy9wwsc6axdwla"; - let _func_value = super::pool_ticker(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_ticker(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "EUSKL"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_metadata_json() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1l5u4zh84na80xr56d342d32rsdw62qycwaw97hy9wwsc6axdwla"; - let _func_value = super::pool_metadata_json(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_metadata_json(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = json!({"name": "EUSKAL STAKE POOL TESTNET", "ticker": "EUSKL", "homepage": "https://euskalstakepool.win", "description": "EUSKAL STAKE POOL TESTNET"}); - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_name() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1l5u4zh84na80xr56d342d32rsdw62qycwaw97hy9wwsc6axdwla"; - let _func_value = super::pool_name(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_name(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "EUSKAL STAKE POOL TESTNET"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_homepage() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1l5u4zh84na80xr56d342d32rsdw62qycwaw97hy9wwsc6axdwla"; - let _func_value = super::pool_homepage(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_homepage(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "https://euskalstakepool.win"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } #[tokio::test] async fn pool_description() { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_DB_URL").unwrap(), - })); let pool_hash = "pool1l5u4zh84na80xr56d342d32rsdw62qycwaw97hy9wwsc6axdwla"; - let _func_value = super::pool_description(dp.provider(), pool_hash).await.unwrap(); + let _func_value = super::pool_description(data_provider().provider(), pool_hash).await.unwrap(); let _manual_value = "EUSKAL STAKE POOL TESTNET"; - - // assert_eq!(_func_value, _manual_value); // The value change in the future. But it passed at the time of this writing. } } \ No newline at end of file diff --git a/src/dbsync/error.rs b/src/dbsync/error.rs index 4aaf143..570696e 100644 --- a/src/dbsync/error.rs +++ b/src/dbsync/error.rs @@ -44,3 +44,5 @@ impl From for DataProviderDB DataProviderDBSyncError::Custom(err.to_string()) } } + +impl rweb::reject::Reject for DataProviderDBSyncError {} \ No newline at end of file diff --git a/src/dbsync/models.rs b/src/dbsync/models.rs index ca433b9..f96a475 100644 --- a/src/dbsync/models.rs +++ b/src/dbsync/models.rs @@ -34,9 +34,11 @@ pub enum Scriptpurposetype { #[db_rename = "reward"] Reward, } -#[derive(Debug, Clone, DbEnum, QueryId)] -#[ExistingTypePath = "crate::dbsync::schema::sql_types::Rewardtype"] -pub enum Rewardtype { + +/// Represents SQL enum +#[derive(Clone, Copy, Debug, DbEnum, PartialEq, Eq)] // Debug, Clone, QueryId +#[ExistingTypePath = "crate::dbsync::schema::sql_types::RewardType"] +pub enum RewardType { #[db_rename = "leader"] Leader, #[db_rename = "member"] @@ -48,6 +50,7 @@ pub enum Rewardtype { #[db_rename = "refund"] Refund, } + #[derive(Debug, Clone, DbEnum, QueryId, serde::Serialize, serde::Deserialize)] #[ExistingTypePath = "crate::dbsync::schema::sql_types::Scripttype"] pub enum Scripttype { @@ -640,7 +643,7 @@ pub struct ReservedPoolTicker { pub struct Reward { pub id: i64, pub addr_id: i64, - pub type_: Rewardtype, + pub type_: RewardType, pub amount: BigDecimal, pub earned_epoch: i64, pub spendable_epoch: i64, diff --git a/src/dbsync/schema.rs b/src/dbsync/schema.rs index 60af444..dad5781 100644 --- a/src/dbsync/schema.rs +++ b/src/dbsync/schema.rs @@ -1,17 +1,25 @@ pub mod sql_types { - #[derive(diesel::sql_types::SqlType)] + use diesel::{ + sql_types::SqlType, + query_builder::QueryId + }; + + use diesel_derive_enum::DbEnum; + + #[derive(SqlType, QueryId)] #[diesel(postgres_type(name = "Syncstatetype"))] pub struct Syncstatetype; - #[derive(diesel::sql_types::SqlType)] + #[derive(SqlType, QueryId)] #[diesel(postgres_type(name = "Scriptpurposetype"))] pub struct Scriptpurposetype; - #[derive(diesel::sql_types::SqlType)] - #[diesel(postgres_type(name = "Rewardtype"))] - pub struct Rewardtype; + /// Represents SQL enum + #[derive(SqlType, QueryId)] + #[diesel(postgres_type(name = "rewardtype"))] + pub struct RewardType; - #[derive(diesel::sql_types::SqlType)] + #[derive(SqlType, QueryId)] #[diesel(postgres_type(name = "Scripttype"))] pub struct Scripttype; } @@ -469,11 +477,14 @@ table! { } table! { + use diesel::sql_types::*; + use super::sql_types::RewardType; + reward (id) { id -> Int8, addr_id -> Int8, #[sql_name = "type"] - type_ -> crate::dbsync::schema::sql_types::Rewardtype, + type_ -> RewardType, amount -> Numeric, earned_epoch -> Int8, spendable_epoch -> Int8, diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 075b901..edbc36f 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -215,7 +215,7 @@ impl ChainFollowerRequestService for AyaCardanoRPCServer { Ok(Response::new(reply)) // Send back our formatted greeting } - async fn deligator_stake_event( + async fn delegator_stake_event( &self, request: Request, ) -> Result, Status> { @@ -229,7 +229,7 @@ impl ChainFollowerRequestService for AyaCardanoRPCServer { Ok(Response::new(reply)) // Send back our formatted greeting } - async fn deligator_staked( + async fn delegator_staked( &self, request: Request, ) -> Result, Status> { @@ -242,7 +242,7 @@ impl ChainFollowerRequestService for AyaCardanoRPCServer { Ok(Response::new(reply)) // Send back our formatted greeting } - async fn deligator_unstake_event( + async fn delegator_unstake_event( &self, request: Request, ) -> Result, Status> { @@ -256,7 +256,7 @@ impl ChainFollowerRequestService for AyaCardanoRPCServer { Ok(Response::new(reply)) // Send back our formatted greeting } - async fn deligator_unbonding( + async fn delegator_unbonding( &self, request: Request, ) -> Result, Status> { @@ -269,7 +269,7 @@ impl ChainFollowerRequestService for AyaCardanoRPCServer { Ok(Response::new(reply)) // Send back our formatted greeting } - async fn deligator_unbonding_event( + async fn delegator_unbonding_event( &self, request: Request, ) -> Result, Status> { diff --git a/src/koios/mod.rs b/src/koios.rs similarity index 95% rename from src/koios/mod.rs rename to src/koios.rs index 1c4fec6..02e89a8 100644 --- a/src/koios/mod.rs +++ b/src/koios.rs @@ -127,13 +127,13 @@ impl super::provider::CardanoDataProvider for KoiosProvider { Ok(api::stakers_on_pool(self, pool, epoch)?) } - async fn deligations_per_pool_epoch_intervall( + async fn delegations_per_pool_epoch_intervall( &self, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderError> { - Ok(api::deligations_per_pool_for_epochs( + Ok(api::delegations_per_pool_for_epochs( self, pool, start_epoch, @@ -276,6 +276,20 @@ impl super::provider::CardanoDataProvider for KoiosProvider { Ok(api::pool_blocks_current_epoch(self, pool_hash)?) } + async fn pool_reward_recipients( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_reward_recipients(self, pool_hash)?) + } + + async fn pool_last_reward_earned_epoch( + &self, + pool_hash: &str, + ) -> Result { + Ok(api::pool_last_reward_earned_epoch(self, pool_hash)?) + } + async fn pool_declared_pledge( &self, pool_hash: &str, diff --git a/src/koios/api.rs b/src/koios/api.rs index b8055a9..7a7000a 100644 --- a/src/koios/api.rs +++ b/src/koios/api.rs @@ -20,7 +20,7 @@ pub fn select_addr_of_first_transaction( bfp: &KoiosProvider, stake_address_in: &str, ) -> Result { - Ok("".to_owned()) + todo!() } /// get all utxos of an address @@ -29,9 +29,7 @@ pub fn get_utxo_by_dataumhash( addr: &str, datumhash: &Vec, ) -> Result { - Err(DataProviderKoiosError::Custom( - "not implemented".to_string(), - )) + todo!() } /// get all utxos of an address @@ -40,9 +38,7 @@ pub fn utxo_by_txid( txhash: &Vec, index: i16, ) -> Result { - Err(DataProviderKoiosError::Custom( - "not implemented".to_string(), - )) + todo!() } /// get all utxos of an address @@ -50,7 +46,7 @@ pub fn get_address_utxos( bfp: &KoiosProvider, addr: &str, ) -> Result { - Ok(dcslc::TransactionUnspentOutputs::new()) + todo!() } /// Get all utxos of a stake address @@ -58,7 +54,7 @@ pub fn get_stake_address_utxos( bfp: &KoiosProvider, stake_addr: &str, ) -> Result { - Ok(dcslc::TransactionUnspentOutputs::new()) + todo!() } /// Get all utxos of a stake address @@ -66,7 +62,7 @@ pub fn asset_utxos_on_addr( bfp: &KoiosProvider, addr: &str, ) -> Result { - Ok(dcslc::TransactionUnspentOutputs::new()) + todo!() } pub fn find_datums_for_tx( @@ -77,7 +73,7 @@ pub fn find_datums_for_tx( } pub fn slot(bfp: &KoiosProvider) -> Result { - Ok(0) + todo!() } pub fn stakers_on_pool( @@ -85,16 +81,16 @@ pub fn stakers_on_pool( pool: &str, epoch: i32, ) -> Result, DataProviderKoiosError> { - todo!(); + todo!() } -pub fn deligations_per_pool_for_epochs( +pub fn delegations_per_pool_for_epochs( bfp: &KoiosProvider, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderKoiosError> { - todo!(); + todo!() } pub fn pool_total_stake( @@ -102,11 +98,11 @@ pub fn pool_total_stake( pool: &str, epoch: i32, ) -> Result { - Ok(0) + todo!() } pub fn current_epoch(bfp: &KoiosProvider) -> Result { - Ok(0) + todo!() } pub fn fingerprint( @@ -114,7 +110,7 @@ pub fn fingerprint( policy: &str, tokenname: &str, ) -> Result { - Ok("".to_owned()) + todo!() } pub fn token_info( @@ -143,7 +139,7 @@ pub fn check_stakeaddr_registered( bfp: &KoiosProvider, stake_addr_in: &str, ) -> Result { - Ok(false) + todo!() } pub fn lookup_token_holders( @@ -165,26 +161,17 @@ pub fn mint_metadata( bfp: &KoiosProvider, fingerprint_in: &str, ) -> Result { - Ok(TokenInfoView { - fingerprint: "".to_owned(), - policy: hex::encode(""), - tokenname: "".to_owned(), - meta_key: None, - json: None, - txhash: None, - quantity: None, - mint_slot: None, - }) + todo!() } pub fn pool_valid(bfp: &KoiosProvider, pool_id: &str) -> Result { - Ok(true) + todo!() } pub fn txhash_spent(bfp: &KoiosProvider, txhash: &str) -> Result { let txh_b = hex::decode(txhash)?; - Ok(false) + todo!() } pub fn retrieve_staked_amount ( @@ -192,14 +179,14 @@ pub fn retrieve_staked_amount ( epoch: i32, stake_addr: &str, ) -> Result { - Ok(BigDecimal::from(0)) + todo!() } pub fn retrieve_generated_rewards ( bfp: &KoiosProvider, stake_addr: &str, ) -> Result, DataProviderKoiosError> { - Ok(vec![]) + todo!() } pub fn pool_vrf_key_hash( @@ -223,6 +210,20 @@ pub fn pool_blocks_current_epoch( todo!() } +pub fn pool_reward_recipients( + bfp: &KoiosProvider, + pool_hash: &str, +) -> Result { + todo!() +} + +pub fn pool_last_reward_earned_epoch( + bfp: &KoiosProvider, + pool_hash: &str, +) -> Result { + todo!() +} + pub fn pool_declared_pledge( bfp: &KoiosProvider, pool_hash: &str, diff --git a/src/proto/aya_cardano.proto b/src/proto/aya_cardano.proto index 9ae13b0..4a38e25 100644 --- a/src/proto/aya_cardano.proto +++ b/src/proto/aya_cardano.proto @@ -8,11 +8,11 @@ service ChainFollowerRequestService { rpc AyaValidatorStake (StakeRequest) returns (StateResponse); rpc AyaValidatorRegistrationEvent (ValidatorRequest) returns (EventResponse); rpc AyaValidatorUnregistrationEvent (ValidatorRequest) returns (EventResponse); - rpc DeligatorStakeEvent (StakeRequest) returns (EventResponse); - rpc DeligatorStaked (StakeRequest) returns (StateResponse); - rpc DeligatorUnstakeEvent (StakeRequest) returns (EventResponse); - rpc DeligatorUnbonding (StakeRequest) returns (StateResponse); - rpc DeligatorUnbondingEvent (StakeRequest) returns (EventResponse); + rpc DelegatorStakeEvent (StakeRequest) returns (EventResponse); + rpc DelegatorStaked (StakeRequest) returns (StateResponse); + rpc DelegatorUnstakeEvent (StakeRequest) returns (EventResponse); + rpc DelegatorUnbonding (StakeRequest) returns (StateResponse); + rpc DelegatorUnbondingEvent (StakeRequest) returns (EventResponse); }; enum EpochRequestType { diff --git a/src/proto/aya_cardano.rs b/src/proto/aya_cardano.rs index 2b15305..42bb987 100644 --- a/src/proto/aya_cardano.rs +++ b/src/proto/aya_cardano.rs @@ -502,7 +502,7 @@ pub mod chain_follower_request_service_client { ); self.inner.unary(req, path, codec).await } - pub async fn deligator_stake_event( + pub async fn delegator_stake_event( &mut self, request: impl tonic::IntoRequest, ) -> std::result::Result, tonic::Status> { @@ -517,19 +517,19 @@ pub mod chain_follower_request_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/aya_cardano.ChainFollowerRequestService/DeligatorStakeEvent", + "/aya_cardano.ChainFollowerRequestService/DelegatorStakeEvent", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "aya_cardano.ChainFollowerRequestService", - "DeligatorStakeEvent", + "DelegatorStakeEvent", ), ); self.inner.unary(req, path, codec).await } - pub async fn deligator_staked( + pub async fn delegator_staked( &mut self, request: impl tonic::IntoRequest, ) -> std::result::Result, tonic::Status> { @@ -544,19 +544,19 @@ pub mod chain_follower_request_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/aya_cardano.ChainFollowerRequestService/DeligatorStaked", + "/aya_cardano.ChainFollowerRequestService/DelegatorStaked", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "aya_cardano.ChainFollowerRequestService", - "DeligatorStaked", + "DelegatorStaked", ), ); self.inner.unary(req, path, codec).await } - pub async fn deligator_unstake_event( + pub async fn delegator_unstake_event( &mut self, request: impl tonic::IntoRequest, ) -> std::result::Result, tonic::Status> { @@ -571,19 +571,19 @@ pub mod chain_follower_request_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/aya_cardano.ChainFollowerRequestService/DeligatorUnstakeEvent", + "/aya_cardano.ChainFollowerRequestService/DelegatorUnstakeEvent", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "aya_cardano.ChainFollowerRequestService", - "DeligatorUnstakeEvent", + "DelegatorUnstakeEvent", ), ); self.inner.unary(req, path, codec).await } - pub async fn deligator_unbonding( + pub async fn delegator_unbonding( &mut self, request: impl tonic::IntoRequest, ) -> std::result::Result, tonic::Status> { @@ -598,19 +598,19 @@ pub mod chain_follower_request_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/aya_cardano.ChainFollowerRequestService/DeligatorUnbonding", + "/aya_cardano.ChainFollowerRequestService/DelegatorUnbonding", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "aya_cardano.ChainFollowerRequestService", - "DeligatorUnbonding", + "DelegatorUnbonding", ), ); self.inner.unary(req, path, codec).await } - pub async fn deligator_unbonding_event( + pub async fn delegator_unbonding_event( &mut self, request: impl tonic::IntoRequest, ) -> std::result::Result, tonic::Status> { @@ -625,14 +625,14 @@ pub mod chain_follower_request_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/aya_cardano.ChainFollowerRequestService/DeligatorUnbondingEvent", + "/aya_cardano.ChainFollowerRequestService/DelegatorUnbondingEvent", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "aya_cardano.ChainFollowerRequestService", - "DeligatorUnbondingEvent", + "DelegatorUnbondingEvent", ), ); self.inner.unary(req, path, codec).await @@ -666,23 +666,23 @@ pub mod chain_follower_request_service_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; - async fn deligator_stake_event( + async fn delegator_stake_event( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; - async fn deligator_staked( + async fn delegator_staked( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; - async fn deligator_unstake_event( + async fn delegator_unstake_event( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; - async fn deligator_unbonding( + async fn delegator_unbonding( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; - async fn deligator_unbonding_event( + async fn delegator_unbonding_event( &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; @@ -1011,15 +1011,15 @@ pub mod chain_follower_request_service_server { }; Box::pin(fut) } - "/aya_cardano.ChainFollowerRequestService/DeligatorStakeEvent" => { + "/aya_cardano.ChainFollowerRequestService/DelegatorStakeEvent" => { #[allow(non_camel_case_types)] - struct DeligatorStakeEventSvc( + struct DelegatorStakeEventSvc( pub Arc, ); impl< T: ChainFollowerRequestService, > tonic::server::UnaryService - for DeligatorStakeEventSvc { + for DelegatorStakeEventSvc { type Response = super::EventResponse; type Future = BoxFuture< tonic::Response, @@ -1031,7 +1031,7 @@ pub mod chain_follower_request_service_server { ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - (*inner).deligator_stake_event(request).await + (*inner).delegator_stake_event(request).await }; Box::pin(fut) } @@ -1043,7 +1043,7 @@ pub mod chain_follower_request_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = DeligatorStakeEventSvc(inner); + let method = DelegatorStakeEventSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -1059,15 +1059,15 @@ pub mod chain_follower_request_service_server { }; Box::pin(fut) } - "/aya_cardano.ChainFollowerRequestService/DeligatorStaked" => { + "/aya_cardano.ChainFollowerRequestService/DelegatorStaked" => { #[allow(non_camel_case_types)] - struct DeligatorStakedSvc( + struct DelegatorStakedSvc( pub Arc, ); impl< T: ChainFollowerRequestService, > tonic::server::UnaryService - for DeligatorStakedSvc { + for DelegatorStakedSvc { type Response = super::StateResponse; type Future = BoxFuture< tonic::Response, @@ -1079,7 +1079,7 @@ pub mod chain_follower_request_service_server { ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - (*inner).deligator_staked(request).await + (*inner).delegator_staked(request).await }; Box::pin(fut) } @@ -1091,7 +1091,7 @@ pub mod chain_follower_request_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = DeligatorStakedSvc(inner); + let method = DelegatorStakedSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -1107,15 +1107,15 @@ pub mod chain_follower_request_service_server { }; Box::pin(fut) } - "/aya_cardano.ChainFollowerRequestService/DeligatorUnstakeEvent" => { + "/aya_cardano.ChainFollowerRequestService/DelegatorUnstakeEvent" => { #[allow(non_camel_case_types)] - struct DeligatorUnstakeEventSvc( + struct DelegatorUnstakeEventSvc( pub Arc, ); impl< T: ChainFollowerRequestService, > tonic::server::UnaryService - for DeligatorUnstakeEventSvc { + for DelegatorUnstakeEventSvc { type Response = super::EventResponse; type Future = BoxFuture< tonic::Response, @@ -1127,7 +1127,7 @@ pub mod chain_follower_request_service_server { ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - (*inner).deligator_unstake_event(request).await + (*inner).delegator_unstake_event(request).await }; Box::pin(fut) } @@ -1139,7 +1139,7 @@ pub mod chain_follower_request_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = DeligatorUnstakeEventSvc(inner); + let method = DelegatorUnstakeEventSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -1155,15 +1155,15 @@ pub mod chain_follower_request_service_server { }; Box::pin(fut) } - "/aya_cardano.ChainFollowerRequestService/DeligatorUnbonding" => { + "/aya_cardano.ChainFollowerRequestService/DelegatorUnbonding" => { #[allow(non_camel_case_types)] - struct DeligatorUnbondingSvc( + struct DelegatorUnbondingSvc( pub Arc, ); impl< T: ChainFollowerRequestService, > tonic::server::UnaryService - for DeligatorUnbondingSvc { + for DelegatorUnbondingSvc { type Response = super::StateResponse; type Future = BoxFuture< tonic::Response, @@ -1175,7 +1175,7 @@ pub mod chain_follower_request_service_server { ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - (*inner).deligator_unbonding(request).await + (*inner).delegator_unbonding(request).await }; Box::pin(fut) } @@ -1187,7 +1187,7 @@ pub mod chain_follower_request_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = DeligatorUnbondingSvc(inner); + let method = DelegatorUnbondingSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -1203,15 +1203,15 @@ pub mod chain_follower_request_service_server { }; Box::pin(fut) } - "/aya_cardano.ChainFollowerRequestService/DeligatorUnbondingEvent" => { + "/aya_cardano.ChainFollowerRequestService/DelegatorUnbondingEvent" => { #[allow(non_camel_case_types)] - struct DeligatorUnbondingEventSvc( + struct DelegatorUnbondingEventSvc( pub Arc, ); impl< T: ChainFollowerRequestService, > tonic::server::UnaryService - for DeligatorUnbondingEventSvc { + for DelegatorUnbondingEventSvc { type Response = super::EventResponse; type Future = BoxFuture< tonic::Response, @@ -1223,7 +1223,7 @@ pub mod chain_follower_request_service_server { ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - (*inner).deligator_unbonding_event(request).await + (*inner).delegator_unbonding_event(request).await }; Box::pin(fut) } @@ -1235,7 +1235,7 @@ pub mod chain_follower_request_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = DeligatorUnbondingEventSvc(inner); + let method = DelegatorUnbondingEventSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( diff --git a/src/provider.rs b/src/provider.rs index d1f672d..fa28409 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -70,7 +70,7 @@ pub trait CardanoDataProvider { epoch: i32, ) -> Result, DataProviderError>; /// return the delegations for a pool in an epoch intervall - async fn deligations_per_pool_epoch_intervall( + async fn delegations_per_pool_epoch_intervall( &self, pool: &str, start_epoch: i64, @@ -150,6 +150,16 @@ pub trait CardanoDataProvider { pool_hash: &str, ) -> Result; + async fn pool_reward_recipients( + &self, + pool_hash: &str, + ) -> Result; + + async fn pool_last_reward_earned_epoch( + &self, + pool_hash: &str, + ) -> Result; + async fn pool_declared_pledge( &self, pool_hash: &str, @@ -310,14 +320,14 @@ impl CardanoData self.provider().stakers_on_pool(pool, epoch).await } - async fn deligations_per_pool_epoch_intervall( + async fn delegations_per_pool_epoch_intervall( &self, pool: &str, start_epoch: i64, end_epoch: i64, ) -> Result, DataProviderError> { self.provider() - .deligations_per_pool_epoch_intervall(pool, start_epoch, end_epoch) + .delegations_per_pool_epoch_intervall(pool, start_epoch, end_epoch) .await } @@ -441,6 +451,20 @@ impl CardanoData self.provider().pool_blocks_current_epoch(pool_hash).await } + async fn pool_reward_recipients ( + &self, + pool_hash: &str, + ) -> Result { + self.provider().pool_reward_recipients(pool_hash).await + } + + async fn pool_last_reward_earned_epoch ( + &self, + pool_hash: &str, + ) -> Result { + self.provider().pool_last_reward_earned_epoch(pool_hash).await + } + async fn pool_declared_pledge ( &self, pool_hash: &str, diff --git a/src/provider/error.rs b/src/provider/error.rs index 1c5994a..1fb29f3 100644 --- a/src/provider/error.rs +++ b/src/provider/error.rs @@ -40,3 +40,5 @@ impl From for DataProviderError { DataProviderError::Custom(err.to_string()) } } + +impl rweb::reject::Reject for DataProviderError {} \ No newline at end of file diff --git a/src/server/error.rs b/src/server/error.rs index cc27439..b22c978 100644 --- a/src/server/error.rs +++ b/src/server/error.rs @@ -1,5 +1,5 @@ use rweb::warp::{http::StatusCode, Rejection, Reply}; -use std::convert::Infallible; +use std::{convert::Infallible, env::VarError}; use thiserror::Error; use super::models::ErrorResponse; diff --git a/src/server/handler/handler_rest/info.rs b/src/server/handler/handler_rest/info.rs index 21f3a18..3c32479 100644 --- a/src/server/handler/handler_rest/info.rs +++ b/src/server/handler/handler_rest/info.rs @@ -6,12 +6,22 @@ use crate::server::error::RESTError; use crate::server::filter::with_auth; use crate::server::handler::make_error; use crate::{models::TokenInfoView, provider::CardanoDataProvider}; +use crate::DataProvider; +use crate::DBSyncProvider; use ::log::debug; use cardano_serialization_lib::utils::from_bignum; use dcslc::{make_fingerprint, TransactionUnspentOutputs}; use rweb::*; use serde_json::json; +fn data_provider() -> Result, Rejection> { + let dp = DataProvider::new(DBSyncProvider::new(crate::Config { + db_path: std::env::var("DBSYNC_URL").map_err(|_| warp::reject::not_found())?, + })); + + Ok(dp) +} + #[get("/utxos/{address}")] #[openapi( id = "api.info.utxos", @@ -23,11 +33,7 @@ pub async fn utxos_per_addr( #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { // check against dataprovider - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let utxos = dp + let utxos = data_provider()? .script_utxos(&address) .await .map_err(|_| RESTError::Custom("Could not find UTxOs".to_string()))?; @@ -47,13 +53,10 @@ pub async fn address_exists( #[query] addresses: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - let mut addresses: Vec = parse_string_vec_from_query(&addresses).unwrap(); + let mut addresses: Vec = parse_string_vec_from_query(&addresses)?; let addresses = addresses.iter_mut().map(|address| &address[..]).collect(); - let result = dp.addresses_exist(&addresses).await.unwrap(); + let result = data_provider()?.addresses_exist(&addresses).await?; Ok(rweb::Json::from(json!(result))) } @@ -83,10 +86,7 @@ pub async fn mint_metadata( fingerprint: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: dotenv::var("DBSYNC_URL").unwrap(), - })); - let metadata: TokenInfoView = match dp.mint_metadata(&fingerprint).await { + let metadata: TokenInfoView = match data_provider()?.mint_metadata(&fingerprint).await { Ok(metadata) => metadata, Err(e) => return Err(RESTError::Custom(e.to_string()).into()), }; @@ -104,11 +104,8 @@ pub async fn mint_metadata_policy_assetname( assetname: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); let fingerprint = make_fingerprint(&policy, &assetname).unwrap(); - let metadata: TokenInfoView = dp.mint_metadata(&fingerprint).await.unwrap(); + let metadata: TokenInfoView = data_provider()?.mint_metadata(&fingerprint).await?; Ok(rweb::Json::from(json!(metadata))) } @@ -123,15 +120,13 @@ pub async fn tx_history( #[query] slot: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - let mut addresses: Vec = parse_string_vec_from_query(&addresses).unwrap(); + + let mut addresses: Vec = parse_string_vec_from_query(&addresses)?; let addresses = addresses.iter_mut().map(|address| &address[..]).collect(); let slot = slot.parse::().ok(); - let history = dp.tx_history(&addresses, slot).await.unwrap(); + let history = data_provider()?.tx_history(&addresses, slot).await?; Ok(rweb::Json::from(json!(history))) } @@ -146,11 +141,10 @@ pub async fn tx_history_discover( hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); debug!("Try to discover Transaction: {:?}", hash); - let tx = crate::dbsync::discover_transaction(dp.provider(), &hash).await; + let tx = crate::dbsync::discover_transaction( + data_provider()?.provider(), &hash + ).await; match tx { Ok(tx) => Ok(rweb::Json::from(json!(tx))), @@ -189,14 +183,10 @@ pub(crate) async fn get_asset_for_addresses( addresses: &Vec, ) -> Result, Rejection> { debug!("{addresses:?}"); - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - let mut utxos = TransactionUnspentOutputs::new(); for a in addresses { - let us = dp.script_utxos(a).await.unwrap(); + let us = data_provider()?.script_utxos(a).await?; utxos.merge(us); } @@ -219,7 +209,7 @@ pub(crate) async fn get_asset_for_addresses( let k = assets.keys(); for a in 0..k.len() { let asset = k.get(a); - let amt = assets.get(&asset).unwrap(); + let amt = assets.get(&asset).unwrap(); let fingerprint = make_fingerprint(&policy.to_hex(), &hex::encode(asset.name())).unwrap(); // Deactivated Metadata Requests for performance @@ -302,13 +292,9 @@ pub async fn handle_asset_for_stake_address( } }; - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - // dp //.wallet_utxos(&reward_address.to_bech32(None).unwrap()) let utxos = match get_stake_address_utxos_dep( - dp.provider(), + data_provider()?.provider(), &reward_address.to_bech32(None).unwrap(), ) { Ok(u) => u, @@ -395,18 +381,15 @@ pub async fn handle_asset_for_stake_address( #[get("/pools/{page}")] #[openapi( - id = "api.info.pools", + id = "api.info.pools_one_page", tags("Stake Pool"), - summary = "Get Stake Pool List" + summary = "Get Stake Pool List (specified page)" )] pub async fn retrieve_active_pools( page: usize, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - let pools = crate::dbsync::get_pools(dp.provider()).await.unwrap(); + let pools = crate::dbsync::get_pools(data_provider()?.provider()).await?; let pools_paged: Vec> = pools.chunks(100).map(|s| s.into()).collect(); if pools_paged.len() < page { return make_error( @@ -418,6 +401,20 @@ pub async fn retrieve_active_pools( Ok(rweb::Json::from(json!(pools_paged[page]))) } +#[get("/pools/pages")] +#[openapi( + id = "api.info.pools_all_pages", + tags("Stake Pool"), + summary = "Get Stake Pool List (all pages)" +)] +pub async fn retrieve_active_pools_all_pages( + #[filter = "with_auth"] _user_id: String, +) -> Result, Rejection> { + let pools = crate::dbsync::get_pools(data_provider()?.provider()).await?; + let pools_paged: Vec> = pools.chunks(100).map(|s| s.into()).collect(); + Ok(rweb::Json::from(json!(pools_paged))) +} + #[get("/tokens/supply/{fingerprint}")] #[openapi( id = "api.info.tokens.supply", @@ -428,10 +425,7 @@ pub async fn token_supply( fingerprint: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - let supply = crate::dbsync::token_supply(dp.provider(), &fingerprint).await; + let supply = crate::dbsync::token_supply(data_provider()?.provider(), &fingerprint).await; if let Err(e) = &supply { return make_error( format!("Could not get supply for {:?}", e.to_string()), @@ -439,7 +433,7 @@ pub async fn token_supply( None, ); } - Ok(rweb::Json::from(json!(supply.unwrap()))) + Ok(rweb::Json::from(json!(supply?))) } #[get("/tokens/isNft/")] @@ -462,13 +456,9 @@ pub async fn is_nft( ); } }; - debug!("Creatign dataprovider instance"); - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); debug!("Try to execute query"); let supply = crate::dbsync::is_nft( - dp.provider(), + data_provider()?.provider(), &f.iter().map(|n| &**n).collect::>()[..], ) .await; @@ -480,7 +470,7 @@ pub async fn is_nft( None, ); } - Ok(rweb::Json::from(json!(supply.unwrap()))) + Ok(rweb::Json::from(json!(supply?))) } #[get("/epoch/stake/amount/{stake_addr}/{epoch}")] @@ -494,14 +484,10 @@ pub async fn retrieve_staked_amount( stake_addr: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - dbg!(epoch.clone()); dbg!(stake_addr.clone()); - let staked_amount = dp + let staked_amount = data_provider()? .retrieve_staked_amount(epoch, &stake_addr) .await .map_err(|_| RESTError::Custom("Couldn't find staked amount".to_string()))?; @@ -520,11 +506,7 @@ pub async fn retrieve_generated_rewards( stake_addr: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let generated_rewards = dp + let generated_rewards = data_provider()? .retrieve_generated_rewards(&stake_addr) .await .map_err(|_| RESTError::Custom("Couldn't find generated rewards".to_string()))?; @@ -542,11 +524,7 @@ pub async fn pool_vrf_key_hash( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_vrf_key_hash = dp + let pool_vrf_key_hash = data_provider()? .pool_vrf_key_hash(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find pools VRF key hash".to_string()))?; @@ -564,11 +542,7 @@ pub async fn pool_blocks_minted( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_blocks_minted = dp + let pool_blocks_minted = data_provider()? .pool_blocks_minted(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the total number of blocks minted by the given pool".to_string()))?; @@ -586,11 +560,7 @@ pub async fn pool_blocks_current_epoch( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_blocks_current_epoch = dp + let pool_blocks_current_epoch = data_provider()? .pool_blocks_current_epoch(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the quantity of blocks minted by the given pool in current epoch".to_string()))?; @@ -598,7 +568,42 @@ pub async fn pool_blocks_current_epoch( Ok(rweb::Json::from(json!(pool_blocks_current_epoch))) } -// #[get("pool/live_delegators/{pool_hash}")] // TODO: FixMe (start with dbsync/api.rs) +#[get("/pool/pool_reward_recipients/{pool_hash}")] +#[openapi( + id = "api.info.pool.pool_reward_recipients", + tags("Pool"), + summary = "The quantity of delegators that received rewards last time (epoch) the given pool was a slot leader." +)] +pub async fn pool_reward_recipients( + pool_hash: String, + #[filter = "with_auth"] _user_id: String, +) -> Result, Rejection> { + let pool_reward_recipients = data_provider()? + .pool_reward_recipients(&pool_hash) + .await + .map_err(|_| RESTError::Custom("Couldn't find the quantity of delegators that received rewards".to_string()))?; + + Ok(rweb::Json::from(json!(pool_reward_recipients))) +} + +#[get("/pool/last_reward_earned_epoch/{pool_hash}")] +#[openapi( + id = "api.info.pool.last_reward_earned_epoch", + tags("Pool"), + summary = "The last epoch when the given pool gave rewards to delegators" +)] +pub async fn pool_last_reward_earned_epoch( + pool_hash: String, + #[filter = "with_auth"] _user_id: String, +) -> Result, Rejection> { + let pool_last_reward_earned_epoch = data_provider()? + .pool_last_reward_earned_epoch(&pool_hash) + .await + .map_err(|_| RESTError::Custom("Couldn't find the last epoch when the given pool distributed rewards".to_string()))?; + + Ok(rweb::Json::from(json!(pool_last_reward_earned_epoch))) +} + #[get("/pool/declared_pledge/{pool_hash}")] #[openapi( @@ -610,11 +615,7 @@ pub async fn pool_declared_pledge( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_declared_pledge = dp + let pool_declared_pledge = data_provider()? .pool_declared_pledge(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the amount of Ada pledged by the given pool".to_string()))?; @@ -632,11 +633,7 @@ pub async fn pool_margin_cost( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_margin_cost = dp + let pool_margin_cost = data_provider()? .pool_margin_cost(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the margin cost of the given pool".to_string()))?; @@ -654,11 +651,7 @@ pub async fn pool_fixed_cost( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_fixed_cost = dp + let pool_fixed_cost = data_provider()? .pool_fixed_cost(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the fixed cost of the given pool".to_string()))?; @@ -676,11 +669,7 @@ pub async fn pool_reward_address( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_reward_address = dp + let pool_reward_address = data_provider()? .pool_reward_address(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the reward address of the given pool".to_string()))?; @@ -698,11 +687,7 @@ pub async fn pool_owner( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_owner = dp + let pool_owner = data_provider()? .pool_owner(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the owner of the given pool".to_string()))?; @@ -720,11 +705,7 @@ pub async fn pool_registration( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_registration = dp + let pool_registration = data_provider()? .pool_registration(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the epoch in which the given pool made its latest registration".to_string()))?; @@ -742,11 +723,7 @@ pub async fn pool_retirement( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_retirement = dp + let pool_retirement = data_provider()? .pool_retirement(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the epoch in which the given pool retired".to_string()))?; @@ -764,11 +741,7 @@ pub async fn pool_url( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_url = dp + let pool_url = data_provider()? .pool_url(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the url in which the given pool stores its metadata".to_string()))?; @@ -786,11 +759,7 @@ pub async fn pool_ticker( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_ticker = dp + let pool_ticker = data_provider()? .pool_ticker(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the ticker of the given stake pool".to_string()))?; @@ -808,11 +777,7 @@ pub async fn pool_metadata_json( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_metadata_json = dp + let pool_metadata_json = data_provider()? .pool_metadata_json(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the metadata JSON of the given stake pool".to_string()))?; @@ -830,11 +795,7 @@ pub async fn pool_name( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_name = dp + let pool_name = data_provider()? .pool_name(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the name of the given stake pool".to_string()))?; @@ -852,11 +813,7 @@ pub async fn pool_homepage( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_homepage = dp + let pool_homepage = data_provider()? .pool_homepage(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the homepage of the given stake pool".to_string()))?; @@ -874,11 +831,7 @@ pub async fn pool_description( pool_hash: String, #[filter = "with_auth"] _user_id: String, ) -> Result, Rejection> { - let dp = crate::DataProvider::new(crate::DBSyncProvider::new(crate::Config { - db_path: std::env::var("DBSYNC_URL").unwrap(), - })); - - let pool_description = dp + let pool_description = data_provider()? .pool_description(&pool_hash) .await .map_err(|_| RESTError::Custom("Couldn't find the description of the given stake pool".to_string()))?; diff --git a/src/server/handler/handler_rest/mod.rs b/src/server/handler/handler_rest/mod.rs index f427310..53fc477 100644 --- a/src/server/handler/handler_rest/mod.rs +++ b/src/server/handler/handler_rest/mod.rs @@ -3,11 +3,12 @@ pub(crate) mod info; use info::{ address_exists, handle_asset_for_stake_address, handle_get_asset_for_addresses, is_nft, - mint_metadata, retrieve_active_pools, token_supply, tx_history, tx_history_discover, - utxos_per_addr, retrieve_staked_amount, retrieve_generated_rewards, pool_vrf_key_hash, - pool_blocks_minted, pool_blocks_current_epoch, pool_declared_pledge, pool_margin_cost, - pool_fixed_cost, pool_reward_address, pool_owner, pool_registration, pool_retirement, - pool_url, pool_ticker, pool_metadata_json, pool_name, pool_homepage, pool_description, + mint_metadata, retrieve_active_pools, retrieve_active_pools_all_pages, token_supply, tx_history, + tx_history_discover, utxos_per_addr, retrieve_staked_amount, retrieve_generated_rewards, pool_vrf_key_hash, + pool_blocks_minted, pool_blocks_current_epoch, pool_reward_recipients, pool_last_reward_earned_epoch, + pool_declared_pledge, pool_margin_cost, pool_fixed_cost, pool_reward_address, pool_owner, + pool_registration, pool_retirement, pool_url, pool_ticker, pool_metadata_json, pool_name, + pool_homepage, pool_description, }; use rweb::*; @@ -24,12 +25,15 @@ use rweb::*; handle_asset_for_stake_address, handle_get_asset_for_addresses, retrieve_active_pools, + retrieve_active_pools_all_pages, is_nft, retrieve_staked_amount, retrieve_generated_rewards, - pool_vrf_key_hash, + pool_vrf_key_hash, pool_blocks_minted, pool_blocks_current_epoch, + pool_reward_recipients, + pool_last_reward_earned_epoch, pool_declared_pledge, pool_margin_cost, pool_fixed_cost,