use crate::chaindef::OutPointHash;
use crate::store::{db_decode, db_encode, Row};
use bitcoincash::hashes::Hash;
use bitcoincash::Txid;
use super::DBRow;
use anyhow::{Context, Result};
const OUTPUTINDEX_CF: &str = "output";
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct OutputIndexKey {
pub hash: [u8; 32],
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct OutputIndexRow {
key: OutputIndexKey,
txid: [u8; 32],
index: u32,
value: u64,
height: u32,
}
fn deserialize_value(value: &[u8]) -> Result<([u8; 32], u32, u64, u32)> {
db_decode(value).context("failed to parse OutputIndexRow value")
}
impl OutputIndexRow {
pub fn new(
txid: &Txid,
outpoint_hash: &OutPointHash,
output_value: u64,
output_index: u32,
height: u32,
) -> OutputIndexRow {
OutputIndexRow {
key: OutputIndexKey {
hash: outpoint_hash.into_inner(),
},
txid: txid.into_inner(),
index: output_index,
value: output_value,
height,
}
}
pub fn filter_by_outpointhash(hash: &OutPointHash) -> Vec<u8> {
db_encode(&OutputIndexKey {
hash: hash.into_inner(),
})
.unwrap()
}
pub fn hash(&self) -> OutPointHash {
OutPointHash::from_inner(self.key.hash)
}
pub fn take_hash(self) -> OutPointHash {
OutPointHash::from_inner(self.key.hash)
}
pub fn txid(&self) -> Txid {
Txid::from_inner(self.txid)
}
pub fn txid_inner(&self) -> &[u8; 32] {
&self.txid
}
pub fn index(&self) -> u32 {
self.index
}
pub fn value(&self) -> u64 {
self.value
}
pub(crate) fn txid_from_value(value: &[u8]) -> Result<Txid> {
let (txid, _index, _value, _height): ([u8; 32], u32, u64, u32) = deserialize_value(value)?;
Ok(Txid::from_inner(txid))
}
#[cfg(nexa)]
pub(crate) fn txid_and_height_from_value(value: &[u8]) -> Result<(Txid, u32)> {
let (txid, _index, _value, height): ([u8; 32], u32, u64, u32) = deserialize_value(value)?;
Ok((Txid::from_inner(txid), height))
}
pub fn height(&self) -> u32 {
self.height
}
}
impl DBRow for OutputIndexRow {
const CF: &'static str = OUTPUTINDEX_CF;
fn to_row(&self) -> Row {
Row {
key: db_encode(&self.key).unwrap().into_boxed_slice(),
value: db_encode(&(self.txid, self.index, self.value, self.height))
.unwrap()
.into_boxed_slice(),
}
}
fn from_row(row: &Row) -> OutputIndexRow {
let (txid, index, value, height) =
deserialize_value(&row.value).expect("failed to parse OutputIndexRow");
OutputIndexRow {
key: db_decode(&row.key).expect("failed to parse OutputIndexKey"),
txid,
index,
value,
height,
}
}
}