Unverified Commit 04b25689 authored by Roman Zeyde's avatar Roman Zeyde
Browse files

Move Status-related functions to `query` module

parent 8a3b6f90
......@@ -2,14 +2,17 @@ use bitcoin::blockdata::block::{Block, BlockHeader};
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::network::serialize::deserialize;
use bitcoin::util::hash::Sha256dHash;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use itertools::enumerate;
use std::collections::HashMap;
use std::sync::RwLock;
use daemon::Daemon;
use index::{compute_script_hash, Index, TxInRow, TxOutRow, TxRow};
use mempool::Tracker;
use store::Store;
use util::{HashPrefix, HeaderEntry};
use util::{FullHash, HashPrefix, HeaderEntry};
error_chain!{}
......@@ -27,11 +30,44 @@ pub struct SpendingInput {
}
pub struct Status {
// TODO: make private
pub balance: u64,
pub funding: Vec<FundingOutput>,
pub spending: Vec<SpendingInput>,
}
impl Status {
pub fn history(&self) -> Vec<(i32, Sha256dHash)> {
let mut txns_map = HashMap::<Sha256dHash, i32>::new();
for f in &self.funding {
txns_map.insert(f.txn_id, f.height);
}
for s in &self.spending {
txns_map.insert(s.txn_id, s.height);
}
let mut txns: Vec<(i32, Sha256dHash)> =
txns_map.into_iter().map(|item| (item.1, item.0)).collect();
txns.sort();
txns
}
pub fn hash(&self) -> Option<FullHash> {
let txns = self.history();
if txns.is_empty() {
None
} else {
let mut hash = FullHash::default();
let mut sha2 = Sha256::new();
for (height, txn_id) in txns {
let part = format!("{}:{}:", txn_id.be_hex_string(), height);
sha2.input(part.as_bytes());
}
sha2.result(&mut hash);
Some(hash)
}
}
}
struct TxnHeight {
txn: Transaction,
height: i32,
......
......@@ -3,8 +3,6 @@ use bitcoin::blockdata::transaction::Transaction;
use bitcoin::network::serialize::{deserialize, serialize};
use bitcoin::util::hash::Sha256dHash;
use crossbeam;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use hex;
use itertools;
use serde_json::{from_str, Number, Value};
......@@ -13,8 +11,7 @@ use std::io::{BufRead, BufReader, Write};
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use query::{Query, Status};
use util::FullHash;
use query::Query;
error_chain!{}
......@@ -26,36 +23,6 @@ fn hash_from_value(val: Option<&Value>) -> Result<Sha256dHash> {
Ok(script_hash)
}
fn history_from_status(status: &Status) -> Vec<(i32, Sha256dHash)> {
let mut txns_map = HashMap::<Sha256dHash, i32>::new();
for f in &status.funding {
txns_map.insert(f.txn_id, f.height);
}
for s in &status.spending {
txns_map.insert(s.txn_id, s.height);
}
let mut txns: Vec<(i32, Sha256dHash)> =
txns_map.into_iter().map(|item| (item.1, item.0)).collect();
txns.sort();
txns
}
fn hash_from_status(status: &Status) -> Value {
let txns = history_from_status(status);
if txns.is_empty() {
return Value::Null;
}
let mut hash = FullHash::default();
let mut sha2 = Sha256::new();
for (height, txn_id) in txns {
let part = format!("{}:{}:", txn_id.be_hex_string(), height);
sha2.input(part.as_bytes());
}
sha2.result(&mut hash);
Value::String(hex::encode(&hash))
}
fn jsonify_header(header: &BlockHeader, height: usize) -> Value {
json!({
"block_height": height,
......@@ -148,7 +115,7 @@ impl<'a> Connection<'a> {
fn blockchain_scripthash_subscribe(&mut self, params: &[Value]) -> Result<Value> {
let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?;
let status = self.query.status(&script_hash[..]);
let result = hash_from_status(&status);
let result = status.hash().map_or(Value::Null, |h| json!(hex::encode(h)));
self.status_hashes.insert(script_hash, result.clone());
Ok(result)
}
......@@ -163,7 +130,8 @@ impl<'a> Connection<'a> {
let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?;
let status = self.query.status(&script_hash[..]);
Ok(json!(Value::Array(
history_from_status(&status)
status
.history()
.into_iter()
.map(|item| json!({"height": item.0, "tx_hash": item.1.be_hex_string()}))
.collect()
......@@ -244,7 +212,7 @@ impl<'a> Connection<'a> {
}
for (script_hash, status_hash) in self.status_hashes.iter_mut() {
let status = self.query.status(&script_hash[..]);
let new_status_hash = hash_from_status(&status);
let new_status_hash = status.hash().map_or(Value::Null, |h| json!(hex::encode(h)));
if new_status_hash == *status_hash {
continue;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment