ee5b55fab6
* Feature/ephemera compile (#3437) * Include ephemera node code in repo * Upgrade deps * Bump minor version of cosmwasm-std * Include ephemera in nym-api dep and downgrade rusqlite * Fix clippy and ephemera docs code * More clippy on ephemera --------- Co-authored-by: Andrus Salumets <andrus@nymtech.net> * Start ephemera components in nym-api (#3475) * Start ephemera components in nym-api * Pass nyxd client and use common metric structures * Swap url endpoint with contract for sending rewarding messages * Fix build after rebase * Perform ephemera rewards computation before normal nym-api ones * Remove contract mock from ephemera * Take raw rewards from network monitor * Remove ephemera old reward version * Use nym shutdown procedure in ephemera * Temporary fix for some warnings * Umock contract membership of ephemera (#3574) * Pass nyxd client to members provider * Basic ephemera contract * Add register peer tx * Add query all peers * Nyxd ephemera client * Add registration of ephemera peer * Replace epoch http api with actual contract * Merge ephemera config into nym-api config * Load cluster from contract * Guard nym-outfox out of cosmwasm builds (#3650) * Feature/fixes while testing (#3668) * Commit local peer before querying contract * Default to anyonline * Remove string from template * Fix avg computing * Use updated qa env * Fix clippy * Add unit tests for ephemera contract * Upload ephemera contract in CI * Add group check for peer signup * Peer registration unit test * Start ephemera only on monitoring * Remove old MixnodeToReward struct * Move all ephemera config to its file * Skip with serde ephemera config * Fix default value in args * Feature/add ephemera flag (#3727) * Replace unwrap with error handling * Add ephemera enable flag * Fix template * Add json schema to ephemera contract (#3735) * Update lock files * Update changelog --------- Co-authored-by: Andrus Salumets <andrus@nymtech.net>
168 lines
5.3 KiB
Rust
168 lines
5.3 KiB
Rust
use log::{error, trace};
|
|
use rusqlite::{params, Connection, OpenFlags, OptionalExtension, Row};
|
|
|
|
use crate::block::types::block::Block;
|
|
use crate::config::DatabaseConfiguration;
|
|
use crate::peer::PeerId;
|
|
use crate::utilities::crypto::Certificate;
|
|
use crate::utilities::merkle::MerkleTree;
|
|
|
|
pub(crate) struct DbQuery {
|
|
pub(crate) connection: Connection,
|
|
}
|
|
|
|
impl DbQuery {
|
|
pub(crate) fn open(db_conf: DatabaseConfiguration, flags: OpenFlags) -> anyhow::Result<Self> {
|
|
let connection = Connection::open_with_flags(db_conf.sqlite_path, flags)?;
|
|
let query = Self { connection };
|
|
Ok(query)
|
|
}
|
|
|
|
pub(crate) fn get_block_by_hash(&self, block_hash: &str) -> anyhow::Result<Option<Block>> {
|
|
let mut stmt = self
|
|
.connection
|
|
.prepare_cached("SELECT block FROM blocks WHERE block_hash = ?1")?;
|
|
let block = stmt
|
|
.query_row(params![block_hash], Self::map_block())
|
|
.optional()?;
|
|
|
|
if let Some(block) = &block {
|
|
trace!("Found block: {}", block.header);
|
|
} else {
|
|
trace!("Block not found: {}", block_hash);
|
|
};
|
|
|
|
Ok(block)
|
|
}
|
|
|
|
pub(crate) fn get_last_block(&self) -> anyhow::Result<Option<Block>> {
|
|
let mut stmt = self
|
|
.connection
|
|
.prepare_cached("SELECT block FROM blocks where id = (select max(id) from blocks)")?;
|
|
|
|
let block = stmt.query_row(params![], Self::map_block()).optional()?;
|
|
|
|
if let Some(block) = &block {
|
|
trace!("Found last block: {}", block.header);
|
|
} else {
|
|
trace!("Last block not found");
|
|
};
|
|
|
|
Ok(block)
|
|
}
|
|
|
|
pub(crate) fn get_block_by_height(&self, height: u64) -> anyhow::Result<Option<Block>> {
|
|
let mut stmt = self
|
|
.connection
|
|
.prepare_cached("SELECT block FROM blocks WHERE height = ?1")?;
|
|
let block = stmt
|
|
.query_row(params![height], Self::map_block())
|
|
.optional()?;
|
|
|
|
if let Some(block) = &block {
|
|
trace!("Found block: {}", block.header);
|
|
} else {
|
|
trace!("Block not found: {}", height);
|
|
};
|
|
|
|
Ok(block)
|
|
}
|
|
|
|
pub(crate) fn get_block_certificates(
|
|
&self,
|
|
block_hash: &str,
|
|
) -> anyhow::Result<Option<Vec<Certificate>>> {
|
|
let mut stmt = self
|
|
.connection
|
|
.prepare_cached("SELECT certificates FROM block_certificates where block_hash = ?1")?;
|
|
|
|
let signatures = stmt
|
|
.query_row(params![block_hash], |row| {
|
|
let certificates: Vec<u8> = row.get(0)?;
|
|
let certificates = serde_json::from_slice::<Vec<Certificate>>(&certificates)
|
|
.map_err(|e| {
|
|
error!("Error deserializing certificates: {}", e);
|
|
rusqlite::Error::InvalidQuery {}
|
|
})?;
|
|
Ok(certificates)
|
|
})
|
|
.optional()?;
|
|
|
|
if signatures.is_some() {
|
|
trace!("Found block {} certificates", block_hash);
|
|
} else {
|
|
trace!("Certificates not found");
|
|
};
|
|
|
|
Ok(signatures)
|
|
}
|
|
|
|
pub(crate) fn get_block_broadcast_group(
|
|
&self,
|
|
block_hash: &str,
|
|
) -> anyhow::Result<Option<Vec<PeerId>>> {
|
|
let mut stmt = self
|
|
.connection
|
|
.prepare_cached("SELECT members FROM block_broadcast_group where block_hash = ?1")?;
|
|
|
|
let members = stmt
|
|
.query_row(params![block_hash], |row| {
|
|
let members: Vec<u8> = row.get(0)?;
|
|
let members = serde_json::from_slice::<Vec<PeerId>>(&members).map_err(|e| {
|
|
error!("Error deserializing members: {}", e);
|
|
rusqlite::Error::InvalidQuery {}
|
|
})?;
|
|
Ok(members)
|
|
})
|
|
.optional()?;
|
|
|
|
if members.is_some() {
|
|
trace!("Found block {} members", block_hash);
|
|
} else {
|
|
trace!("Members not found");
|
|
};
|
|
|
|
Ok(members)
|
|
}
|
|
|
|
pub(crate) fn get_block_merkle_tree(
|
|
&self,
|
|
block_hash: &str,
|
|
) -> anyhow::Result<Option<MerkleTree>> {
|
|
let mut stmt = self
|
|
.connection
|
|
.prepare_cached("SELECT merkle_tree FROM block_merkle_tree where block_hash = ?1")?;
|
|
|
|
let merkle_tree = stmt
|
|
.query_row(params![block_hash], |row| {
|
|
let merkle_tree: Vec<u8> = row.get(0)?;
|
|
let merkle_tree =
|
|
serde_json::from_slice::<MerkleTree>(&merkle_tree).map_err(|e| {
|
|
error!("Error deserializing merkle_tree: {}", e);
|
|
rusqlite::Error::InvalidQuery {}
|
|
})?;
|
|
Ok(merkle_tree)
|
|
})
|
|
.optional()?;
|
|
|
|
if merkle_tree.is_some() {
|
|
trace!("Found block {} merkle_tree", block_hash);
|
|
} else {
|
|
trace!("Merkle_tree not found");
|
|
};
|
|
|
|
Ok(merkle_tree)
|
|
}
|
|
|
|
fn map_block() -> impl FnOnce(&Row) -> Result<Block, rusqlite::Error> {
|
|
|row| {
|
|
let body: Vec<u8> = row.get(0)?;
|
|
let block = serde_json::from_slice::<Block>(&body).map_err(|e| {
|
|
error!("Error deserializing block: {}", e);
|
|
rusqlite::Error::InvalidQuery {}
|
|
})?;
|
|
Ok(block)
|
|
}
|
|
}
|
|
}
|