-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Ocean API database implementation to all modules #2748
Merged
Merged
Changes from 11 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
ff27aee
added block indexing
nagarajm22 ad474a8
added block indexing and query method
nagarajm22 31a8710
added query methods and extra table
nagarajm22 3de89af
added query methods to modules
nagarajm22 7783b82
added oracle price active and prive feed module
nagarajm22 0c7a503
added oracle price active and prive feed module
nagarajm22 24fd7fd
rebased indexing ocean-archive
nagarajm22 c61380c
rebased indexing ocean-archive and updated query methods all modules
nagarajm22 ef97dd1
rebased indexing ocean-archive and updated query methods all modules
nagarajm22 38fbd20
fixed white space
nagarajm22 719434d
fixed white space
nagarajm22 3e7fe2e
fixed query method for masternode and masterstats
nagarajm22 a66e781
Merge branch 'feature/ocean-archive' into feature/ocean_db
nagarajm22 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,171 @@ | ||
use anyhow::{anyhow, Result}; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::{ | ||
database::db_manager::{ColumnFamilyOperations, RocksDB}, | ||
database::db_manager::{ColumnFamilyOperations, RocksDB, SortOrder}, | ||
model::block::Block, | ||
}; | ||
|
||
use anyhow::{anyhow, Result}; | ||
use rocksdb::IteratorMode; | ||
use std::convert::TryInto; | ||
|
||
#[derive(Debug)] | ||
pub struct BlockDb { | ||
pub db: RocksDB, | ||
} | ||
|
||
impl BlockDb { | ||
pub async fn get_by_hash(&self) -> Result<Block> { | ||
todo!() | ||
pub async fn get_by_hash(&self, hash: String) -> Result<Option<Block>> { | ||
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<Block> { | ||
todo!() | ||
|
||
pub async fn get_by_height(&self, height: i32) -> Result<Option<Block>> { | ||
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<Block> { | ||
todo!() | ||
|
||
pub async fn get_highest(&self) -> Result<Option<Block>> { | ||
// 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<Vec<Block>> { | ||
todo!() | ||
|
||
pub async fn query_by_height( | ||
&self, | ||
limit: i32, | ||
lt: i32, | ||
sort_order: SortOrder, | ||
) -> Result<Vec<Block>> { | ||
let mut blocks: Vec<Block> = Vec::new(); | ||
|
||
let iterator = self.db.iterator("block", IteratorMode::End)?; | ||
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 block: Block = serde_json::from_slice(&value)?; | ||
|
||
if block.height < lt { | ||
blocks.push(block); | ||
|
||
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) | ||
} | ||
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())?; | ||
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)), | ||
} | ||
} | ||
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(()) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to handle secondary sort index (block height + masternode.id). This CF indexes by masternode.id for now, we need to be able to sort by masternode creation height.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to dig through Ocean spec and check all the models that need a secondary sort index (I guess all the one that are currently indexed by TX id but needs to be iterable via block height). I'll add this requirement to the main tracking PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's take care of the rest and implement these secondary indexes in another dedicated PR.