mirror of
https://github.com/romanz/electrs.git
synced 2025-02-24 06:57:53 +01:00
Refactor rows' serialization into index
module
This commit is contained in:
parent
935467e6b4
commit
b0fb4d4367
2 changed files with 115 additions and 66 deletions
142
src/index.rs
142
src/index.rs
|
@ -17,7 +17,7 @@ use time;
|
|||
|
||||
use daemon::Daemon;
|
||||
use store::{Row, Store};
|
||||
use types::{full_hash, hash_prefix, FullHash, HashPrefix, HeaderMap};
|
||||
use types::{full_hash, hash_prefix, Bytes, FullHash, HashPrefix, HeaderMap, HASH_PREFIX_LEN};
|
||||
|
||||
// TODO: move to a separate file (to break index<->daemon dependency)
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
|
@ -103,6 +103,38 @@ pub struct TxInRow {
|
|||
pub txid_prefix: HashPrefix,
|
||||
}
|
||||
|
||||
impl TxInRow {
|
||||
pub fn new(txid: &Sha256dHash, input: &TxIn) -> TxInRow {
|
||||
TxInRow {
|
||||
key: TxInKey {
|
||||
code: b'I',
|
||||
prev_hash_prefix: hash_prefix(&input.prev_hash[..]),
|
||||
prev_index: input.prev_index as u16,
|
||||
},
|
||||
txid_prefix: hash_prefix(&txid[..]),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter(txid: &Sha256dHash, output_index: usize) -> Bytes {
|
||||
bincode::serialize(&TxInKey {
|
||||
code: b'I',
|
||||
prev_hash_prefix: hash_prefix(&txid[..]),
|
||||
prev_index: output_index as u16,
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
pub fn to_row(&self) -> Row {
|
||||
Row {
|
||||
key: bincode::serialize(&self).unwrap(),
|
||||
value: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_row(row: &Row) -> TxInRow {
|
||||
bincode::deserialize(&row.key).expect("failed to parse TxInRow")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct TxOutKey {
|
||||
code: u8,
|
||||
|
@ -115,12 +147,77 @@ pub struct TxOutRow {
|
|||
pub txid_prefix: HashPrefix,
|
||||
}
|
||||
|
||||
impl TxOutRow {
|
||||
pub fn new(txid: &Sha256dHash, output: &TxOut) -> TxOutRow {
|
||||
TxOutRow {
|
||||
key: TxOutKey {
|
||||
code: b'O',
|
||||
script_hash_prefix: hash_prefix(&compute_script_hash(&output.script_pubkey[..])),
|
||||
},
|
||||
txid_prefix: hash_prefix(&txid[..]),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter(script_hash: &[u8]) -> Bytes {
|
||||
bincode::serialize(&TxOutKey {
|
||||
code: b'O',
|
||||
script_hash_prefix: hash_prefix(&script_hash[..HASH_PREFIX_LEN]),
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
pub fn to_row(&self) -> Row {
|
||||
Row {
|
||||
key: bincode::serialize(&self).unwrap(),
|
||||
value: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_row(row: &Row) -> TxOutRow {
|
||||
bincode::deserialize(&row.key).expect("failed to parse TxOutRow")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct TxKey {
|
||||
code: u8,
|
||||
pub txid: FullHash,
|
||||
}
|
||||
|
||||
pub struct TxRow {
|
||||
pub key: TxKey,
|
||||
pub height: u32, // value
|
||||
}
|
||||
|
||||
impl TxRow {
|
||||
pub fn new(txid: &Sha256dHash, height: u32) -> TxRow {
|
||||
TxRow {
|
||||
key: TxKey {
|
||||
code: b'T',
|
||||
txid: full_hash(&txid[..]),
|
||||
},
|
||||
height: height,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filter(txid_prefix: &HashPrefix) -> Bytes {
|
||||
[b"T", &txid_prefix[..]].concat()
|
||||
}
|
||||
|
||||
pub fn to_row(&self) -> Row {
|
||||
Row {
|
||||
key: bincode::serialize(&self.key).unwrap(),
|
||||
value: bincode::serialize(&self.height).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_row(row: &Row) -> TxRow {
|
||||
TxRow {
|
||||
key: bincode::deserialize(&row.key).expect("failed to parse TxKey"),
|
||||
height: bincode::deserialize(&row.value).expect("failed to parse height"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct BlockKey {
|
||||
code: u8,
|
||||
|
@ -135,43 +232,6 @@ pub fn compute_script_hash(data: &[u8]) -> FullHash {
|
|||
hash
|
||||
}
|
||||
|
||||
fn txin_row(input: &TxIn, txid: &Sha256dHash) -> Row {
|
||||
Row {
|
||||
key: bincode::serialize(&TxInRow {
|
||||
key: TxInKey {
|
||||
code: b'I',
|
||||
prev_hash_prefix: hash_prefix(&input.prev_hash[..]),
|
||||
prev_index: input.prev_index as u16,
|
||||
},
|
||||
txid_prefix: hash_prefix(&txid[..]),
|
||||
}).unwrap(),
|
||||
value: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn txout_row(output: &TxOut, txid: &Sha256dHash) -> Row {
|
||||
Row {
|
||||
key: bincode::serialize(&TxOutRow {
|
||||
key: TxOutKey {
|
||||
code: b'O',
|
||||
script_hash_prefix: hash_prefix(&compute_script_hash(&output.script_pubkey[..])),
|
||||
},
|
||||
txid_prefix: hash_prefix(&txid[..]),
|
||||
}).unwrap(),
|
||||
value: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn tx_row(txid: &Sha256dHash, height: usize) -> Row {
|
||||
Row {
|
||||
key: bincode::serialize(&TxKey {
|
||||
code: b'T',
|
||||
txid: full_hash(&txid[..]),
|
||||
}).unwrap(),
|
||||
value: bincode::serialize(&(height as u32)).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn block_rows(block: &Block) -> Vec<Row> {
|
||||
let blockhash = block.bitcoin_hash();
|
||||
vec![
|
||||
|
@ -198,13 +258,13 @@ fn index_block(block: &Block, height: usize) -> Vec<Row> {
|
|||
if input.prev_hash == null_hash {
|
||||
continue;
|
||||
}
|
||||
rows.push(txin_row(&input, &txid));
|
||||
rows.push(TxInRow::new(&txid, &input).to_row());
|
||||
}
|
||||
for output in &tx.output {
|
||||
rows.push(txout_row(&output, &txid))
|
||||
rows.push(TxOutRow::new(&txid, &output).to_row());
|
||||
}
|
||||
// Persist transaction ID and confirmed height
|
||||
rows.push(tx_row(&txid, height))
|
||||
rows.push(TxRow::new(&txid, height as u32).to_row());
|
||||
}
|
||||
// Persist block hash and header
|
||||
rows.extend(block_rows(&block));
|
||||
|
|
39
src/query.rs
39
src/query.rs
|
@ -1,4 +1,3 @@
|
|||
use bincode;
|
||||
use bitcoin::blockdata::block::{Block, BlockHeader};
|
||||
use bitcoin::blockdata::transaction::Transaction;
|
||||
use bitcoin::network::serialize::deserialize;
|
||||
|
@ -6,9 +5,9 @@ use bitcoin::util::hash::Sha256dHash;
|
|||
use itertools::enumerate;
|
||||
|
||||
use daemon::Daemon;
|
||||
use index::{compute_script_hash, HeaderEntry, Index, TxInKey, TxInRow, TxKey, TxOutRow};
|
||||
use index::{compute_script_hash, HeaderEntry, Index, TxInRow, TxOutRow, TxRow};
|
||||
use store::Store;
|
||||
use types::{hash_prefix, HashPrefix, HASH_PREFIX_LEN};
|
||||
use types::HashPrefix;
|
||||
|
||||
pub struct Query<'a> {
|
||||
store: &'a Store,
|
||||
|
@ -58,14 +57,17 @@ impl<'a> Query<'a> {
|
|||
fn load_txns(&self, prefixes: Vec<HashPrefix>) -> Vec<TxnHeight> {
|
||||
let mut txns = Vec::new();
|
||||
for txid_prefix in prefixes {
|
||||
for row in self.store.scan(&[b"T", &txid_prefix[..]].concat()) {
|
||||
let key: TxKey = bincode::deserialize(&row.key).unwrap();
|
||||
let txid: Sha256dHash = deserialize(&key.txid).unwrap();
|
||||
let tx_rows: Vec<TxRow> = self.store
|
||||
.scan(&TxRow::filter(&txid_prefix))
|
||||
.iter()
|
||||
.map(|row| TxRow::from_row(row))
|
||||
.collect();
|
||||
for tx_row in tx_rows {
|
||||
let txid: Sha256dHash = deserialize(&tx_row.key.txid).unwrap();
|
||||
let txn: Transaction = self.get_tx(&txid);
|
||||
let height: u32 = bincode::deserialize(&row.value).unwrap();
|
||||
txns.push(TxnHeight {
|
||||
txn,
|
||||
height: height as i32,
|
||||
height: tx_row.height as i32,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -73,20 +75,11 @@ impl<'a> Query<'a> {
|
|||
}
|
||||
|
||||
fn find_spending_input(&self, funding: &FundingOutput) -> Option<SpendingInput> {
|
||||
let spend_key = bincode::serialize(&TxInKey {
|
||||
code: b'I',
|
||||
prev_hash_prefix: hash_prefix(&funding.txn_id[..]),
|
||||
prev_index: funding.output_index as u16,
|
||||
}).unwrap();
|
||||
let spending_txns: Vec<TxnHeight> = self.load_txns(
|
||||
self.store
|
||||
.scan(&spend_key)
|
||||
.scan(&TxInRow::filter(&funding.txn_id, funding.output_index))
|
||||
.iter()
|
||||
.map(|row| {
|
||||
bincode::deserialize::<TxInRow>(&row.key)
|
||||
.unwrap()
|
||||
.txid_prefix
|
||||
})
|
||||
.map(|row| TxInRow::from_row(row).txid_prefix)
|
||||
.collect(),
|
||||
);
|
||||
let mut spending_inputs = Vec::new();
|
||||
|
@ -120,13 +113,9 @@ impl<'a> Query<'a> {
|
|||
|
||||
let funding_txns = self.load_txns(
|
||||
self.store
|
||||
.scan(&[b"O", &script_hash[..HASH_PREFIX_LEN]].concat())
|
||||
.scan(&TxOutRow::filter(script_hash))
|
||||
.iter()
|
||||
.map(|row| {
|
||||
bincode::deserialize::<TxOutRow>(&row.key)
|
||||
.unwrap()
|
||||
.txid_prefix
|
||||
})
|
||||
.map(|row| TxOutRow::from_row(row).txid_prefix)
|
||||
.collect(),
|
||||
);
|
||||
for t in funding_txns {
|
||||
|
|
Loading…
Add table
Reference in a new issue