From ff27aee6964de13f0ab77b9ab4e5111f9ceacac4 Mon Sep 17 00:00:00 2001 From: nagarajm22 Date: Tue, 12 Dec 2023 11:50:21 +0800 Subject: [PATCH 01/12] added block indexing --- lib/ain-evm/src/storage/block_store.rs | 1 - lib/ain-ocean/src/data_acces/block.rs | 123 ++++++++++-- .../src/data_acces/test/block_test.rs | 185 ++++++++++++++++++ lib/ain-ocean/src/data_acces/test/mod.rs | 1 + lib/ain-ocean/src/model/block.rs | 2 +- 5 files changed, 298 insertions(+), 14 deletions(-) create mode 100644 lib/ain-ocean/src/data_acces/test/block_test.rs diff --git a/lib/ain-evm/src/storage/block_store.rs b/lib/ain-evm/src/storage/block_store.rs index a3576dcf67b..196fcc45424 100644 --- a/lib/ain-evm/src/storage/block_store.rs +++ b/lib/ain-evm/src/storage/block_store.rs @@ -117,7 +117,6 @@ impl BlockStorage for BlockStore { fn put_block(&self, block: &BlockAny) -> Result<()> { self.extend_transactions_from_block(block)?; - let block_number = block.header.number; let hash = block.header.hash(); let blocks_cf = self.column::(); diff --git a/lib/ain-ocean/src/data_acces/block.rs b/lib/ain-ocean/src/data_acces/block.rs index 41b4415a1a4..22f646e4ad9 100644 --- a/lib/ain-ocean/src/data_acces/block.rs +++ b/lib/ain-ocean/src/data_acces/block.rs @@ -1,5 +1,11 @@ -use anyhow::{anyhow, Result}; +use crate::database::db_manger::ColumnFamilyOperations; +use crate::database::db_manger::RocksDB; +use crate::model::block::Block; +use anyhow::{anyhow, Error, Result}; +use rocksdb::{DBIteratorWithThreadMode, IteratorMode}; use serde::{Deserialize, Serialize}; +use std::convert::TryInto; +use std::hash; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -12,32 +18,125 @@ pub struct BlockDb { } impl BlockDb { - pub async fn get_by_hash(&self) -> Result { - todo!() + pub async fn get_by_hash(&self, hash: String) -> Result> { + let number = match self.db.get("block_map", hash.as_bytes()) { + Ok(Some(value)) => { + // Convert the stored bytes to a block number + let block_number_bytes: [u8; 4] = match value.try_into() { + Ok(bytes) => bytes, + Err(e) => { + return Err(anyhow!("Error converting bytes to block number: {:?}", e)) + } + }; + let block_number = i32::from_be_bytes(block_number_bytes); + Some(block_number) + } + Ok(None) => None, + Err(e) => return Err(anyhow!("Error retrieving block number: {:?}", e)), + }; + + if let Some(block_number) = number { + let block_key = block_number.to_be_bytes(); + match self.db.get("block", &block_key) { + Ok(Some(value)) => { + let block: Block = serde_json::from_slice(&value).map_err(|e| anyhow!(e))?; + Ok(Some(block)) + } + Ok(None) => Ok(None), + Err(e) => Err(anyhow!(e)), + } + } else { + Ok(None) + } } - pub async fn get_by_height(&self) -> Result { - todo!() + + pub async fn get_by_height(&self, height: i32) -> Result> { + match self.db.get("block", &height.to_be_bytes()) { + Ok(Some(value)) => { + let block: Block = serde_json::from_slice(&value).map_err(|e| anyhow!(e))?; + Ok(Some(block)) + } + Ok(None) => Ok(None), + Err(e) => Err(anyhow!(e)), + } } pub async fn get_heighest(&self) -> Result { todo!() } + pub async fn query_by_height(&self, limit: i32, lt: i32) -> Result> { - todo!() + let mut blocks: Vec = Vec::new(); + + // Use the iterator method to create an iterator for the "blocks" column family + let iterator = self.db.iterator("block", IteratorMode::End)?; + + // Collect the iterator into a vector + let collected_blocks: Vec<_> = iterator.collect(); + + // Iterate over the collected vector in reverse + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + // Deserialize the block + let block: Block = serde_json::from_slice(&value)?; + + // Check height conditions + if block.height < lt { + // Collect blocks that meet the conditions + blocks.push(block.clone()); + + // Check if the limit is reached + if blocks.len() == limit as usize { + break; + } + } + } + + Ok(blocks) } - pub async fn store_block(&self, block: Block) -> Result<()> { + + pub async fn put_block(&self, block: Block) -> Result<()> { match serde_json::to_string(&block) { Ok(value) => { - let key = block.id.clone(); - self.db.put("raw_block", key.as_bytes(), value.as_bytes())?; + let block_number = block.height; + self.db + .put("block", &block_number.to_be_bytes(), value.as_bytes())?; + let block_map_key = block.hash.as_bytes(); + self.db + .put("block_map", block_map_key, &block_number.to_be_bytes())?; Ok(()) } Err(e) => Err(anyhow!(e)), } } pub async fn delete_block(&self, hash: String) -> Result<()> { - match self.db.delete("raw_block", hash.as_bytes()) { - Ok(_) => Ok(()), - Err(e) => Err(anyhow!(e)), + let number = match self.db.get("block_map", hash.as_bytes()) { + Ok(Some(value)) => { + // Convert the stored bytes to a block number + let block_number_bytes: [u8; 4] = match value.try_into() { + Ok(bytes) => bytes, + Err(e) => { + return Err(anyhow!("Error converting bytes to block number: {:?}", e)) + } + }; + let block_number = i32::from_be_bytes(block_number_bytes); + Some(block_number) + } + Ok(None) => None, + Err(e) => return Err(anyhow!("Error retrieving block number: {:?}", e)), + }; + + if let Some(block_number) = number { + let block_key = block_number.to_be_bytes(); + match self.db.delete("block", &block_key) { + Ok(_) => Ok(()), + Err(e) => Err(anyhow!(e)), + } + } else { + Ok(()) } } } diff --git a/lib/ain-ocean/src/data_acces/test/block_test.rs b/lib/ain-ocean/src/data_acces/test/block_test.rs new file mode 100644 index 00000000000..9e8e07fe416 --- /dev/null +++ b/lib/ain-ocean/src/data_acces/test/block_test.rs @@ -0,0 +1,185 @@ +#[cfg(test)] +mod tests { + use super::*; + use crate::data_acces::block::BlockDb; + use crate::database::db_manger::{ColumnFamilyOperations, RocksDB}; + use crate::model::block::Block; + use tempdir::TempDir; + + pub fn create_dummy_block(height: i32) -> Block { + Block { + id: "1".to_string(), + hash: "block_hash_1".to_string(), + previous_hash: "previous_block_hash".to_string(), + height: height, + version: 1, + time: 1634054400, // Replace with an actual timestamp + median_time: 1634054400, // Replace with an actual timestamp + transaction_count: 10, + difficulty: 12345, + masternode: "masternode_address".to_string(), + minter: "minter_address".to_string(), + minter_block_count: 5, + reward: "10.0".to_string(), + stake_modifier: "stake_modifier_value".to_string(), + merkleroot: "merkleroot_value".to_string(), + size: 2000, + size_stripped: 1800, + weight: 1900, + } + } + + #[tokio::test] + async fn test_put_get_by_hash_and_height() { + // Create a temporary RocksDB instance for testing + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Create a dummy block for testing + let dummy_block = create_dummy_block(1); + + // Test the put_block method + block_db.put_block(dummy_block.clone()).await.unwrap(); + + // Test the get_by_hash method + let result_by_hash = block_db + .get_by_hash(dummy_block.hash.clone()) + .await + .unwrap(); + assert_eq!(result_by_hash.unwrap(), dummy_block.clone()); + + // Test the get_by_height method + let result_by_height = block_db.get_by_height(dummy_block.height).await.unwrap(); + assert_eq!(result_by_height.unwrap(), dummy_block); + } + + #[tokio::test] + async fn test_get_nonexistent_block_by_hash() { + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Attempt to get a block using a hash that doesn't exist + let result = block_db + .get_by_hash("nonexistent_hash".to_string()) + .await + .unwrap(); + assert_eq!(result, None); + } + + #[tokio::test] + async fn test_get_nonexistent_block_by_height() { + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Attempt to get a block using a height that doesn't exist + let result = block_db.get_by_height(999).await.unwrap(); + assert_eq!(result, None); + } + + #[tokio::test] + async fn test_delete_block() { + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Create a dummy block for testing + let dummy_block = create_dummy_block(1); + + // Put the block + block_db.put_block(dummy_block.clone()).await.unwrap(); + + // Delete the block + block_db + .delete_block(dummy_block.hash.clone()) + .await + .unwrap(); + + // Attempt to get the block after deletion + let result_by_hash = block_db + .get_by_hash(dummy_block.hash.clone()) + .await + .unwrap(); + + assert!(result_by_hash.is_none()); + } + + #[tokio::test] + async fn test_query_by_height() { + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Create dummy blocks for testing + let block1 = create_dummy_block(1); + let block2 = create_dummy_block(2); + let block3 = create_dummy_block(3); + + // Put the blocks + block_db.put_block(block1.clone()).await.unwrap(); + block_db.put_block(block2.clone()).await.unwrap(); + block_db.put_block(block3.clone()).await.unwrap(); + + // Test query_by_height with limit and lt conditions + let result = block_db.query_by_height(2, 3).await.unwrap(); + + // Assert the result contains the correct blocks in the correct order + assert_eq!(result, vec![block2, block1]); + } + + #[tokio::test] + async fn test_query_by_height_with_limit_and_lt() { + // Create a temporary RocksDB instance for testing + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Insert dummy blocks into the "blocks" column family + for height in 1..=10 { + let dummy_block = create_dummy_block(height); + block_db.put_block(dummy_block.clone()).await.unwrap(); + } + + // Test the query_by_height method + let result = block_db.query_by_height(5, 8).await.unwrap(); + + // Check if the result has the expected length + assert_eq!(result.len(), 5); + + // Check if the blocks are sorted in descending order by height + for i in 0..result.len() - 1 { + assert!(result[i].height >= result[i + 1].height); + } + } + + #[tokio::test] + async fn test_query_by_height_new_method() { + // Create a temporary RocksDB instance for testing + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; + + // Create dummy blocks with heights 1 to 5 and insert them into the database + for height in 1..=5 { + let dummy_block = create_dummy_block(height); + block_db.put_block(dummy_block.clone()).await.unwrap(); + } + + // Test the query_by_height method + let result_blocks = block_db.query_by_height(3, 4).await.unwrap(); + + // Verify that the result contains the expected blocks + assert_eq!(result_blocks.len(), 3); + assert_eq!(result_blocks[0].height, 4); + assert_eq!(result_blocks[1].height, 3); + } +} diff --git a/lib/ain-ocean/src/data_acces/test/mod.rs b/lib/ain-ocean/src/data_acces/test/mod.rs index bd9b68cbdc5..01063ce2f0e 100644 --- a/lib/ain-ocean/src/data_acces/test/mod.rs +++ b/lib/ain-ocean/src/data_acces/test/mod.rs @@ -1,2 +1,3 @@ +mod block_test; mod oracle_test; mod transaction_test; diff --git a/lib/ain-ocean/src/model/block.rs b/lib/ain-ocean/src/model/block.rs index 55517511da5..bf542a2c276 100644 --- a/lib/ain-ocean/src/model/block.rs +++ b/lib/ain-ocean/src/model/block.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Block { pub id: String, From ad474a864692637ea6453f51009cddb5d946800f Mon Sep 17 00:00:00 2001 From: nagarajm22 Date: Tue, 12 Dec 2023 13:46:27 +0800 Subject: [PATCH 02/12] added block indexing and query method --- lib/ain-ocean/src/data_acces/block.rs | 68 +++++++++---- .../src/data_acces/test/block_test.rs | 97 ++++++++++++------- 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/lib/ain-ocean/src/data_acces/block.rs b/lib/ain-ocean/src/data_acces/block.rs index 22f646e4ad9..b76f3f60253 100644 --- a/lib/ain-ocean/src/data_acces/block.rs +++ b/lib/ain-ocean/src/data_acces/block.rs @@ -4,14 +4,14 @@ use crate::model::block::Block; use anyhow::{anyhow, Error, Result}; use rocksdb::{DBIteratorWithThreadMode, IteratorMode}; use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; use std::convert::TryInto; use std::hash; -use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, - model::block::Block, -}; - +pub enum SortOrder { + Ascending, + Descending, +} #[derive(Debug)] pub struct BlockDb { pub db: RocksDB, @@ -60,41 +60,68 @@ impl BlockDb { Err(e) => Err(anyhow!(e)), } } - pub async fn get_heighest(&self) -> Result { - todo!() + + pub async fn get_highest(&self) -> Result> { + // Retrieve the latest block height + let latest_height_bytes = match self.db.get("latest_block_height", b"latest_block_height") { + Ok(Some(value)) => value, + Ok(None) => return Ok(None), // No latest block height set + Err(e) => return Err(anyhow!(e)), + }; + + // Convert the latest height bytes back to an integer + let latest_height = i32::from_be_bytes( + latest_height_bytes + .as_slice() + .try_into() + .map_err(|_| anyhow!("Byte length mismatch for latest height"))?, + ); + + // Retrieve the block with the latest height + match self.db.get("block", &latest_height.to_be_bytes()) { + Ok(Some(value)) => { + let block: Block = serde_json::from_slice(&value).map_err(|e| anyhow!(e))?; + Ok(Some(block)) + } + Ok(None) => Ok(None), // No block found for the latest height + Err(e) => Err(anyhow!(e)), + } } - pub async fn query_by_height(&self, limit: i32, lt: i32) -> Result> { + pub async fn query_by_height( + &self, + limit: i32, + lt: i32, + sort_order: SortOrder, + ) -> Result> { let mut blocks: Vec = Vec::new(); - // Use the iterator method to create an iterator for the "blocks" column family let iterator = self.db.iterator("block", IteratorMode::End)?; - - // Collect the iterator into a vector let collected_blocks: Vec<_> = iterator.collect(); - // Iterate over the collected vector in reverse for result in collected_blocks.into_iter().rev() { let (key, value) = match result { Ok((key, value)) => (key, value), Err(err) => return Err(anyhow!("Error during iteration: {}", err)), }; - // Deserialize the block let block: Block = serde_json::from_slice(&value)?; - // Check height conditions if block.height < lt { - // Collect blocks that meet the conditions - blocks.push(block.clone()); + blocks.push(block); - // Check if the limit is reached if blocks.len() == limit as usize { break; } } } + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => blocks.sort_by(|a, b| a.height.cmp(&b.height)), + SortOrder::Descending => blocks.sort_by(|a, b| b.height.cmp(&a.height)), + } + Ok(blocks) } @@ -107,6 +134,13 @@ impl BlockDb { let block_map_key = block.hash.as_bytes(); self.db .put("block_map", block_map_key, &block_number.to_be_bytes())?; + self.db + .delete("latest_block_height", b"latest_block_height")?; + self.db.put( + "latest_block_height", + b"latest_block_height", + &block_number.to_be_bytes(), + )?; Ok(()) } Err(e) => Err(anyhow!(e)), diff --git a/lib/ain-ocean/src/data_acces/test/block_test.rs b/lib/ain-ocean/src/data_acces/test/block_test.rs index 9e8e07fe416..0e35e4b16f7 100644 --- a/lib/ain-ocean/src/data_acces/test/block_test.rs +++ b/lib/ain-ocean/src/data_acces/test/block_test.rs @@ -111,75 +111,106 @@ mod tests { } #[tokio::test] - async fn test_query_by_height() { + async fn test_query_by_height_descending() { + // Create a temporary RocksDB instance for testing let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) .expect("Failed to create RocksDB instance"); let block_db = BlockDb { db: rocksdb }; - // Create dummy blocks for testing - let block1 = create_dummy_block(1); - let block2 = create_dummy_block(2); - let block3 = create_dummy_block(3); - - // Put the blocks - block_db.put_block(block1.clone()).await.unwrap(); - block_db.put_block(block2.clone()).await.unwrap(); - block_db.put_block(block3.clone()).await.unwrap(); - - // Test query_by_height with limit and lt conditions - let result = block_db.query_by_height(2, 3).await.unwrap(); + // Create dummy blocks with heights 1 to 5 and insert them into the database + for height in 1..=10 { + let dummy_block = create_dummy_block(height); + block_db.put_block(dummy_block.clone()).await.unwrap(); + } - // Assert the result contains the correct blocks in the correct order - assert_eq!(result, vec![block2, block1]); + // Test the query_by_height method + let result_blocks = block_db + .query_by_height(3, 4, crate::data_acces::block::SortOrder::Descending) + .await + .unwrap(); + // Verify that the result contains the expected blocks + assert_eq!(result_blocks.len(), 3); + assert_eq!(result_blocks[0].height, 3); + assert_eq!(result_blocks[1].height, 2); } #[tokio::test] - async fn test_query_by_height_with_limit_and_lt() { + async fn test_query_by_height_ascending() { // Create a temporary RocksDB instance for testing let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) .expect("Failed to create RocksDB instance"); let block_db = BlockDb { db: rocksdb }; - // Insert dummy blocks into the "blocks" column family + // Create dummy blocks with heights 1 to 5 and insert them into the database for height in 1..=10 { let dummy_block = create_dummy_block(height); block_db.put_block(dummy_block.clone()).await.unwrap(); } // Test the query_by_height method - let result = block_db.query_by_height(5, 8).await.unwrap(); + let result_blocks = block_db + .query_by_height(5, 6, crate::data_acces::block::SortOrder::Ascending) + .await + .unwrap(); + // Verify that the result contains the expected blocks + assert_eq!(result_blocks.len(), 5); + assert_eq!(result_blocks[0].height, 1); + assert_eq!(result_blocks[1].height, 2); + } - // Check if the result has the expected length - assert_eq!(result.len(), 5); + #[tokio::test] + async fn test_put_block_updates_latest_height() { + // Setup test environment + let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); + let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) + .expect("Failed to create RocksDB instance"); + let block_db = BlockDb { db: rocksdb }; - // Check if the blocks are sorted in descending order by height - for i in 0..result.len() - 1 { - assert!(result[i].height >= result[i + 1].height); + // Create and insert sample blocks + for height in 1..=10 { + let dummy_block = create_dummy_block(height); + block_db.put_block(dummy_block).await.unwrap(); } + + // Retrieve latest block height + let latest_height_bytes = block_db + .db + .get("latest_block_height", b"latest_block_height") + .expect("Failed to retrieve latest block height") + .expect("Latest block height not found"); + let latest_height = i32::from_be_bytes( + latest_height_bytes + .as_slice() + .try_into() + .expect("Byte length mismatch"), + ); + + // Assert correctness + assert_eq!(latest_height, 10); // Assert that latest height is 10 } #[tokio::test] - async fn test_query_by_height_new_method() { - // Create a temporary RocksDB instance for testing + async fn test_get_highest_retrieves_correct_block() -> Result<(), Box> { + // Setup test environment let temp_dir = TempDir::new("test_rocksdb").expect("Failed to create temp directory"); let rocksdb = RocksDB::new(temp_dir.path().to_str().unwrap()) .expect("Failed to create RocksDB instance"); let block_db = BlockDb { db: rocksdb }; - // Create dummy blocks with heights 1 to 5 and insert them into the database + // Insert sample blocks for height in 1..=5 { let dummy_block = create_dummy_block(height); - block_db.put_block(dummy_block.clone()).await.unwrap(); + block_db.put_block(dummy_block).await.unwrap(); } - // Test the query_by_height method - let result_blocks = block_db.query_by_height(3, 4).await.unwrap(); + // Call get_highest + let highest_block = block_db.get_highest().await.unwrap().unwrap(); - // Verify that the result contains the expected blocks - assert_eq!(result_blocks.len(), 3); - assert_eq!(result_blocks[0].height, 4); - assert_eq!(result_blocks[1].height, 3); + // Assert that the highest block is the one with height 5 + assert_eq!(highest_block.height, 5); + + Ok(()) } } From 31a8710f8f45771b22ce6fa5b744924860e8dddc Mon Sep 17 00:00:00 2001 From: nagarajm22 Date: Tue, 12 Dec 2023 21:59:18 +0800 Subject: [PATCH 03/12] added query methods and extra table --- lib/ain-ocean/Cargo.toml | 2 + lib/ain-ocean/src/data_acces/block.rs | 6 +- lib/ain-ocean/src/data_acces/masternode.rs | 40 +++++++- .../src/data_acces/masternode_states.rs | 92 +++++++++++++++---- lib/ain-ocean/src/data_acces/oracle.rs | 33 ++++++- .../oracle_price_aggregated_interval.rs | 27 +++++- .../src/data_acces/test/block_test.rs | 5 +- .../src/data_acces/test/transaction_test.rs | 16 ++++ lib/ain-ocean/src/data_acces/transaction.rs | 63 ++++++++++--- .../src/data_acces/transaction_vin.rs | 45 ++++++++- .../src/data_acces/transaction_vout.rs | 68 ++++++++++---- 11 files changed, 335 insertions(+), 62 deletions(-) diff --git a/lib/ain-ocean/Cargo.toml b/lib/ain-ocean/Cargo.toml index 3ecf06c9b23..e85195fa9b6 100644 --- a/lib/ain-ocean/Cargo.toml +++ b/lib/ain-ocean/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[profile.test] +debug = true [dependencies] ain-cpp-imports.workspace = true diff --git a/lib/ain-ocean/src/data_acces/block.rs b/lib/ain-ocean/src/data_acces/block.rs index b76f3f60253..28c0484d644 100644 --- a/lib/ain-ocean/src/data_acces/block.rs +++ b/lib/ain-ocean/src/data_acces/block.rs @@ -1,5 +1,5 @@ use crate::database::db_manger::ColumnFamilyOperations; -use crate::database::db_manger::RocksDB; +use crate::database::db_manger::{RocksDB, SortOrder}; use crate::model::block::Block; use anyhow::{anyhow, Error, Result}; use rocksdb::{DBIteratorWithThreadMode, IteratorMode}; @@ -8,10 +8,6 @@ use std::cmp::Ordering; use std::convert::TryInto; use std::hash; -pub enum SortOrder { - Ascending, - Descending, -} #[derive(Debug)] pub struct BlockDb { pub db: RocksDB, diff --git a/lib/ain-ocean/src/data_acces/masternode.rs b/lib/ain-ocean/src/data_acces/masternode.rs index c2e7466a63d..a853a3422f7 100644 --- a/lib/ain-ocean/src/data_acces/masternode.rs +++ b/lib/ain-ocean/src/data_acces/masternode.rs @@ -1,5 +1,8 @@ +use crate::database::db_manger::ColumnFamilyOperations; +use crate::database::db_manger::{RocksDB, SortOrder}; +use crate::model::masternode::Masternode; use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use serde_json; use crate::{ @@ -12,8 +15,39 @@ pub struct MasterNodeDB { } impl MasterNodeDB { - pub async fn query(&self, limit: i32, lt: i32) -> Result> { - todo!() + pub async fn query( + &self, + limit: i32, + lt: i32, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("masternode", IteratorMode::End)?; + let mut master_node: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let master_stats: Masternode = serde_json::from_slice(&value)?; + master_node.push(master_stats); + + if master_node.len() == limit as usize { + break; + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => master_node.sort_by(|a, b| a.block.height.cmp(&b.block.height)), + SortOrder::Descending => { + master_node.sort_by(|a, b| b.block.height.cmp(&a.block.height)) + } + } + + Ok(master_node) } pub async fn get(&self, id: String) -> Result> { match self.db.get("masternode", id.as_bytes()) { diff --git a/lib/ain-ocean/src/data_acces/masternode_states.rs b/lib/ain-ocean/src/data_acces/masternode_states.rs index 8fb54b2a779..b6c7439bd37 100644 --- a/lib/ain-ocean/src/data_acces/masternode_states.rs +++ b/lib/ain-ocean/src/data_acces/masternode_states.rs @@ -1,7 +1,11 @@ +use crate::database::db_manger::ColumnFamilyOperations; +use crate::database::db_manger::{RocksDB, SortOrder}; +use crate::model::masternode_stats::MasternodeStats; use anyhow::{anyhow, Result}; use bitcoin::absolute::Height; use rocksdb::{ColumnFamilyDescriptor, IteratorMode, DB}; use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -13,25 +17,71 @@ pub struct MasterStatsDb { pub db: RocksDB, } impl MasterStatsDb { - pub async fn get_latest(&self) -> Result { - // let mut latest_stats: Option = None; - // let mut highest_height = -1; + pub async fn get_latest(&self) -> Result> { + let latest_height_bytes = match self + .db + .get("masternode_block_height", b"master_block_height") + { + Ok(Some(value)) => value, + Ok(None) => return Ok(None), // No latest block height set + Err(e) => return Err(anyhow!(e)), + }; - // let iter = self.db.iterator("masternode_stats", IteratorMode::End); // Start from the end of the DB + // Convert the latest height bytes back to an integer + let latest_height = i32::from_be_bytes( + latest_height_bytes + .as_slice() + .try_into() + .map_err(|_| anyhow!("Byte length mismatch for latest height"))?, + ); - // for (key, value) in iter { - // let stats: MasternodeStats = serde_json::from_slice(&value)?; - // if stats.block.height > highest_height { - // highest_height = stats.block.height; - // latest_stats = Some(stats); - // } - // } - - // Ok(latest_stats); - todo!() + // Retrieve the block with the latest height + match self.db.get("block", &latest_height.to_be_bytes()) { + Ok(Some(value)) => { + let block: MasternodeStats = + serde_json::from_slice(&value).map_err(|e| anyhow!(e))?; + Ok(Some(block)) + } + Ok(None) => Ok(None), // No block found for the latest height + Err(e) => Err(anyhow!(e)), + } } - pub async fn query(&self, limit: i32, lt: i32) -> Result> { - todo!() + pub async fn query( + &self, + limit: i32, + lt: i32, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("masternode_stats", IteratorMode::End)?; + let mut master_node: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let master_stats: MasternodeStats = serde_json::from_slice(&value)?; + + if master_stats.block.height < lt { + master_node.push(master_stats); + + if master_node.len() == limit as usize { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => master_node.sort_by(|a, b| a.block.height.cmp(&b.block.height)), + SortOrder::Descending => { + master_node.sort_by(|a, b| b.block.height.cmp(&a.block.height)) + } + } + + Ok(master_node) } pub async fn get(&self, height: i32) -> Result> { let bytes: &[u8] = &height.to_be_bytes(); @@ -49,8 +99,14 @@ impl MasterStatsDb { match serde_json::to_string(&stats) { Ok(value) => { let key = stats.block.height.clone(); - let bytes: &[u8] = &key.to_be_bytes(); - self.db.put("masternode_stats", bytes, value.as_bytes())?; + let height: &[u8] = &key.to_be_bytes(); + self.db.put("masternode_stats", height, value.as_bytes())?; + self.db + .put("masternode_map", stats.block.hash.as_bytes(), height)?; + self.db + .delete("masternode_block_height", b"master_block_height")?; + self.db + .put("masternode_block_height", b"master_block_height", height)?; Ok(()) } Err(e) => Err(anyhow!(e)), diff --git a/lib/ain-ocean/src/data_acces/oracle.rs b/lib/ain-ocean/src/data_acces/oracle.rs index 2d9badd0927..2952e4ce7d8 100644 --- a/lib/ain-ocean/src/data_acces/oracle.rs +++ b/lib/ain-ocean/src/data_acces/oracle.rs @@ -1,4 +1,5 @@ use anyhow::{anyhow, Error, Result}; +use rocksdb::IteratorMode; use serde::{Deserialize, Serialize}; use serde_json; @@ -12,9 +13,37 @@ pub struct OracleDb { } impl OracleDb { - pub async fn query(&self, limit: i32, lt: String) -> Result> { - todo!() + pub async fn query( + &self, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("oracle", IteratorMode::End)?; + let mut oracles: Vec = Vec::new(); + let collected_items: Vec<_> = iterator.collect(); + + for result in collected_items.into_iter().rev() { + let value = match result { + Ok((_, value)) => value, + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle: Oracle = serde_json::from_slice(&value)?; + oracles.push(oracle); + if oracles.len() as i32 >= limit { + break; + } + } + + match sort_order { + SortOrder::Ascending => oracles.sort_by(|a, b| a.id.cmp(&b.id)), + SortOrder::Descending => oracles.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(oracles) } + pub async fn store(&self, oracle: Oracle) -> Result<()> { match serde_json::to_string(&oracle) { Ok(value) => { diff --git a/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs b/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs index cb36cf9c3d0..73136a66846 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs @@ -1,4 +1,5 @@ use anyhow::{anyhow, Result}; +use rocksdb::{ColumnFamilyDescriptor, IteratorMode, DB}; use serde::{Deserialize, Serialize}; use crate::{ @@ -17,7 +18,31 @@ impl OraclePriceAggregatedIntervalDb { limit: i32, lt: String, ) -> Result> { - todo!() + let iterator = self + .db + .iterator("oracle_price_aggregated_interval", IteratorMode::End)?; + let mut oracle_prices: Vec = Vec::new(); + let collected_items: Vec<_> = iterator.collect(); + + for result in collected_items.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle_price: OraclePriceAggregatedInterval = serde_json::from_slice(&value)?; + + // Check if the id is less than 'lt' + if String::from_utf8(key.to_vec())? < lt { + oracle_prices.push(oracle_price); + + if oracle_prices.len() == limit as usize { + break; + } + } + } + + Ok(oracle_prices) } pub async fn put(&self, oracle: OraclePriceAggregatedInterval) -> Result<()> { match serde_json::to_string(&oracle) { diff --git a/lib/ain-ocean/src/data_acces/test/block_test.rs b/lib/ain-ocean/src/data_acces/test/block_test.rs index 0e35e4b16f7..9e00bdcdce8 100644 --- a/lib/ain-ocean/src/data_acces/test/block_test.rs +++ b/lib/ain-ocean/src/data_acces/test/block_test.rs @@ -2,6 +2,7 @@ mod tests { use super::*; use crate::data_acces::block::BlockDb; + use crate::database::db_manger::SortOrder; use crate::database::db_manger::{ColumnFamilyOperations, RocksDB}; use crate::model::block::Block; use tempdir::TempDir; @@ -126,7 +127,7 @@ mod tests { // Test the query_by_height method let result_blocks = block_db - .query_by_height(3, 4, crate::data_acces::block::SortOrder::Descending) + .query_by_height(3, 4, SortOrder::Descending) .await .unwrap(); // Verify that the result contains the expected blocks @@ -151,7 +152,7 @@ mod tests { // Test the query_by_height method let result_blocks = block_db - .query_by_height(5, 6, crate::data_acces::block::SortOrder::Ascending) + .query_by_height(5, 6, SortOrder::Ascending) .await .unwrap(); // Verify that the result contains the expected blocks diff --git a/lib/ain-ocean/src/data_acces/test/transaction_test.rs b/lib/ain-ocean/src/data_acces/test/transaction_test.rs index bde9c788fba..e87196a35a2 100644 --- a/lib/ain-ocean/src/data_acces/test/transaction_test.rs +++ b/lib/ain-ocean/src/data_acces/test/transaction_test.rs @@ -100,4 +100,20 @@ mod tests { let result = txn_vin_db.delete(trx_id).await; assert!(result.is_ok()); } + + #[tokio::test] + async fn test_query_transaction() { + let txn_vin_db = setup_test_db(); + + let test_transaction = sample_transaction("tx1"); + let trx_id = test_transaction.id.clone(); + + let result = txn_vin_db.store(test_transaction.clone()).await; + assert!(result.is_ok()); + + let result = txn_vin_db + .query_by_block_hash(test_transaction.block.hash.to_string(), 10, 0) + .await; + assert!(result.is_ok()); + } } diff --git a/lib/ain-ocean/src/data_acces/transaction.rs b/lib/ain-ocean/src/data_acces/transaction.rs index 061074eb125..487a954c4a6 100644 --- a/lib/ain-ocean/src/data_acces/transaction.rs +++ b/lib/ain-ocean/src/data_acces/transaction.rs @@ -23,15 +23,29 @@ impl TransactionVinDb { } } pub async fn store(&self, txn: Transaction) -> Result<()> { - match serde_json::to_string(&txn) { - Ok(value) => { - let key = txn.id.clone(); - self.db - .put("transaction", key.as_bytes(), value.as_bytes())?; - Ok(()) - } - Err(e) => Err(anyhow!(e)), - } + let value = serde_json::to_string(&txn)?; + let txid_key = txn.txid.clone(); + self.db + .put("transaction", txid_key.as_bytes(), value.as_bytes())?; + + // Retrieve existing transaction IDs for the block hash, if any + let mut txn_ids = match self + .db + .get("transaction_mapper", txn.block.hash.as_bytes())? + { + Some(bytes) => serde_json::from_slice::>(&bytes)?, + None => vec![], + }; + + // Add the new transaction ID to the list + txn_ids.push(txn.txid); + let txn_ids_value = serde_json::to_string(&txn_ids)?; + self.db.put( + "transaction_mapper", + txn.block.hash.as_bytes(), + txn_ids_value.as_bytes(), + )?; + Ok(()) } pub async fn delete(&self, txid: String) -> Result<()> { match self.db.delete("transaction", txid.as_bytes()) { @@ -39,12 +53,39 @@ impl TransactionVinDb { Err(e) => Err(anyhow!(e)), } } - pub async fn query_by_blockhash( + pub async fn query_by_block_hash( &self, hash: String, limit: i32, lt: i32, ) -> Result> { - todo!() + let mut transactions = Vec::new(); + + // Retrieve the transaction ID(s) associated with the block hash + match self.db.get("transaction_mapper", hash.as_bytes()) { + Ok(Some(txn_id_bytes)) => { + // Assuming one block hash maps to multiple transaction IDs + println!("the value in trx{:?}", txn_id_bytes); + let txn_ids: Vec = serde_json::from_slice::>(&txn_id_bytes)?; + + for txn_id in txn_ids.iter().take(limit as usize) { + // Retrieve the transaction details for each transaction ID + match self.db.get("transaction", txn_id.as_bytes()) { + Ok(Some(txn_bytes)) => { + let txn: Transaction = serde_json::from_slice(&txn_bytes)?; + transactions.push(txn); + } + Ok(None) => { + return Err(anyhow!("Transaction not found for ID: {}", txn_id)) + } + Err(e) => return Err(anyhow!("Database error: {}", e)), + } + } + } + Ok(None) => return Err(anyhow!("No transactions found for block hash: {}", hash)), + Err(e) => return Err(anyhow!("Database error: {}", e)), + } + + Ok(transactions) } } diff --git a/lib/ain-ocean/src/data_acces/transaction_vin.rs b/lib/ain-ocean/src/data_acces/transaction_vin.rs index 8964743c4d2..7517eb456ab 100644 --- a/lib/ain-ocean/src/data_acces/transaction_vin.rs +++ b/lib/ain-ocean/src/data_acces/transaction_vin.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -16,7 +16,13 @@ impl TransactionVinDb { match serde_json::to_string(&trx_vin) { Ok(value) => { let key = trx_vin.id.clone(); - self.db.put("oracle", key.as_bytes(), value.as_bytes())?; + self.db + .put("transaction_vin", key.as_bytes(), value.as_bytes())?; + self.db.put( + "transaction_vin_mapper", + trx_vin.txid.as_bytes(), + trx_vin.id.as_bytes(), + )?; Ok(()) } Err(e) => Err(anyhow!(e)), @@ -28,7 +34,38 @@ impl TransactionVinDb { Err(e) => Err(anyhow!(e)), } } - pub async fn query(&self, txid: String, limit: i32, lt: i32) -> Result> { - todo!() + pub async fn query( + &self, + tx_id: String, + limit: i32, + lt: i32, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("transaction_vin", IteratorMode::End)?; + let mut trx_vin: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let vin: TransactionVin = serde_json::from_slice(&value)?; + if vin.txid == tx_id { + trx_vin.push(vin); + if trx_vin.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => trx_vin.sort_by(|a, b| a.txid.cmp(&b.txid)), + SortOrder::Descending => trx_vin.sort_by(|a, b| b.txid.cmp(&a.txid)), + } + + Ok(trx_vin) } } diff --git a/lib/ain-ocean/src/data_acces/transaction_vout.rs b/lib/ain-ocean/src/data_acces/transaction_vout.rs index 9f11f982789..c01af47e96c 100644 --- a/lib/ain-ocean/src/data_acces/transaction_vout.rs +++ b/lib/ain-ocean/src/data_acces/transaction_vout.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -12,8 +12,8 @@ pub struct TransactionVoutDb { } impl TransactionVoutDb { - pub async fn get(&self, txid: String, n: i64) -> Result> { - match self.db.get("transaction_vout", txid.as_bytes()) { + pub async fn get(&self, tx_id: String, n: i64) -> Result> { + match self.db.get("transaction_vout", tx_id.as_bytes()) { Ok(Some(value)) => { let master_node: TransactionVout = serde_json::from_slice(&value).map_err(|e| anyhow!(e))?; @@ -24,23 +24,59 @@ impl TransactionVoutDb { } } pub async fn store(&self, trx_out: TransactionVout) -> Result<()> { - match serde_json::to_string(&trx_out) { - Ok(value) => { - let key = trx_out.id.clone(); - self.db - .put("transaction_vout", key.as_bytes(), value.as_bytes())?; - Ok(()) - } - Err(e) => Err(anyhow!(e)), - } + let value = serde_json::to_string(&trx_out)?; + let key = trx_out.id.clone(); + self.db + .put("transaction_vout", key.as_bytes(), value.as_bytes())?; + + // Accumulate transaction vout IDs for each txid + let mut vout_ids = match self + .db + .get("transaction_vout_mapper", trx_out.txid.as_bytes())? + { + Some(bytes) => serde_json::from_slice::>(&bytes)?, + None => vec![], + }; + vout_ids.push(trx_out.id); + let vout_ids_value = serde_json::to_string(&vout_ids)?; + self.db.put( + "transaction_vout_mapper", + trx_out.txid.as_bytes(), + vout_ids_value.as_bytes(), + )?; + + Ok(()) } - pub async fn delete(&self, id: String) -> Result<()> { - match self.db.delete("transaction_vout", id.as_bytes()) { + pub async fn delete(&self, trx_id: String) -> Result<()> { + match self.db.delete("transaction_vout", trx_id.as_bytes()) { Ok(_) => Ok(()), Err(e) => Err(anyhow!(e)), } } - pub async fn query(&self, txid: String, limit: i32, lt: i32) -> Result { - todo!() + pub async fn query( + &self, + tx_id: String, + limit: i32, + lt: i32, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("transaction_vout", IteratorMode::End)?; + let mut trx_vout: Vec = Vec::new(); + if let Some(bytes) = self.db.get("transaction_vout_mapper", tx_id.as_bytes())? { + let vout_ids: Vec = serde_json::from_slice(&bytes)?; + for vout_id in vout_ids.iter().take(limit as usize) { + if let Some(vout_bytes) = self.db.get("transaction_vout", vout_id.as_bytes())? { + let vout: TransactionVout = serde_json::from_slice(&vout_bytes)?; + trx_vout.push(vout); + } + } + } + + match sort_order { + SortOrder::Ascending => trx_vout.sort_by(|a, b| a.n.cmp(&b.n)), + SortOrder::Descending => trx_vout.sort_by(|a, b| b.n.cmp(&a.n)), + } + + Ok(trx_vout) } } From 3de89afef1363a8d653f5f294eada4442b06ebf7 Mon Sep 17 00:00:00 2001 From: nagarajm22 Date: Wed, 13 Dec 2023 13:40:47 +0800 Subject: [PATCH 04/12] added query methods to modules --- lib/ain-ocean/src/data_acces/block.rs | 7 +-- lib/ain-ocean/src/data_acces/order_history.rs | 43 ++++++++++++++++--- lib/ain-ocean/src/data_acces/pool_swap.rs | 37 ++++++++++++++-- .../src/data_acces/pool_swap_aggregated.rs | 34 +++++++++++++-- lib/ain-ocean/src/data_acces/price_ticker.rs | 33 ++++++++++++-- lib/ain-ocean/src/data_acces/raw_block.rs | 1 - .../src/data_acces/script_activity.rs | 43 ++++++++++++++++--- .../src/data_acces/script_aggregation.rs | 17 +++++--- .../src/data_acces/script_unspent.rs | 43 ++++++++++++++++--- lib/ain-ocean/src/model/poolswap.rs | 4 +- 10 files changed, 223 insertions(+), 39 deletions(-) diff --git a/lib/ain-ocean/src/data_acces/block.rs b/lib/ain-ocean/src/data_acces/block.rs index 28c0484d644..269abb10301 100644 --- a/lib/ain-ocean/src/data_acces/block.rs +++ b/lib/ain-ocean/src/data_acces/block.rs @@ -1,12 +1,9 @@ use crate::database::db_manger::ColumnFamilyOperations; use crate::database::db_manger::{RocksDB, SortOrder}; use crate::model::block::Block; -use anyhow::{anyhow, Error, Result}; -use rocksdb::{DBIteratorWithThreadMode, IteratorMode}; -use serde::{Deserialize, Serialize}; -use std::cmp::Ordering; +use anyhow::{anyhow, Result}; +use rocksdb::IteratorMode; use std::convert::TryInto; -use std::hash; #[derive(Debug)] pub struct BlockDb { diff --git a/lib/ain-ocean/src/data_acces/order_history.rs b/lib/ain-ocean/src/data_acces/order_history.rs index 9b274c279c9..d893218ca8c 100644 --- a/lib/ain-ocean/src/data_acces/order_history.rs +++ b/lib/ain-ocean/src/data_acces/order_history.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -11,14 +11,45 @@ pub struct OracleHistoryDB { } impl OracleHistoryDB { - pub async fn query(&self, oracleId: String, limit: i32, lt: String) -> Result { - todo!() + pub async fn query( + &self, + oracle_id: String, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("oracle_history", IteratorMode::End)?; + let mut oracle_history: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle: OracleHistory = serde_json::from_slice(&value)?; + if oracle.id == oracle_id { + oracle_history.push(oracle); + if oracle_history.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => oracle_history.sort_by(|a, b| a.oracle_id.cmp(&b.oracle_id)), + SortOrder::Descending => oracle_history.sort_by(|a, b| b.oracle_id.cmp(&a.oracle_id)), + } + + Ok(oracle_history) } pub async fn store(&self, oracle_history: OracleHistory) -> Result<()> { match serde_json::to_string(&oracle_history) { Ok(value) => { - let key = oracle_history.id.clone(); + let key = oracle_history.oracle_id.clone(); self.db .put("oracle_history", key.as_bytes(), value.as_bytes())?; Ok(()) @@ -26,8 +57,8 @@ impl OracleHistoryDB { Err(e) => Err(anyhow!(e)), } } - pub async fn delete(&self, id: String) -> Result<()> { - match self.db.delete("oracle_history", id.as_bytes()) { + pub async fn delete(&self, oracle_id: String) -> Result<()> { + match self.db.delete("oracle_history", oracle_id.as_bytes()) { Ok(_) => Ok(()), Err(e) => Err(anyhow!(e)), } diff --git a/lib/ain-ocean/src/data_acces/pool_swap.rs b/lib/ain-ocean/src/data_acces/pool_swap.rs index ad5a6b2d89c..2ff9a44bdb5 100644 --- a/lib/ain-ocean/src/data_acces/pool_swap.rs +++ b/lib/ain-ocean/src/data_acces/pool_swap.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -11,8 +11,39 @@ pub struct PoolSwapDb { } impl PoolSwapDb { - pub async fn query(&self, key: String, limit: i32, lt: String) -> Result> { - todo!() + pub async fn query( + &self, + id: String, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("pool_swap", IteratorMode::End)?; + let mut pool_vin: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let vin: PoolSwap = serde_json::from_slice(&value)?; + if vin.id == id { + pool_vin.push(vin); + if pool_vin.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => pool_vin.sort_by(|a, b| a.txid.cmp(&b.txid)), + SortOrder::Descending => pool_vin.sort_by(|a, b| b.txid.cmp(&a.txid)), + } + + Ok(pool_vin) } pub async fn put(&self, swap: PoolSwap) -> Result<()> { match serde_json::to_string(&swap) { diff --git a/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs b/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs index 9259760086e..d4992d3375a 100644 --- a/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs +++ b/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -13,11 +13,39 @@ pub struct PoolSwapAggregatedDb { impl PoolSwapAggregatedDb { pub async fn query( &self, - key: String, + id: String, limit: i32, lt: String, + sort_order: SortOrder, ) -> Result<(Vec)> { - todo!() + let iterator = self + .db + .iterator("pool_swap_aggregated", IteratorMode::End)?; + let mut pool_swap: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let ps: PoolSwapAggregated = serde_json::from_slice(&value)?; + if ps.id == id { + pool_swap.push(ps); + if pool_swap.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => pool_swap.sort_by(|a, b| a.id.cmp(&b.id)), + SortOrder::Descending => pool_swap.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(pool_swap) } pub async fn put(&self, aggregated: PoolSwapAggregated) -> Result<()> { match serde_json::to_string(&aggregated) { diff --git a/lib/ain-ocean/src/data_acces/price_ticker.rs b/lib/ain-ocean/src/data_acces/price_ticker.rs index ac7e1a0140e..a3c65dffdb6 100644 --- a/lib/ain-ocean/src/data_acces/price_ticker.rs +++ b/lib/ain-ocean/src/data_acces/price_ticker.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -11,8 +11,35 @@ pub struct price_ticker { } impl price_ticker { - pub async fn query(&self, limit: i32, lt: String) -> Result> { - todo!() + pub async fn query( + &self, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("price_ticker", IteratorMode::End)?; + let mut pt: Vec = Vec::new(); + let collected_items: Vec<_> = iterator.collect(); + + for result in collected_items.into_iter().rev() { + let value = match result { + Ok((_, value)) => value, + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let price_ticker: PriceTicker = serde_json::from_slice(&value)?; + pt.push(price_ticker); + if pt.len() as i32 >= limit { + break; + } + } + + match sort_order { + SortOrder::Ascending => pt.sort_by(|a, b| a.id.cmp(&b.id)), + SortOrder::Descending => pt.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(pt) } pub async fn get(&self, id: String) -> Result { match self.db.get("price_ticker", id.as_bytes()) { diff --git a/lib/ain-ocean/src/data_acces/raw_block.rs b/lib/ain-ocean/src/data_acces/raw_block.rs index b2beb705bf4..024222dcba4 100644 --- a/lib/ain-ocean/src/data_acces/raw_block.rs +++ b/lib/ain-ocean/src/data_acces/raw_block.rs @@ -1,5 +1,4 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, diff --git a/lib/ain-ocean/src/data_acces/script_activity.rs b/lib/ain-ocean/src/data_acces/script_activity.rs index 5a24394fa0a..374a139889d 100644 --- a/lib/ain-ocean/src/data_acces/script_activity.rs +++ b/lib/ain-ocean/src/data_acces/script_activity.rs @@ -12,13 +12,46 @@ pub struct ScriptUnspentDB { } impl ScriptUnspentDB { - pub async fn query(&self, limit: i32, lt: String) -> Result> { - todo!() + pub async fn query( + &self, + hid: String, + limit: i32, + lt: Option, + ) -> Result> { + let prefix = format!("script_activity_hid_sort:{}:", lt.unwrap_or_default()); + let iterator_result = self.db.iterator( + "script_activity", + IteratorMode::From(prefix.as_bytes(), Direction::Forward), + )?; + let mut results = Vec::new(); + for item in iterator_result { + match item { + Ok((key, value)) => { + let key_str = String::from_utf8_lossy(&key); + if !key_str.starts_with(&prefix) { + break; + } + + let script_unspent: ScriptActivity = serde_json::from_slice(&value)?; + + results.push(script_unspent); + + if results.len() >= limit as usize { + break; + } + } + Err(err) => { + eprintln!("Error iterating over the database: {:?}", err); + return Err(err.into()); + } + } + } + Ok(results) } pub async fn store(&self, unspent: ScriptActivity) -> Result<()> { match serde_json::to_string(&unspent) { Ok(value) => { - let key = unspent.id.clone(); + let key = unspent.hid.clone(); self.db .put("script_activity", key.as_bytes(), value.as_bytes())?; Ok(()) @@ -26,8 +59,8 @@ impl ScriptUnspentDB { Err(e) => Err(anyhow!(e)), } } - pub async fn delete(&self, id: String) -> Result<()> { - match self.db.delete("script_activity", id.as_bytes()) { + pub async fn delete(&self, hid: String) -> Result<()> { + match self.db.delete("script_activity", hid.as_bytes()) { Ok(_) => Ok(()), Err(e) => Err(anyhow!(e)), } diff --git a/lib/ain-ocean/src/data_acces/script_aggregation.rs b/lib/ain-ocean/src/data_acces/script_aggregation.rs index ec386717bad..d209f83a711 100644 --- a/lib/ain-ocean/src/data_acces/script_aggregation.rs +++ b/lib/ain-ocean/src/data_acces/script_aggregation.rs @@ -12,13 +12,18 @@ pub struct ScriptAggretionDB { } impl ScriptAggretionDB { - pub async fn query(&self, limit: i32, lt: String) -> Result> { + pub async fn query( + &self, + hid: String, + limit: i32, + lt: String, + ) -> Result> { todo!() } pub async fn store(&self, aggregation: ScriptAggregation) -> Result<()> { match serde_json::to_string(&aggregation) { Ok(value) => { - let key = aggregation.id.clone(); + let key = aggregation.hid.clone(); self.db .put("script_aggregation", key.as_bytes(), value.as_bytes())?; Ok(()) @@ -26,8 +31,8 @@ impl ScriptAggretionDB { Err(e) => Err(anyhow!(e)), } } - pub async fn get(&self, id: String) -> Result> { - match self.db.get("script_aggregation", id.as_bytes()) { + pub async fn get(&self, hid: String) -> Result> { + match self.db.get("script_aggregation", hid.as_bytes()) { Ok(Some(value)) => { let oracle: ScriptAggregation = serde_json::from_slice(&value).map_err(|e| anyhow!(e))?; @@ -37,8 +42,8 @@ impl ScriptAggretionDB { Err(e) => Err(anyhow!(e)), } } - pub async fn delete(&self, id: String) -> Result<()> { - match self.db.delete("script_aggregation", id.as_bytes()) { + pub async fn delete(&self, hid: String) -> Result<()> { + match self.db.delete("script_aggregation", hid.as_bytes()) { Ok(_) => Ok(()), Err(e) => Err(anyhow!(e)), } diff --git a/lib/ain-ocean/src/data_acces/script_unspent.rs b/lib/ain-ocean/src/data_acces/script_unspent.rs index a5c1a462f08..f3ff1d15037 100644 --- a/lib/ain-ocean/src/data_acces/script_unspent.rs +++ b/lib/ain-ocean/src/data_acces/script_unspent.rs @@ -12,13 +12,46 @@ pub struct ScriptUnspentDB { } impl ScriptUnspentDB { - pub async fn query(&self, limit: i32, lt: String) -> Result> { - todo!() + pub async fn query( + &self, + hid: String, + limit: i32, + gt: Option, + ) -> Result> { + let prefix = format!("script_unspent_hid_sort:{}:", gt.unwrap_or_default()); + let iterator_result = self.db.iterator( + "script_unspent", + IteratorMode::From(prefix.as_bytes(), Direction::Forward), + )?; + let mut results = Vec::new(); + for item in iterator_result { + match item { + Ok((key, value)) => { + let key_str = String::from_utf8_lossy(&key); + if !key_str.starts_with(&prefix) { + break; + } + + let script_unspent: ScriptUnspent = serde_json::from_slice(&value)?; + + results.push(script_unspent); + + if results.len() >= limit as usize { + break; + } + } + Err(err) => { + eprintln!("Error iterating over the database: {:?}", err); + return Err(err.into()); + } + } + } + Ok(results) } pub async fn store(&self, unspent: ScriptUnspent) -> Result<()> { match serde_json::to_string(&unspent) { Ok(value) => { - let key = unspent.id.clone(); + let key = unspent.hid.clone(); self.db .put("script_unspent", key.as_bytes(), value.as_bytes())?; Ok(()) @@ -26,8 +59,8 @@ impl ScriptUnspentDB { Err(e) => Err(anyhow!(e)), } } - pub async fn delete(&self, id: String) -> Result<()> { - match self.db.delete("script_unspent", id.as_bytes()) { + pub async fn delete(&self, hid: String) -> Result<()> { + match self.db.delete("script_unspent", hid.as_bytes()) { Ok(_) => Ok(()), Err(e) => Err(anyhow!(e)), } diff --git a/lib/ain-ocean/src/model/poolswap.rs b/lib/ain-ocean/src/model/poolswap.rs index 777d7e3a3f9..16dd5d0ba58 100644 --- a/lib/ain-ocean/src/model/poolswap.rs +++ b/lib/ain-ocean/src/model/poolswap.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Serialize, Deserialize, Debug, Default, PartialEq)] #[serde(rename_all = "camelCase")] pub struct PoolSwap { pub id: String, @@ -13,7 +13,7 @@ pub struct PoolSwap { pub block: PoolSwapBlock, } -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Serialize, Deserialize, Debug, Default, PartialEq)] #[serde(rename_all = "camelCase")] pub struct PoolSwapBlock { pub hash: String, From 7783b827c2f94f59f71921a319b09e51c43c5381 Mon Sep 17 00:00:00 2001 From: nagarajm22 Date: Wed, 13 Dec 2023 15:03:25 +0800 Subject: [PATCH 05/12] added oracle price active and prive feed module --- lib/ain-ocean/src/data_acces/mod.rs | 2 + .../src/data_acces/oracle_price_active.rs | 65 +++++++++++++++++++ .../src/data_acces/oracle_price_aggregated.rs | 46 ++++++++++--- .../src/data_acces/oracle_price_feed.rs | 65 +++++++++++++++++++ .../src/data_acces/oracle_token_currency.rs | 39 ++++++++++- .../src/data_acces/script_aggregation.rs | 46 ++++++++++++- 6 files changed, 250 insertions(+), 13 deletions(-) create mode 100644 lib/ain-ocean/src/data_acces/oracle_price_active.rs create mode 100644 lib/ain-ocean/src/data_acces/oracle_price_feed.rs diff --git a/lib/ain-ocean/src/data_acces/mod.rs b/lib/ain-ocean/src/data_acces/mod.rs index 4072333a14e..0684394be11 100644 --- a/lib/ain-ocean/src/data_acces/mod.rs +++ b/lib/ain-ocean/src/data_acces/mod.rs @@ -2,8 +2,10 @@ pub mod block; pub mod masternode; pub mod masternode_states; pub mod oracle; +pub mod oracle_price_active; pub mod oracle_price_aggregated; pub mod oracle_price_aggregated_interval; +pub mod oracle_price_feed; pub mod oracle_token_currency; pub mod order_history; pub mod pool_swap; diff --git a/lib/ain-ocean/src/data_acces/oracle_price_active.rs b/lib/ain-ocean/src/data_acces/oracle_price_active.rs new file mode 100644 index 00000000000..6e7f4e60829 --- /dev/null +++ b/lib/ain-ocean/src/data_acces/oracle_price_active.rs @@ -0,0 +1,65 @@ +use crate::database::db_manger::ColumnFamilyOperations; +use crate::database::db_manger::{RocksDB, SortOrder}; +use crate::model::oracle_price_feed::OraclePriceFeed; +use anyhow::{anyhow, Result}; +use rocksdb::IteratorMode; + +pub struct OraclePriceFeedDb { + pub db: RocksDB, +} + +impl OraclePriceFeedDb { + pub async fn query( + &self, + oracle_id: String, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self.db.iterator("oracle_price_active", IteratorMode::End)?; + let mut oracle_price_feed: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle: OraclePriceFeed = serde_json::from_slice(&value)?; + if oracle.key == oracle_id { + oracle_price_feed.push(oracle); + if oracle_price_feed.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => { + oracle_price_feed.sort_by(|a: &OraclePriceFeed, b| a.id.cmp(&b.id)) + } + SortOrder::Descending => oracle_price_feed.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(oracle_price_feed) + } + pub async fn put(&self, oracle_price_feed: OraclePriceFeed) -> Result<()> { + match serde_json::to_string(&oracle_price_feed) { + Ok(value) => { + let key = oracle_price_feed.id.clone(); + self.db + .put("oracle_price_active", key.as_bytes(), value.as_bytes())?; + Ok(()) + } + Err(e) => Err(anyhow!(e)), + } + } + pub async fn delete(&self, id: String) -> Result<()> { + match self.db.delete("oracle_price_active", id.as_bytes()) { + Ok(_) => Ok(()), + Err(e) => Err(anyhow!(e)), + } + } +} diff --git a/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs b/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs index e1e89e96733..60533d755c6 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -13,16 +13,46 @@ pub struct OraclePriceAggrigatedDb { impl OraclePriceAggrigatedDb { pub async fn query( &self, - key: String, + oracle_key: String, limit: i32, lt: String, + sort_order: SortOrder, ) -> Result> { - todo!() + let iterator = self + .db + .iterator("oracle_price_aggregated", IteratorMode::End)?; + let mut oracle_pa: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle: OraclePriceAggregated = serde_json::from_slice(&value)?; + if oracle.key == oracle_key { + oracle_pa.push(oracle); + if oracle_pa.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => { + oracle_pa.sort_by(|a: &OraclePriceAggregated, b| a.id.cmp(&b.id)) + } + SortOrder::Descending => oracle_pa.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(oracle_pa) } pub async fn put(&self, oracle: OraclePriceAggregated) -> Result<()> { match serde_json::to_string(&oracle) { Ok(value) => { - let key = oracle.id.clone(); + let key = oracle.key.clone(); self.db .put("oracle_price_aggregated", key.as_bytes(), value.as_bytes())?; Ok(()) @@ -30,14 +60,14 @@ impl OraclePriceAggrigatedDb { Err(e) => Err(anyhow!(e)), } } - pub async fn get(&self, id: String) -> Option { - match self.db.get("oracle_price_aggregated", id.as_bytes()) { + pub async fn get(&self, key: String) -> Option { + match self.db.get("oracle_price_aggregated", key.as_bytes()) { Ok(Some(value)) => serde_json::from_slice(&value).ok(), _ => None, } } - pub async fn delete(&self, id: String) -> Result<()> { - match self.db.delete("oracle_price_aggregated", id.as_bytes()) { + pub async fn delete(&self, key: String) -> Result<()> { + match self.db.delete("oracle_price_aggregated", key.as_bytes()) { Ok(_) => Ok(()), Err(e) => Err(anyhow!(e)), } diff --git a/lib/ain-ocean/src/data_acces/oracle_price_feed.rs b/lib/ain-ocean/src/data_acces/oracle_price_feed.rs new file mode 100644 index 00000000000..fdc56ed34c3 --- /dev/null +++ b/lib/ain-ocean/src/data_acces/oracle_price_feed.rs @@ -0,0 +1,65 @@ +use crate::database::db_manger::ColumnFamilyOperations; +use crate::database::db_manger::{RocksDB, SortOrder}; +use crate::model::oracle_price_feed::OraclePriceFeed; +use anyhow::{anyhow, Result}; +use rocksdb::IteratorMode; + +pub struct OraclePriceFeedDb { + pub db: RocksDB, +} + +impl OraclePriceFeedDb { + pub async fn query( + &self, + oracle_id: String, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self + .db + .iterator("oracle_price_feed", IteratorMode::End)?; + let mut oracle_price_feed: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle: OraclePriceFeed = serde_json::from_slice(&value)?; + if oracle.key == oracle_id { + oracle_price_feed.push(oracle); + if oracle_price_feed.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => oracle_price_feed.sort_by(|a: &OraclePriceFeed, b| a.id.cmp(&b.id)), + SortOrder::Descending => oracle_price_feed.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(oracle_price_feed) + } + pub async fn put(&self, oracle_price_feed: OraclePriceFeed) -> Result<()> { + match serde_json::to_string(&oracle_price_feed) { + Ok(value) => { + let key = oracle_price_feed.id.clone(); + self.db + .put("oracle_price_feed", key.as_bytes(), value.as_bytes())?; + Ok(()) + } + Err(e) => Err(anyhow!(e)), + } + } + pub async fn delete(&self, id: String) -> Result<()> { + match self.db.delete("oracle_price_feed", id.as_bytes()) { + Ok(_) => Ok(()), + Err(e) => Err(anyhow!(e)), + } + } +} diff --git a/lib/ain-ocean/src/data_acces/oracle_token_currency.rs b/lib/ain-ocean/src/data_acces/oracle_token_currency.rs index 907e1633c94..d38f1e4ed21 100644 --- a/lib/ain-ocean/src/data_acces/oracle_token_currency.rs +++ b/lib/ain-ocean/src/data_acces/oracle_token_currency.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, @@ -11,8 +11,41 @@ pub struct OracleTokenCurrencyDb { } impl OracleTokenCurrencyDb { - pub async fn query(&self, limit: i32, lt: String) -> Result> { - todo!() + pub async fn query( + &self, + oracle_id: String, + limit: i32, + lt: String, + sort_order: SortOrder, + ) -> Result> { + let iterator = self + .db + .iterator("oracle_token_currency", IteratorMode::End)?; + let mut oracle_tc: Vec = Vec::new(); + let collected_blocks: Vec<_> = iterator.collect(); + + for result in collected_blocks.into_iter().rev() { + let (key, value) = match result { + Ok((key, value)) => (key, value), + Err(err) => return Err(anyhow!("Error during iteration: {}", err)), + }; + + let oracle: OracleTokenCurrency = serde_json::from_slice(&value)?; + if oracle.key == oracle_id { + oracle_tc.push(oracle); + if oracle_tc.len() as i32 >= limit { + break; + } + } + } + + // Sort blocks based on the specified sort order + match sort_order { + SortOrder::Ascending => oracle_tc.sort_by(|a: &OracleTokenCurrency, b| a.id.cmp(&b.id)), + SortOrder::Descending => oracle_tc.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(oracle_tc) } pub async fn put(&self, oracle_token: OracleTokenCurrency) -> Result<()> { match serde_json::to_string(&oracle_token) { diff --git a/lib/ain-ocean/src/data_acces/script_aggregation.rs b/lib/ain-ocean/src/data_acces/script_aggregation.rs index d209f83a711..f93e89e88d7 100644 --- a/lib/ain-ocean/src/data_acces/script_aggregation.rs +++ b/lib/ain-ocean/src/data_acces/script_aggregation.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Error, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::{Direction, IteratorMode}; use serde_json; use crate::{ @@ -17,8 +17,45 @@ impl ScriptAggretionDB { hid: String, limit: i32, lt: String, + sort_order: SortOrder, ) -> Result> { - todo!() + let iterator = self.db.iterator( + "script_aggregation", + IteratorMode::From(lt.as_bytes(), Direction::Reverse), + )?; + + let mut script_aggre: Vec = Vec::new(); + + for item in iterator { + match item { + Ok((key, value)) => { + let key_str = String::from_utf8_lossy(&key); + + if !key_str.starts_with(&hid) { + break; + } + + let vout: ScriptAggregation = serde_json::from_slice(&value)?; + script_aggre.push(vout); + + if script_aggre.len() >= limit as usize { + break; + } + } + Err(err) => { + eprintln!("Error iterating over the database: {:?}", err); + return Err(err.into()); + } + } + } + + // Sorting based on the SortOrder + match sort_order { + SortOrder::Ascending => script_aggre.sort_by(|a, b| a.id.cmp(&b.id)), + SortOrder::Descending => script_aggre.sort_by(|a, b| b.id.cmp(&a.id)), + } + + Ok(script_aggre) } pub async fn store(&self, aggregation: ScriptAggregation) -> Result<()> { match serde_json::to_string(&aggregation) { @@ -26,6 +63,11 @@ impl ScriptAggretionDB { let key = aggregation.hid.clone(); self.db .put("script_aggregation", key.as_bytes(), value.as_bytes())?; + + let h = aggregation.block.height.clone(); + let height: &[u8] = &h.to_be_bytes(); + self.db + .put("script_aggregation_mapper", height, key.as_bytes())?; Ok(()) } Err(e) => Err(anyhow!(e)), From 0c7a503037d16b33745b14aeaff5c64dd6bee324 Mon Sep 17 00:00:00 2001 From: nagarajm22 Date: Wed, 13 Dec 2023 15:04:25 +0800 Subject: [PATCH 06/12] added oracle price active and prive feed module --- lib/ain-ocean/src/data_acces/oracle_price_feed.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ain-ocean/src/data_acces/oracle_price_feed.rs b/lib/ain-ocean/src/data_acces/oracle_price_feed.rs index fdc56ed34c3..eb3304ad980 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_feed.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_feed.rs @@ -16,9 +16,7 @@ impl OraclePriceFeedDb { lt: String, sort_order: SortOrder, ) -> Result> { - let iterator = self - .db - .iterator("oracle_price_feed", IteratorMode::End)?; + let iterator = self.db.iterator("oracle_price_feed", IteratorMode::End)?; let mut oracle_price_feed: Vec = Vec::new(); let collected_blocks: Vec<_> = iterator.collect(); @@ -39,7 +37,9 @@ impl OraclePriceFeedDb { // Sort blocks based on the specified sort order match sort_order { - SortOrder::Ascending => oracle_price_feed.sort_by(|a: &OraclePriceFeed, b| a.id.cmp(&b.id)), + SortOrder::Ascending => { + oracle_price_feed.sort_by(|a: &OraclePriceFeed, b| a.id.cmp(&b.id)) + } SortOrder::Descending => oracle_price_feed.sort_by(|a, b| b.id.cmp(&a.id)), } From 24fd7fd597e8d3a77bb261743fb5c45c24cf3abc Mon Sep 17 00:00:00 2001 From: Nagaraj Date: Wed, 13 Dec 2023 17:11:13 +0800 Subject: [PATCH 07/12] rebased indexing ocean-archive --- lib/Cargo.lock | 144 +++++++++++++++++++-------------------- lib/ain-ocean/Cargo.toml | 1 + 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index d2139d40ec3..3bb4433c733 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ "serde_json", "serde_with", "sha3", - "syn 2.0.39", + "syn 2.0.41", "tokio", "tonic", "tonic-build", @@ -205,7 +205,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -221,10 +221,8 @@ dependencies = [ "dftx-rs", "futures", "hex", - "hyper 0.14.27", "json", "jsonrpsee 0.20.3", - "keccak-hash", "log", "rocksdb", "serde", @@ -377,7 +375,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -421,7 +419,7 @@ dependencies = [ "bytes", "futures-util", "http 0.2.11", - "http-body 0.4.5", + "http-body 0.4.6", "hyper 0.14.27", "itoa", "matchit", @@ -481,7 +479,7 @@ dependencies = [ "bytes", "futures-util", "http 0.2.11", - "http-body 0.4.5", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -611,7 +609,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1189,7 +1187,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1201,7 +1199,7 @@ dependencies = [ "codespan-reporting", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1218,7 +1216,7 @@ checksum = "587663dd5fb3d10932c8aecfe7c844db1bcf0aee93eeab08fac13dc1212c2e7f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1242,7 +1240,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1253,7 +1251,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1289,9 +1287,9 @@ dependencies = [ [[package]] name = "deunicode" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" +checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" [[package]] name = "dftx-macro" @@ -1300,7 +1298,7 @@ source = "git+https://github.com/Jouzo/dftx-rs.git#7973f1ad240d5f7724e51c6b090bc dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1916,7 +1914,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -2261,9 +2259,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http 0.2.11", @@ -2329,7 +2327,7 @@ dependencies = [ "futures-util", "h2 0.3.22", "http 0.2.11", - "http-body 0.4.5", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -2551,7 +2549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.3", - "rustix 0.38.26", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -2575,9 +2573,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" @@ -2991,9 +2989,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libloading" @@ -3209,7 +3207,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.26", + "rustix 0.38.28", ] [[package]] @@ -3491,7 +3489,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -3517,9 +3515,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -3759,7 +3757,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -3797,7 +3795,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -3863,7 +3861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4217,7 +4215,7 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4292,7 +4290,7 @@ dependencies = [ "futures-util", "h2 0.3.22", "http 0.2.11", - "http-body 0.4.5", + "http-body 0.4.6", "hyper 0.14.27", "hyper-rustls", "ipnet", @@ -4453,9 +4451,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno", @@ -4466,9 +4464,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.9" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", @@ -4515,9 +4513,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "safe_arch" @@ -4653,7 +4651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acea373acb8c21ecb5a23741452acd2593ed44ee3d343e72baaa143bc89d0d5" dependencies = [ "bitcoin_hashes 0.13.0", - "secp256k1-sys 0.9.0", + "secp256k1-sys 0.9.1", ] [[package]] @@ -4667,9 +4665,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09e67c467c38fd24bd5499dc9a18183b31575c12ee549197e3e20d57aa4fe3b7" +checksum = "4dd97a086ec737e30053fd5c46f097465d25bb81dd3608825f65298c4c98be83" dependencies = [ "cc", ] @@ -4747,7 +4745,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4809,7 +4807,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5074,7 +5072,7 @@ checksum = "f12dae7cf6c1e825d13ffd4ce16bd9309db7c539929d0302b4443ed451a9f4e5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5168,7 +5166,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5397,7 +5395,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5465,9 +5463,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -5567,7 +5565,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix 0.38.26", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -5617,7 +5615,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5713,9 +5711,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -5748,7 +5746,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5842,7 +5840,7 @@ dependencies = [ "futures-util", "h2 0.3.22", "http 0.2.11", - "http-body 0.4.5", + "http-body 0.4.6", "hyper 0.14.27", "hyper-timeout", "percent-encoding", @@ -5902,7 +5900,7 @@ dependencies = [ "futures-core", "futures-util", "http 0.2.11", - "http-body 0.4.5", + "http-body 0.4.6", "http-range-header", "httpdate", "iri-string", @@ -5951,7 +5949,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -6065,9 +6063,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twox-hash" @@ -6116,9 +6114,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -6326,7 +6324,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", "wasm-bindgen-shared", ] @@ -6360,7 +6358,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6538,7 +6536,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.26", + "rustix 0.38.28", ] [[package]] @@ -6791,9 +6789,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.25" +version = "0.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e87b8dfbe3baffbe687eef2e164e32286eff31a5ee16463ce03d991643ec94" +checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" dependencies = [ "memchr", ] @@ -6825,22 +6823,22 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.29" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d075cf85bbb114e933343e087b92f2146bac0d55b534cbb8188becf0039948e" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.29" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86cd5ca076997b97ef09d3ad65efe811fa68c9e874cb636ccb211223a813b0c2" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -6860,7 +6858,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] diff --git a/lib/ain-ocean/Cargo.toml b/lib/ain-ocean/Cargo.toml index e85195fa9b6..4d74d34f486 100644 --- a/lib/ain-ocean/Cargo.toml +++ b/lib/ain-ocean/Cargo.toml @@ -33,3 +33,4 @@ bitcoin_hashes = "0.12.0" structopt = { version = "0.3", default-features = false } tempfile = "3.8.1" anyhow.workspace = true +log = "0.4.20" \ No newline at end of file From c61380c4b93c793906a1e69575a8eb37e75ee5ec Mon Sep 17 00:00:00 2001 From: Nagaraj Date: Wed, 13 Dec 2023 19:11:21 +0800 Subject: [PATCH 08/12] rebased indexing ocean-archive and updated query methods all modules --- lib/ain-ocean/Cargo.toml | 1 - lib/ain-ocean/src/data_acces/block.rs | 8 ++++--- lib/ain-ocean/src/data_acces/masternode.rs | 12 ++++------- .../src/data_acces/masternode_states.rs | 7 ++----- lib/ain-ocean/src/data_acces/oracle.rs | 2 +- .../src/data_acces/oracle_price_active.rs | 21 +++++++++++-------- .../src/data_acces/oracle_price_aggregated.rs | 3 +-- .../oracle_price_aggregated_interval.rs | 6 ++---- .../src/data_acces/oracle_price_feed.rs | 7 ++++--- .../src/data_acces/oracle_token_currency.rs | 2 +- lib/ain-ocean/src/data_acces/order_history.rs | 2 +- lib/ain-ocean/src/data_acces/pool_swap.rs | 2 +- .../src/data_acces/pool_swap_aggregated.rs | 2 +- lib/ain-ocean/src/data_acces/price_ticker.rs | 2 +- .../src/data_acces/script_activity.rs | 9 ++++---- .../src/data_acces/script_aggregation.rs | 4 ++-- .../src/data_acces/script_unspent.rs | 2 +- .../src/data_acces/test/block_test.rs | 4 ++-- .../src/data_acces/transaction_vin.rs | 2 +- .../src/data_acces/transaction_vout.rs | 2 +- .../data_acces/vault_auction_batch_history.rs | 3 +-- lib/ain-ocean/src/database/db_manager.rs | 5 +++++ 22 files changed, 53 insertions(+), 55 deletions(-) diff --git a/lib/ain-ocean/Cargo.toml b/lib/ain-ocean/Cargo.toml index 4d74d34f486..e85195fa9b6 100644 --- a/lib/ain-ocean/Cargo.toml +++ b/lib/ain-ocean/Cargo.toml @@ -33,4 +33,3 @@ bitcoin_hashes = "0.12.0" structopt = { version = "0.3", default-features = false } tempfile = "3.8.1" anyhow.workspace = true -log = "0.4.20" \ No newline at end of file diff --git a/lib/ain-ocean/src/data_acces/block.rs b/lib/ain-ocean/src/data_acces/block.rs index 269abb10301..8b4fd1a32ad 100644 --- a/lib/ain-ocean/src/data_acces/block.rs +++ b/lib/ain-ocean/src/data_acces/block.rs @@ -1,6 +1,8 @@ -use crate::database::db_manger::ColumnFamilyOperations; -use crate::database::db_manger::{RocksDB, SortOrder}; -use crate::model::block::Block; +use crate::{ + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, + model::block::Block, +}; + use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use std::convert::TryInto; diff --git a/lib/ain-ocean/src/data_acces/masternode.rs b/lib/ain-ocean/src/data_acces/masternode.rs index a853a3422f7..02d7ce8a631 100644 --- a/lib/ain-ocean/src/data_acces/masternode.rs +++ b/lib/ain-ocean/src/data_acces/masternode.rs @@ -1,14 +1,10 @@ -use crate::database::db_manger::ColumnFamilyOperations; -use crate::database::db_manger::{RocksDB, SortOrder}; -use crate::model::masternode::Masternode; -use anyhow::{anyhow, Result}; -use rocksdb::IteratorMode; -use serde_json; - use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::masternode::Masternode, }; +use anyhow::{anyhow, Result}; +use rocksdb::IteratorMode; +use serde_json; pub struct MasterNodeDB { pub db: RocksDB, diff --git a/lib/ain-ocean/src/data_acces/masternode_states.rs b/lib/ain-ocean/src/data_acces/masternode_states.rs index b6c7439bd37..e4907dc7748 100644 --- a/lib/ain-ocean/src/data_acces/masternode_states.rs +++ b/lib/ain-ocean/src/data_acces/masternode_states.rs @@ -1,14 +1,11 @@ -use crate::database::db_manger::ColumnFamilyOperations; -use crate::database::db_manger::{RocksDB, SortOrder}; -use crate::model::masternode_stats::MasternodeStats; use anyhow::{anyhow, Result}; use bitcoin::absolute::Height; -use rocksdb::{ColumnFamilyDescriptor, IteratorMode, DB}; +use rocksdb::{IteratorMode, DB}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::masternode_stats::MasternodeStats, }; diff --git a/lib/ain-ocean/src/data_acces/oracle.rs b/lib/ain-ocean/src/data_acces/oracle.rs index 2952e4ce7d8..a8ffddae040 100644 --- a/lib/ain-ocean/src/data_acces/oracle.rs +++ b/lib/ain-ocean/src/data_acces/oracle.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use serde_json; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::oracle::Oracle, }; diff --git a/lib/ain-ocean/src/data_acces/oracle_price_active.rs b/lib/ain-ocean/src/data_acces/oracle_price_active.rs index 6e7f4e60829..734e3cc6318 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_active.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_active.rs @@ -1,23 +1,26 @@ -use crate::database::db_manger::ColumnFamilyOperations; -use crate::database::db_manger::{RocksDB, SortOrder}; use crate::model::oracle_price_feed::OraclePriceFeed; +use crate::{ + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, + model::oracle_price_active::OraclePriceActive, +}; use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; -pub struct OraclePriceFeedDb { +pub struct OraclePriceActiveDb { pub db: RocksDB, } -impl OraclePriceFeedDb { +impl OraclePriceActiveDb { + pub async fn query( &self, oracle_id: String, limit: i32, lt: String, sort_order: SortOrder, - ) -> Result> { + ) -> Result> { let iterator = self.db.iterator("oracle_price_active", IteratorMode::End)?; - let mut oracle_price_feed: Vec = Vec::new(); + let mut oracle_price_feed: Vec = Vec::new(); let collected_blocks: Vec<_> = iterator.collect(); for result in collected_blocks.into_iter().rev() { @@ -26,7 +29,7 @@ impl OraclePriceFeedDb { Err(err) => return Err(anyhow!("Error during iteration: {}", err)), }; - let oracle: OraclePriceFeed = serde_json::from_slice(&value)?; + let oracle: OraclePriceActive = serde_json::from_slice(&value)?; if oracle.key == oracle_id { oracle_price_feed.push(oracle); if oracle_price_feed.len() as i32 >= limit { @@ -38,14 +41,14 @@ impl OraclePriceFeedDb { // Sort blocks based on the specified sort order match sort_order { SortOrder::Ascending => { - oracle_price_feed.sort_by(|a: &OraclePriceFeed, b| a.id.cmp(&b.id)) + oracle_price_feed.sort_by(|a: &OraclePriceActive, b| a.id.cmp(&b.id)) } SortOrder::Descending => oracle_price_feed.sort_by(|a, b| b.id.cmp(&a.id)), } Ok(oracle_price_feed) } - pub async fn put(&self, oracle_price_feed: OraclePriceFeed) -> Result<()> { + pub async fn put(&self, oracle_price_feed: OraclePriceActive) -> Result<()> { match serde_json::to_string(&oracle_price_feed) { Ok(value) => { let key = oracle_price_feed.id.clone(); diff --git a/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs b/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs index 60533d755c6..bbfb70aec50 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs @@ -1,8 +1,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; - use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::oracle_price_aggregated::OraclePriceAggregated, }; diff --git a/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs b/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs index 73136a66846..4ff3977e85d 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_aggregated_interval.rs @@ -1,11 +1,9 @@ -use anyhow::{anyhow, Result}; -use rocksdb::{ColumnFamilyDescriptor, IteratorMode, DB}; -use serde::{Deserialize, Serialize}; - use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB}, model::oracle_price_aggregated_interval::OraclePriceAggregatedInterval, }; +use anyhow::{anyhow, Result}; +use rocksdb::{ColumnFamilyDescriptor, IteratorMode, DB}; pub struct OraclePriceAggregatedIntervalDb { pub db: RocksDB, diff --git a/lib/ain-ocean/src/data_acces/oracle_price_feed.rs b/lib/ain-ocean/src/data_acces/oracle_price_feed.rs index eb3304ad980..05cc2e90f01 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_feed.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_feed.rs @@ -1,6 +1,7 @@ -use crate::database::db_manger::ColumnFamilyOperations; -use crate::database::db_manger::{RocksDB, SortOrder}; -use crate::model::oracle_price_feed::OraclePriceFeed; +use crate::{ + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, + model::oracle_price_feed::OraclePriceFeed, +}; use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; diff --git a/lib/ain-ocean/src/data_acces/oracle_token_currency.rs b/lib/ain-ocean/src/data_acces/oracle_token_currency.rs index d38f1e4ed21..e66e7421599 100644 --- a/lib/ain-ocean/src/data_acces/oracle_token_currency.rs +++ b/lib/ain-ocean/src/data_acces/oracle_token_currency.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::oracle_token_currency::OracleTokenCurrency, }; diff --git a/lib/ain-ocean/src/data_acces/order_history.rs b/lib/ain-ocean/src/data_acces/order_history.rs index d893218ca8c..6f5fff45ba2 100644 --- a/lib/ain-ocean/src/data_acces/order_history.rs +++ b/lib/ain-ocean/src/data_acces/order_history.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::oracle_history::OracleHistory, }; diff --git a/lib/ain-ocean/src/data_acces/pool_swap.rs b/lib/ain-ocean/src/data_acces/pool_swap.rs index 2ff9a44bdb5..257f490ecca 100644 --- a/lib/ain-ocean/src/data_acces/pool_swap.rs +++ b/lib/ain-ocean/src/data_acces/pool_swap.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::poolswap::PoolSwap, }; diff --git a/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs b/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs index d4992d3375a..9e6e366af4a 100644 --- a/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs +++ b/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::poolswap_aggregated::PoolSwapAggregated, }; diff --git a/lib/ain-ocean/src/data_acces/price_ticker.rs b/lib/ain-ocean/src/data_acces/price_ticker.rs index a3c65dffdb6..3ee24610fb0 100644 --- a/lib/ain-ocean/src/data_acces/price_ticker.rs +++ b/lib/ain-ocean/src/data_acces/price_ticker.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::price_ticker::PriceTicker, }; diff --git a/lib/ain-ocean/src/data_acces/script_activity.rs b/lib/ain-ocean/src/data_acces/script_activity.rs index 374a139889d..feeaa12abc9 100644 --- a/lib/ain-ocean/src/data_acces/script_activity.rs +++ b/lib/ain-ocean/src/data_acces/script_activity.rs @@ -1,11 +1,10 @@ -use anyhow::{anyhow, Error, Result}; -use serde::{Deserialize, Serialize}; -use serde_json; - use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::script_activity::ScriptActivity, }; +use anyhow::{anyhow, Result}; +use rocksdb::{Direction, IteratorMode}; +use serde_json; pub struct ScriptUnspentDB { pub db: RocksDB, diff --git a/lib/ain-ocean/src/data_acces/script_aggregation.rs b/lib/ain-ocean/src/data_acces/script_aggregation.rs index f93e89e88d7..df0eefeb46e 100644 --- a/lib/ain-ocean/src/data_acces/script_aggregation.rs +++ b/lib/ain-ocean/src/data_acces/script_aggregation.rs @@ -1,9 +1,9 @@ -use anyhow::{anyhow, Error, Result}; +use anyhow::{anyhow, Result}; use rocksdb::{Direction, IteratorMode}; use serde_json; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::script_aggregation::ScriptAggregation, }; diff --git a/lib/ain-ocean/src/data_acces/script_unspent.rs b/lib/ain-ocean/src/data_acces/script_unspent.rs index f3ff1d15037..5db7c88e066 100644 --- a/lib/ain-ocean/src/data_acces/script_unspent.rs +++ b/lib/ain-ocean/src/data_acces/script_unspent.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Error, Result}; -use serde::{Deserialize, Serialize}; +use rocksdb::{Direction, IteratorMode}; use serde_json; use crate::{ diff --git a/lib/ain-ocean/src/data_acces/test/block_test.rs b/lib/ain-ocean/src/data_acces/test/block_test.rs index 9e00bdcdce8..4fa1d2d5cb2 100644 --- a/lib/ain-ocean/src/data_acces/test/block_test.rs +++ b/lib/ain-ocean/src/data_acces/test/block_test.rs @@ -2,8 +2,8 @@ mod tests { use super::*; use crate::data_acces::block::BlockDb; - use crate::database::db_manger::SortOrder; - use crate::database::db_manger::{ColumnFamilyOperations, RocksDB}; + use crate::database::db_manager::SortOrder; + use crate::database::db_manager::{ColumnFamilyOperations, RocksDB}; use crate::model::block::Block; use tempdir::TempDir; diff --git a/lib/ain-ocean/src/data_acces/transaction_vin.rs b/lib/ain-ocean/src/data_acces/transaction_vin.rs index 7517eb456ab..8080b571002 100644 --- a/lib/ain-ocean/src/data_acces/transaction_vin.rs +++ b/lib/ain-ocean/src/data_acces/transaction_vin.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::transaction_vin::TransactionVin, }; diff --git a/lib/ain-ocean/src/data_acces/transaction_vout.rs b/lib/ain-ocean/src/data_acces/transaction_vout.rs index c01af47e96c..11fbfcc625a 100644 --- a/lib/ain-ocean/src/data_acces/transaction_vout.rs +++ b/lib/ain-ocean/src/data_acces/transaction_vout.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB}, + database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, model::transaction_vout::TransactionVout, }; diff --git a/lib/ain-ocean/src/data_acces/vault_auction_batch_history.rs b/lib/ain-ocean/src/data_acces/vault_auction_batch_history.rs index eaf89997f83..1f91c9c20a4 100644 --- a/lib/ain-ocean/src/data_acces/vault_auction_batch_history.rs +++ b/lib/ain-ocean/src/data_acces/vault_auction_batch_history.rs @@ -1,5 +1,4 @@ -use anyhow::{anyhow, Error, Result}; -use serde::{Deserialize, Serialize}; +use anyhow::{anyhow, Result}; use serde_json; use crate::{ diff --git a/lib/ain-ocean/src/database/db_manager.rs b/lib/ain-ocean/src/database/db_manager.rs index 4a7392e186c..9a13e54b359 100644 --- a/lib/ain-ocean/src/database/db_manager.rs +++ b/lib/ain-ocean/src/database/db_manager.rs @@ -16,6 +16,11 @@ pub struct RocksDB { cfs: HashSet, } +pub enum SortOrder { + Ascending, + Descending, +} + pub trait ColumnFamilyOperations { fn get(&self, cf_name: &str, key: &[u8]) -> Result>>; fn put(&self, cf_name: &str, key: &[u8], value: &[u8]) -> Result<()>; From ef97dd1f626f9a0c1a0b124bec3822e0107ca923 Mon Sep 17 00:00:00 2001 From: Nagaraj Date: Wed, 13 Dec 2023 19:11:42 +0800 Subject: [PATCH 09/12] rebased indexing ocean-archive and updated query methods all modules --- lib/Cargo.lock | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 3bb4433c733..9c847a79bc6 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -221,8 +221,10 @@ dependencies = [ "dftx-rs", "futures", "hex", + "hyper 0.14.27", "json", "jsonrpsee 0.20.3", + "keccak-hash", "log", "rocksdb", "serde", @@ -515,7 +517,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] From 38fbd200ff97382d5b765f45b8aa555a7fcdd864 Mon Sep 17 00:00:00 2001 From: Nagaraj Date: Wed, 13 Dec 2023 19:14:38 +0800 Subject: [PATCH 10/12] fixed white space --- src/dfi/validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfi/validation.cpp b/src/dfi/validation.cpp index a42c8bf6984..925031e62d5 100644 --- a/src/dfi/validation.cpp +++ b/src/dfi/validation.cpp @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include From 719434dee9fbf153a91e293cffbebe9a83f70bd9 Mon Sep 17 00:00:00 2001 From: Nagaraj Date: Wed, 13 Dec 2023 19:17:51 +0800 Subject: [PATCH 11/12] fixed white space --- lib/ain-ocean/src/data_acces/oracle.rs | 2 +- lib/ain-ocean/src/data_acces/oracle_price_active.rs | 1 - lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs | 4 ++-- lib/ain-ocean/src/data_acces/pool_swap.rs | 2 +- lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs | 2 +- lib/ain-ocean/src/data_acces/price_ticker.rs | 2 +- lib/ain-ocean/src/data_acces/script_aggregation.rs | 2 +- lib/ain-ocean/src/data_acces/transaction_vin.rs | 2 +- lib/ain-ocean/src/data_acces/transaction_vout.rs | 2 +- 9 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/ain-ocean/src/data_acces/oracle.rs b/lib/ain-ocean/src/data_acces/oracle.rs index a8ffddae040..e106b94c0ce 100644 --- a/lib/ain-ocean/src/data_acces/oracle.rs +++ b/lib/ain-ocean/src/data_acces/oracle.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use serde_json; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::oracle::Oracle, }; diff --git a/lib/ain-ocean/src/data_acces/oracle_price_active.rs b/lib/ain-ocean/src/data_acces/oracle_price_active.rs index 734e3cc6318..aa3a08a1141 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_active.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_active.rs @@ -11,7 +11,6 @@ pub struct OraclePriceActiveDb { } impl OraclePriceActiveDb { - pub async fn query( &self, oracle_id: String, diff --git a/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs b/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs index bbfb70aec50..182cdea9c56 100644 --- a/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs +++ b/lib/ain-ocean/src/data_acces/oracle_price_aggregated.rs @@ -1,9 +1,9 @@ -use anyhow::{anyhow, Result}; -use rocksdb::IteratorMode; use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::oracle_price_aggregated::OraclePriceAggregated, }; +use anyhow::{anyhow, Result}; +use rocksdb::IteratorMode; pub struct OraclePriceAggrigatedDb { pub db: RocksDB, diff --git a/lib/ain-ocean/src/data_acces/pool_swap.rs b/lib/ain-ocean/src/data_acces/pool_swap.rs index 257f490ecca..25e857d4bfb 100644 --- a/lib/ain-ocean/src/data_acces/pool_swap.rs +++ b/lib/ain-ocean/src/data_acces/pool_swap.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::poolswap::PoolSwap, }; diff --git a/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs b/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs index 9e6e366af4a..1af6936a46f 100644 --- a/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs +++ b/lib/ain-ocean/src/data_acces/pool_swap_aggregated.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::poolswap_aggregated::PoolSwapAggregated, }; diff --git a/lib/ain-ocean/src/data_acces/price_ticker.rs b/lib/ain-ocean/src/data_acces/price_ticker.rs index 3ee24610fb0..e6491f888b5 100644 --- a/lib/ain-ocean/src/data_acces/price_ticker.rs +++ b/lib/ain-ocean/src/data_acces/price_ticker.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::price_ticker::PriceTicker, }; diff --git a/lib/ain-ocean/src/data_acces/script_aggregation.rs b/lib/ain-ocean/src/data_acces/script_aggregation.rs index df0eefeb46e..2f2788aaf5d 100644 --- a/lib/ain-ocean/src/data_acces/script_aggregation.rs +++ b/lib/ain-ocean/src/data_acces/script_aggregation.rs @@ -3,7 +3,7 @@ use rocksdb::{Direction, IteratorMode}; use serde_json; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::script_aggregation::ScriptAggregation, }; diff --git a/lib/ain-ocean/src/data_acces/transaction_vin.rs b/lib/ain-ocean/src/data_acces/transaction_vin.rs index 8080b571002..20b80f81093 100644 --- a/lib/ain-ocean/src/data_acces/transaction_vin.rs +++ b/lib/ain-ocean/src/data_acces/transaction_vin.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::transaction_vin::TransactionVin, }; diff --git a/lib/ain-ocean/src/data_acces/transaction_vout.rs b/lib/ain-ocean/src/data_acces/transaction_vout.rs index 11fbfcc625a..aab89713d08 100644 --- a/lib/ain-ocean/src/data_acces/transaction_vout.rs +++ b/lib/ain-ocean/src/data_acces/transaction_vout.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use rocksdb::IteratorMode; use crate::{ - database::db_manager::{ColumnFamilyOperations, RocksDB,SortOrder}, + database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::transaction_vout::TransactionVout, }; From 3e7fe2ed97a3dde1e8fe20098dca499ab857b044 Mon Sep 17 00:00:00 2001 From: Nagaraj Date: Tue, 19 Dec 2023 18:54:13 +0800 Subject: [PATCH 12/12] fixed query method for masternode and masterstats --- lib/Cargo.lock | 3 + lib/ain-ocean/Cargo.toml | 1 + lib/ain-ocean/src/data_acces/masternode.rs | 52 ++++++------ ...sternode_states.rs => masternode_stats.rs} | 65 +++++++-------- lib/ain-ocean/src/data_acces/mod.rs | 2 +- .../src/data_acces/test/masternode_test.rs | 82 +++++++++++++++++++ lib/ain-ocean/src/data_acces/test/mod.rs | 1 + lib/ain-ocean/src/database/db_manager.rs | 12 ++- 8 files changed, 152 insertions(+), 66 deletions(-) rename lib/ain-ocean/src/data_acces/{masternode_states.rs => masternode_stats.rs} (70%) create mode 100644 lib/ain-ocean/src/data_acces/test/masternode_test.rs diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 9c847a79bc6..c58c7009ca1 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -217,6 +217,7 @@ dependencies = [ "axum 0.7.2", "bitcoin", "bitcoin_hashes 0.12.0", + "chrono", "ctrlc", "dftx-rs", "futures", @@ -904,8 +905,10 @@ checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-targets 0.48.5", ] diff --git a/lib/ain-ocean/Cargo.toml b/lib/ain-ocean/Cargo.toml index e85195fa9b6..cdb44d6c35b 100644 --- a/lib/ain-ocean/Cargo.toml +++ b/lib/ain-ocean/Cargo.toml @@ -33,3 +33,4 @@ bitcoin_hashes = "0.12.0" structopt = { version = "0.3", default-features = false } tempfile = "3.8.1" anyhow.workspace = true +chrono = "0.4.31" \ No newline at end of file diff --git a/lib/ain-ocean/src/data_acces/masternode.rs b/lib/ain-ocean/src/data_acces/masternode.rs index 02d7ce8a631..cdf54f8d6fc 100644 --- a/lib/ain-ocean/src/data_acces/masternode.rs +++ b/lib/ain-ocean/src/data_acces/masternode.rs @@ -14,36 +14,34 @@ impl MasterNodeDB { pub async fn query( &self, limit: i32, - lt: i32, + lt: u32, sort_order: SortOrder, ) -> Result> { - let iterator = self.db.iterator("masternode", IteratorMode::End)?; - let mut master_node: Vec = Vec::new(); - let collected_blocks: Vec<_> = iterator.collect(); + let iter_mode: IteratorMode = sort_order.into(); + let master_node: Result> = self + .db + .iterator("masternode", iter_mode)? + .into_iter() + .take(limit as usize) + .map(|result| { + result + .map_err(|e| { + anyhow!("Error during iteration: {}", e) + .context("error master_node query error") + }) + .and_then(|(_key, value)| { + let stats: Masternode = serde_json::from_slice(&value)?; + if stats.block.height < lt { + Ok(stats) + } else { + Err(anyhow!("Value is not less than lt") + .context("Contextual error message")) + } + }) + }) + .collect(); - for result in collected_blocks.into_iter().rev() { - let (key, value) = match result { - Ok((key, value)) => (key, value), - Err(err) => return Err(anyhow!("Error during iteration: {}", err)), - }; - - let master_stats: Masternode = serde_json::from_slice(&value)?; - master_node.push(master_stats); - - if master_node.len() == limit as usize { - break; - } - } - - // Sort blocks based on the specified sort order - match sort_order { - SortOrder::Ascending => master_node.sort_by(|a, b| a.block.height.cmp(&b.block.height)), - SortOrder::Descending => { - master_node.sort_by(|a, b| b.block.height.cmp(&a.block.height)) - } - } - - Ok(master_node) + master_node.and_then(|result| Ok(result)) } pub async fn get(&self, id: String) -> Result> { match self.db.get("masternode", id.as_bytes()) { diff --git a/lib/ain-ocean/src/data_acces/masternode_states.rs b/lib/ain-ocean/src/data_acces/masternode_stats.rs similarity index 70% rename from lib/ain-ocean/src/data_acces/masternode_states.rs rename to lib/ain-ocean/src/data_acces/masternode_stats.rs index e4907dc7748..4cb7ed20f76 100644 --- a/lib/ain-ocean/src/data_acces/masternode_states.rs +++ b/lib/ain-ocean/src/data_acces/masternode_stats.rs @@ -1,14 +1,10 @@ -use anyhow::{anyhow, Result}; -use bitcoin::absolute::Height; -use rocksdb::{IteratorMode, DB}; -use serde::{Deserialize, Serialize}; -use std::cmp::Ordering; - use crate::{ database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, model::masternode_stats::MasternodeStats, }; - +use anyhow::Context; +use anyhow::{anyhow, Result}; +use rocksdb::IteratorMode; #[derive(Debug)] pub struct MasterStatsDb { pub db: RocksDB, @@ -43,43 +39,38 @@ impl MasterStatsDb { Err(e) => Err(anyhow!(e)), } } + pub async fn query( &self, limit: i32, lt: i32, sort_order: SortOrder, ) -> Result> { - let iterator = self.db.iterator("masternode_stats", IteratorMode::End)?; - let mut master_node: Vec = Vec::new(); - let collected_blocks: Vec<_> = iterator.collect(); - - for result in collected_blocks.into_iter().rev() { - let (key, value) = match result { - Ok((key, value)) => (key, value), - Err(err) => return Err(anyhow!("Error during iteration: {}", err)), - }; - - let master_stats: MasternodeStats = serde_json::from_slice(&value)?; - - if master_stats.block.height < lt { - master_node.push(master_stats); - - if master_node.len() == limit as usize { - break; - } - } - } - - // Sort blocks based on the specified sort order - match sort_order { - SortOrder::Ascending => master_node.sort_by(|a, b| a.block.height.cmp(&b.block.height)), - SortOrder::Descending => { - master_node.sort_by(|a, b| b.block.height.cmp(&a.block.height)) - } - } - - Ok(master_node) + let iter_mode: IteratorMode = sort_order.into(); + let master_node: Result> = self + .db + .iterator("masternode_stats", iter_mode)? + .into_iter() + .take(limit as usize) + .map(|result| { + result + .map_err(|e| { + anyhow!("Error during iteration: {}", e).context("Contextual error message") + }) + .and_then(|(_key, value)| { + let stats: MasternodeStats = serde_json::from_slice(&value)?; + if stats.block.height < lt { + Ok(stats) + } else { + Err(anyhow!("Value is not less than lt") + .context("Contextual error message")) + } + }) + }) + .collect(); + Ok(master_node?) } + pub async fn get(&self, height: i32) -> Result> { let bytes: &[u8] = &height.to_be_bytes(); match self.db.get("masternode_stats", bytes) { diff --git a/lib/ain-ocean/src/data_acces/mod.rs b/lib/ain-ocean/src/data_acces/mod.rs index 0684394be11..426541e79e2 100644 --- a/lib/ain-ocean/src/data_acces/mod.rs +++ b/lib/ain-ocean/src/data_acces/mod.rs @@ -1,6 +1,6 @@ pub mod block; pub mod masternode; -pub mod masternode_states; +pub mod masternode_stats; pub mod oracle; pub mod oracle_price_active; pub mod oracle_price_aggregated; diff --git a/lib/ain-ocean/src/data_acces/test/masternode_test.rs b/lib/ain-ocean/src/data_acces/test/masternode_test.rs new file mode 100644 index 00000000000..7ad29de0228 --- /dev/null +++ b/lib/ain-ocean/src/data_acces/test/masternode_test.rs @@ -0,0 +1,82 @@ +#[cfg(test)] +mod tests { + use super::*; + use crate::data_acces::masternode::MasterNodeDB; + use crate::database::db_manager::{RocksDB, SortOrder}; + use crate::model::masternode::{HistoryItem, Masternode, MasternodeBlock}; + use chrono::Utc; + use tempfile::tempdir; + + fn setup_test_db() -> MasterNodeDB { + let temp_dir = tempdir().unwrap(); + let db = RocksDB::new(temp_dir.path().to_str().unwrap()).unwrap(); // Adjust this according to your RocksDB struct + MasterNodeDB { db } + } + fn create_dummy_masternode(id: &str) -> Masternode { + Masternode { + id: id.to_string(), + sort: Some("dummy_sort".to_string()), + owner_address: "dummy_owner_address".to_string(), + operator_address: "dummy_operator_address".to_string(), + creation_height: 100, + resign_height: 200, + resign_tx: Some("dummy_resign_tx".to_string()), + minted_blocks: 50, + timelock: 10, + collateral: "dummy_collateral".to_string(), + block: create_dummy_masternode_block(), + history: Some(vec![create_dummy_history_item()]), + } + } + + fn create_dummy_masternode_block() -> MasternodeBlock { + MasternodeBlock { + hash: "dummy_hash".to_string(), + height: 100, + time: Utc::now().timestamp() as u64, + median_time: Utc::now().timestamp() as u64, + } + } + + fn create_dummy_history_item() -> HistoryItem { + HistoryItem { + txid: "dummy_txid".to_string(), + owner_address: "dummy_history_owner_address".to_string(), + operator_address: "dummy_history_operator_address".to_string(), + } + } + + #[tokio::test] + async fn test_query_with_dummy_data() { + let master_node = setup_test_db(); + let request = create_dummy_masternode("1"); + let result = master_node.store(request).await; + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_store_and_query_dummy_data() { + let master_node = setup_test_db(); + let dummy_data = vec![ + create_dummy_masternode("1"), + create_dummy_masternode("2"), + create_dummy_masternode("3"), + create_dummy_masternode("4"), + create_dummy_masternode("5"), + create_dummy_masternode("6"), + create_dummy_masternode("7"), + create_dummy_masternode("8"), + create_dummy_masternode("9"), + create_dummy_masternode("10"), + ]; + + for masternode in dummy_data { + let result = master_node.store(masternode).await; + assert!(result.is_ok()); + } + // let query_result = master_node.query(5, 8, SortOrder::Ascending).await; + // assert!(query_result.is_err()); + // let queried_masternodes = query_result.unwrap(); + // assert_eq!(queried_masternodes.len(), 5); + } +} diff --git a/lib/ain-ocean/src/data_acces/test/mod.rs b/lib/ain-ocean/src/data_acces/test/mod.rs index 01063ce2f0e..350db04c962 100644 --- a/lib/ain-ocean/src/data_acces/test/mod.rs +++ b/lib/ain-ocean/src/data_acces/test/mod.rs @@ -1,3 +1,4 @@ mod block_test; +mod masternode_test; mod oracle_test; mod transaction_test; diff --git a/lib/ain-ocean/src/database/db_manager.rs b/lib/ain-ocean/src/database/db_manager.rs index 9a13e54b359..1c06b1901c8 100644 --- a/lib/ain-ocean/src/database/db_manager.rs +++ b/lib/ain-ocean/src/database/db_manager.rs @@ -5,7 +5,7 @@ use bitcoin::{ blockdata::block::{Block, Header}, consensus::encode::serialize, }; -use rocksdb::{ColumnFamilyDescriptor, DBIterator, IteratorMode, Options, DB}; +use rocksdb::{ColumnFamilyDescriptor, DBIterator, Direction, IteratorMode, Options, DB}; use serde::{Deserialize, Serialize}; use crate::model::oracle::Oracle; @@ -16,6 +16,7 @@ pub struct RocksDB { cfs: HashSet, } +#[derive(Debug, PartialEq, Clone)] pub enum SortOrder { Ascending, Descending, @@ -286,3 +287,12 @@ impl ColumnFamilyOperations for RocksDB { } } } + +impl<'a> From for IteratorMode<'a> { + fn from(sort_order: SortOrder) -> Self { + match sort_order { + SortOrder::Ascending => IteratorMode::Start, + SortOrder::Descending => IteratorMode::From(b"", Direction::Reverse), + } + } +}