1
0
mirror of https://github.com/romanz/electrs.git synced 2024-11-19 09:54:09 +01:00

Move HeaderList stuff to 'util' module

This commit is contained in:
Roman Zeyde 2018-05-18 12:08:52 +03:00
parent 0c4e500fb8
commit 33f68509f8
No known key found for this signature in database
GPG Key ID: 87CAE5FA46917CBB
8 changed files with 134 additions and 137 deletions

View File

@ -11,8 +11,7 @@ use std::fs;
use std::io::{BufRead, BufReader, Write};
use std::net::TcpStream;
use index::HeaderList;
use types::HeaderMap;
use util::{HeaderList, HeaderMap};
error_chain!{}

View File

@ -8,124 +8,17 @@ use crypto::digest::Digest;
use crypto::sha2::Sha256;
use log::Level;
use pbr;
use std::collections::VecDeque;
use std::fmt;
use std::io::{stderr, Stderr};
use std::iter::FromIterator;
use std::sync::{Arc, RwLock};
use std::time::{Duration, Instant};
use time;
use daemon::Daemon;
use store::{Row, Store};
use types::{full_hash, hash_prefix, Bytes, FullHash, HashPrefix, HeaderMap, HASH_PREFIX_LEN};
use util::{full_hash, hash_prefix, Bytes, FullHash, HashPrefix, HeaderEntry, HeaderList,
HeaderMap, HASH_PREFIX_LEN};
type ProgressBar = pbr::ProgressBar<Stderr>;
// TODO: move to a separate file (to break index<->daemon dependency)
#[derive(Eq, PartialEq, Clone)]
pub struct HeaderEntry {
height: usize,
hash: Sha256dHash,
header: BlockHeader,
}
impl HeaderEntry {
pub fn hash(&self) -> &Sha256dHash {
&self.hash
}
pub fn header(&self) -> &BlockHeader {
&self.header
}
pub fn height(&self) -> usize {
self.height
}
}
pub struct HeaderList {
headers: Vec<HeaderEntry>,
tip: Sha256dHash,
}
impl HeaderList {
pub fn build(mut header_map: HeaderMap, mut blockhash: Sha256dHash) -> HeaderList {
let null_hash = Sha256dHash::default();
let tip = blockhash;
struct HashedHeader {
blockhash: Sha256dHash,
header: BlockHeader,
}
let mut hashed_headers = VecDeque::<HashedHeader>::new();
while blockhash != null_hash {
let header: BlockHeader = header_map.remove(&blockhash).unwrap();
hashed_headers.push_front(HashedHeader { blockhash, header });
blockhash = header.prev_blockhash;
}
if !header_map.is_empty() {
warn!("orphaned blocks: {:?}", header_map);
}
HeaderList {
headers: hashed_headers
.into_iter()
.enumerate()
.map(|(height, hashed_header)| HeaderEntry {
height: height,
hash: hashed_header.blockhash,
header: hashed_header.header,
})
.collect(),
tip: tip,
}
}
pub fn empty() -> HeaderList {
HeaderList {
headers: vec![],
tip: Sha256dHash::default(),
}
}
pub fn equals(&self, other: &HeaderList) -> bool {
self.headers.last() == other.headers.last()
}
pub fn headers(&self) -> &[HeaderEntry] {
&self.headers
}
pub fn tip(&self) -> Sha256dHash {
self.tip
}
pub fn height(&self) -> usize {
self.headers.len() - 1
}
pub fn as_map(&self) -> HeaderMap {
HeaderMap::from_iter(self.headers.iter().map(|entry| (entry.hash, entry.header)))
}
}
impl fmt::Debug for HeaderList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let last_block_time = self.headers.last().map_or("N/A".to_string(), |h| {
time::at_utc(time::Timespec::new(h.header.time as i64, 0))
.rfc3339()
.to_string()
});
write!(
f,
"best={} height={} @ {}",
self.height(),
self.tip(),
last_block_time,
)
}
}
#[derive(Serialize, Deserialize)]
pub struct TxInKey {
pub code: u8,

View File

@ -29,5 +29,4 @@ pub mod mempool;
pub mod query;
pub mod rpc;
pub mod store;
pub mod types;
pub mod util;

View File

@ -6,10 +6,10 @@ use itertools::enumerate;
use std::sync::RwLock;
use daemon::Daemon;
use index::{compute_script_hash, HeaderEntry, Index, TxInRow, TxOutRow, TxRow};
use index::{compute_script_hash, Index, TxInRow, TxOutRow, TxRow};
use mempool::Tracker;
use store::Store;
use types::HashPrefix;
use util::{HashPrefix, HeaderEntry};
error_chain!{}

View File

@ -14,7 +14,7 @@ use std::net::{SocketAddr, TcpListener, TcpStream};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use query::{Query, Status};
use types::FullHash;
use util::FullHash;
error_chain!{}

View File

@ -2,7 +2,7 @@ use bitcoin::blockdata::block::BlockHeader;
use bitcoin::network::serialize::deserialize;
use rocksdb;
use types::Bytes;
use util::Bytes;
pub struct Store {
db: rocksdb::DB,

View File

@ -1,21 +0,0 @@
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::util::hash::Sha256dHash;
use std::collections::HashMap;
pub type Bytes = Vec<u8>;
pub type HeaderMap = HashMap<Sha256dHash, BlockHeader>;
// TODO: consolidate serialization/deserialize code for bincode/bitcoin.
const HASH_LEN: usize = 32;
pub const HASH_PREFIX_LEN: usize = 8;
pub type FullHash = [u8; HASH_LEN];
pub type HashPrefix = [u8; HASH_PREFIX_LEN];
pub fn hash_prefix(hash: &[u8]) -> HashPrefix {
array_ref![hash, 0, HASH_PREFIX_LEN].clone()
}
pub fn full_hash(hash: &[u8]) -> FullHash {
array_ref![hash, 0, HASH_LEN].clone()
}

View File

@ -1 +1,128 @@
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::util::hash::Sha256dHash;
use std::collections::HashMap;
use std::collections::VecDeque;
use std::fmt;
use std::iter::FromIterator;
use time;
pub type Bytes = Vec<u8>;
pub type HeaderMap = HashMap<Sha256dHash, BlockHeader>;
// TODO: consolidate serialization/deserialize code for bincode/bitcoin.
const HASH_LEN: usize = 32;
pub const HASH_PREFIX_LEN: usize = 8;
pub type FullHash = [u8; HASH_LEN];
pub type HashPrefix = [u8; HASH_PREFIX_LEN];
pub fn hash_prefix(hash: &[u8]) -> HashPrefix {
array_ref![hash, 0, HASH_PREFIX_LEN].clone()
}
pub fn full_hash(hash: &[u8]) -> FullHash {
array_ref![hash, 0, HASH_LEN].clone()
}
#[derive(Eq, PartialEq, Clone)]
pub struct HeaderEntry {
height: usize,
hash: Sha256dHash,
header: BlockHeader,
}
impl HeaderEntry {
pub fn hash(&self) -> &Sha256dHash {
&self.hash
}
pub fn header(&self) -> &BlockHeader {
&self.header
}
pub fn height(&self) -> usize {
self.height
}
}
pub struct HeaderList {
headers: Vec<HeaderEntry>,
tip: Sha256dHash,
}
impl HeaderList {
pub fn build(mut header_map: HeaderMap, mut blockhash: Sha256dHash) -> HeaderList {
let null_hash = Sha256dHash::default();
let tip = blockhash;
struct HashedHeader {
blockhash: Sha256dHash,
header: BlockHeader,
}
let mut hashed_headers = VecDeque::<HashedHeader>::new();
while blockhash != null_hash {
let header: BlockHeader = header_map.remove(&blockhash).unwrap();
hashed_headers.push_front(HashedHeader { blockhash, header });
blockhash = header.prev_blockhash;
}
if !header_map.is_empty() {
warn!("orphaned blocks: {:?}", header_map);
}
HeaderList {
headers: hashed_headers
.into_iter()
.enumerate()
.map(|(height, hashed_header)| HeaderEntry {
height: height,
hash: hashed_header.blockhash,
header: hashed_header.header,
})
.collect(),
tip: tip,
}
}
pub fn empty() -> HeaderList {
HeaderList {
headers: vec![],
tip: Sha256dHash::default(),
}
}
pub fn equals(&self, other: &HeaderList) -> bool {
self.headers.last() == other.headers.last()
}
pub fn headers(&self) -> &[HeaderEntry] {
&self.headers
}
pub fn tip(&self) -> Sha256dHash {
self.tip
}
pub fn height(&self) -> usize {
self.headers.len() - 1
}
pub fn as_map(&self) -> HeaderMap {
HeaderMap::from_iter(self.headers.iter().map(|entry| (entry.hash, entry.header)))
}
}
impl fmt::Debug for HeaderList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let last_block_time = self.headers.last().map_or("N/A".to_string(), |h| {
time::at_utc(time::Timespec::new(h.header.time as i64, 0))
.rfc3339()
.to_string()
});
write!(
f,
"best={} height={} @ {}",
self.height(),
self.tip(),
last_block_time,
)
}
}