riftenlabs-indexer/src/db/cauldron/header.rs

61 lines
1.9 KiB
Rust
Raw Normal View History

2024-03-04 16:40:50 +01:00
// Copyright (C) 2024 Riften Labs AS
//
// This software is licensed under the GNU Affero General Public License (AGPL), version 3.0 or later.
// A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html
use anyhow::{bail, Result};
use bitcoin_hashes::hex::ToHex;
use bitcoincash::consensus::serialize;
use bitcoincash::{consensus::deserialize, BlockHash, BlockHeader};
use rusqlite::{params, Connection};
use crate::chain::NewHeader;
/// Load all headers we have stored in our database
pub fn load_all_headers(conn: &Connection) -> Result<Vec<(BlockHeader, u64)>> {
let mut stmt = conn.prepare("SELECT header, height FROM headers")?;
let headers_iter = stmt.query_map([], |row| {
let data: Vec<u8> = row.get(0)?;
let height: u64 = row.get(1)?;
Ok((data, height))
})?;
let mut headers = Vec::new();
for header in headers_iter {
let (blob, height) = header?;
headers.push((
deserialize(&blob)
.unwrap_or_else(|_| panic!("Failed to deserialize header {}", height)),
height,
));
}
Ok(headers)
}
pub fn db_get_header(conn: &Connection, blockhash: &BlockHash) -> Result<BlockHeader> {
let mut stmt = conn.prepare("SELECT header FROM headers WHERE key = ?")?;
let mut row = stmt.query([blockhash.to_hex()])?;
let header: Option<Vec<u8>> = row.next()?.map(|r| r.get(0).expect("query header"));
match header {
Some(h) => {
let header = deserialize(&h)?;
Ok(header)
}
None => bail!("Header does not exist"),
}
}
/// Store headers to database
pub fn store_headers(conn: &Connection, headers: &[NewHeader]) -> Result<()> {
let mut stmt =
conn.prepare("INSERT OR IGNORE INTO headers (key, height, header) VALUES (?, ?, ?)")?;
for h in headers {
stmt.execute(params![h.hash.to_hex(), h.height, serialize(&h.header)])?;
}
Ok(())
}