1
0
Fork 0
mirror of https://github.com/romanz/electrs.git synced 2025-02-24 15:02:21 +01:00

WIP on migrating to new bitcoin::hash_types

All types are replaced; only work on merkle types left,
which requires addition of the code
This commit is contained in:
Dr. Maxim Orlovsky 2020-04-19 23:39:57 +02:00
parent 0f3aaa6671
commit 969364af00
11 changed files with 140 additions and 210 deletions

116
Cargo.lock generated
View file

@ -83,7 +83,7 @@ dependencies = [
[[package]]
name = "bech32"
version = "0.7.1"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -119,23 +119,21 @@ dependencies = [
[[package]]
name = "bitcoin"
version = "0.21.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitcoin_hashes 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitcoin_hashes 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"secp256k1 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
"secp256k1 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitcoin_hashes"
version = "0.7.1"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -337,8 +335,8 @@ version = "0.8.3"
dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitcoin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitcoin_hashes 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitcoin 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitcoin_hashes 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"configure_me 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"configure_me_codegen 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -717,33 +715,6 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.1"
@ -757,32 +728,6 @@ name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand_hc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_isaac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_jitter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_os"
version = "0.1.3"
@ -796,23 +741,6 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_pcg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "1.2.0"
@ -946,11 +874,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "secp256k1"
version = "0.15.5"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"secp256k1-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "secp256k1-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1273,11 +1209,11 @@ dependencies = [
"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0089c35ab7c6f2bc55ab23f769913f0ac65b1023e7e74638a1f43128dd5df2"
"checksum bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c"
"checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92"
"checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260"
"checksum bitcoin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc34f963060a2091b4e285d8082e1946be35caf467e73b3155262c8357fb4595"
"checksum bitcoin_hashes 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "db6b697833d852acea530c9e815e6adc724267856b6506bc500362a068a39c7b"
"checksum bitcoin 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a32c9d2fa897cfbb0db45d71e3d2838666194abc4828c0f994e4b5c3bf85ba4"
"checksum bitcoin_hashes 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b375d62f341cef9cd9e77793ec8f1db3fc9ce2e4d57e982c8fe697a2c16af3b6"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
@ -1347,16 +1283,9 @@ dependencies = [
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123"
"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
@ -1374,7 +1303,8 @@ dependencies = [
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum secp256k1 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4d311229f403d64002e9eed9964dfa5a0a0c1ac443344f7546bf48e916c6053a"
"checksum secp256k1 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2932dc07acd2066ff2e3921a4419606b220ba6cd03a9935123856cc534877056"
"checksum secp256k1-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ab2c26f0d3552a0f12e639ae8a64afc2e3db9c52fe32f5fc6c289d38519f220"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"

View file

@ -24,8 +24,8 @@ latest_rust = [] # use latest Rust features (otherwise, support Rust 1.34)
[dependencies]
base64 = "0.10"
bincode = "1.0"
bitcoin = { version = "0.21", features = ["use-serde"] }
bitcoin_hashes = "0.7.1"
bitcoin = { version = "0.23", features = ["use-serde"] }
bitcoin_hashes = "0.7.6"
configure_me = "0.3.3"
crossbeam-channel = "0.3"
dirs = "1.0"

View file

@ -1,4 +1,4 @@
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin::hash_types::BlockHash;
use std::sync::{Arc, Mutex};
use crate::{config::Config, daemon, errors::*, index, signal::Waiter, store};
@ -8,7 +8,7 @@ pub struct App {
index: index::Index,
daemon: daemon::Daemon,
banner: String,
tip: Mutex<Sha256dHash>,
tip: Mutex<BlockHash>,
}
impl App {
@ -23,7 +23,7 @@ impl App {
index,
daemon: daemon.reconnect()?,
banner: config.server_banner.clone(),
tip: Mutex::new(Sha256dHash::default()),
tip: Mutex::new(BlockHash::default()),
}))
}

View file

@ -1,7 +1,6 @@
use bitcoin::hash_types::BlockHash;
use bitcoin::blockdata::block::Block;
use bitcoin::consensus::encode::{deserialize, Decodable};
use bitcoin::util::hash::BitcoinHash;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use libc;
use std::collections::HashSet;
use std::fs;
@ -20,11 +19,12 @@ use crate::metrics::{CounterVec, Histogram, HistogramOpts, HistogramVec, MetricO
use crate::signal::Waiter;
use crate::store::{DBStore, Row, WriteStore};
use crate::util::{spawn_thread, HeaderList, SyncChannel};
use bitcoin::BitcoinHash;
struct Parser {
magic: u32,
current_headers: HeaderList,
indexed_blockhashes: Mutex<HashSet<Sha256dHash>>,
indexed_blockhashes: Mutex<HashSet<BlockHash>>,
// metrics
duration: HistogramVec,
block_count: CounterVec,
@ -35,7 +35,7 @@ impl Parser {
fn new(
daemon: &Daemon,
metrics: &Metrics,
indexed_blockhashes: HashSet<Sha256dHash>,
indexed_blockhashes: HashSet<BlockHash>,
) -> Result<Arc<Parser>> {
Ok(Arc::new(Parser {
magic: daemon.magic(),

View file

@ -1,9 +1,9 @@
use crate::errors::*;
use crate::metrics::{CounterVec, MetricOpts, Metrics};
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::consensus::encode::deserialize;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use lru::LruCache;
use prometheus::IntGauge;
use std::hash::Hash;
@ -62,7 +62,7 @@ impl<K: Hash + Eq, V> SizedLruCache<K, V> {
}
pub struct BlockTxIDsCache {
map: Mutex<SizedLruCache<Sha256dHash /* blockhash */, Vec<Sha256dHash /* txid */>>>,
map: Mutex<SizedLruCache<BlockHash, Vec<Txid>>>,
}
impl BlockTxIDsCache {
@ -85,11 +85,11 @@ impl BlockTxIDsCache {
pub fn get_or_else<F>(
&self,
blockhash: &Sha256dHash,
blockhash: &BlockHash,
load_txids_func: F,
) -> Result<Vec<Sha256dHash>>
) -> Result<Vec<Txid>>
where
F: FnOnce() -> Result<Vec<Sha256dHash>>,
F: FnOnce() -> Result<Vec<Txid>>,
{
if let Some(txids) = self.map.lock().unwrap().get(blockhash) {
return Ok(txids.clone());
@ -107,7 +107,7 @@ impl BlockTxIDsCache {
pub struct TransactionCache {
// Store serialized transaction (should use less RAM).
map: Mutex<SizedLruCache<Sha256dHash, Vec<u8>>>,
map: Mutex<SizedLruCache<Txid, Vec<u8>>>,
}
impl TransactionCache {
@ -128,7 +128,7 @@ impl TransactionCache {
}
}
pub fn get_or_else<F>(&self, txid: &Sha256dHash, load_txn_func: F) -> Result<Transaction>
pub fn get_or_else<F>(&self, txid: &Txid, load_txn_func: F) -> Result<Transaction>
where
F: FnOnce() -> Result<Vec<u8>>,
{
@ -201,17 +201,17 @@ mod tests {
assert_eq!(usage.get(), 100);
}
fn gen_hash(seed: u8) -> Sha256dHash {
fn gen_hash<T: Hash>(seed: u8) -> T {
let bytes: Vec<u8> = (seed..seed + 32).collect();
Sha256dHash::hash(&bytes[..])
<T as Hash>::hash(&bytes[..])
}
#[test]
fn test_blocktxids_cache_hit_and_miss() {
let block1 = gen_hash(1);
let block2 = gen_hash(2);
let block3 = gen_hash(3);
let txids = vec![gen_hash(4), gen_hash(5)];
let block1: BlockHash = gen_hash(1);
let block2: BlockHash = gen_hash(2);
let block3: BlockHash = gen_hash(3);
let txids: Vec<Txid> = vec![gen_hash(4), gen_hash(5)];
let misses: Mutex<usize> = Mutex::new(0);
let miss_func = || {
@ -249,7 +249,6 @@ mod tests {
#[test]
fn test_txn_cache() {
use bitcoin::util::hash::BitcoinHash;
use hex;
let dummy_metrics = Metrics::new("127.0.0.1:60000".parse().unwrap());
@ -257,7 +256,7 @@ mod tests {
let tx_bytes = hex::decode("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap();
let tx: Transaction = deserialize(&tx_bytes).unwrap();
let txid = tx.bitcoin_hash();
let txid = tx.txid();
let mut misses = 0;
assert_eq!(

View file

@ -1,11 +1,11 @@
use base64;
use bitcoin_hashes::Hash;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::blockdata::block::{Block, BlockHeader};
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::consensus::encode::{deserialize, serialize};
use bitcoin::network::constants::Network;
use bitcoin::util::hash::BitcoinHash;
use bitcoin_hashes::hex::{FromHex, ToHex};
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use glob;
use hex;
use serde_json::{from_str, from_value, Map, Value};
@ -22,9 +22,10 @@ use crate::errors::*;
use crate::metrics::{HistogramOpts, HistogramVec, Metrics};
use crate::signal::Waiter;
use crate::util::HeaderList;
use bitcoin::BitcoinHash;
fn parse_hash(value: &Value) -> Result<Sha256dHash> {
Ok(Sha256dHash::from_hex(
fn parse_hash<T: Hash>(value: &Value) -> Result<T> {
Ok(T::from_hex(
value
.as_str()
.chain_err(|| format!("non-string value: {}", value))?,
@ -460,11 +461,11 @@ impl Daemon {
Ok(self.getnetworkinfo()?.relayfee)
}
pub fn getbestblockhash(&self) -> Result<Sha256dHash> {
pub fn getbestblockhash(&self) -> Result<BlockHash> {
parse_hash(&self.request("getbestblockhash", json!([]))?).chain_err(|| "invalid blockhash")
}
pub fn getblockheader(&self, blockhash: &Sha256dHash) -> Result<BlockHeader> {
pub fn getblockheader(&self, blockhash: &BlockHash) -> Result<BlockHeader> {
header_from_value(self.request(
"getblockheader",
json!([blockhash.to_hex(), /*verbose=*/ false]),
@ -485,7 +486,7 @@ impl Daemon {
Ok(result)
}
pub fn getblock(&self, blockhash: &Sha256dHash) -> Result<Block> {
pub fn getblock(&self, blockhash: &BlockHash) -> Result<Block> {
let block = block_from_value(
self.request("getblock", json!([blockhash.to_hex(), /*verbose=*/ false]))?,
)?;
@ -493,7 +494,7 @@ impl Daemon {
Ok(block)
}
fn load_blocktxids(&self, blockhash: &Sha256dHash) -> Result<Vec<Sha256dHash>> {
fn load_blocktxids(&self, blockhash: &BlockHash) -> Result<Vec<Txid>> {
self.request("getblock", json!([blockhash.to_hex(), /*verbose=*/ 1]))?
.get("tx")
.chain_err(|| "block missing txids")?
@ -501,15 +502,15 @@ impl Daemon {
.chain_err(|| "invalid block txids")?
.iter()
.map(parse_hash)
.collect::<Result<Vec<Sha256dHash>>>()
.collect::<Result<Vec<Txid>>>()
}
pub fn getblocktxids(&self, blockhash: &Sha256dHash) -> Result<Vec<Sha256dHash>> {
pub fn getblocktxids(&self, blockhash: &BlockHash) -> Result<Vec<Txid>> {
self.blocktxids_cache
.get_or_else(&blockhash, || self.load_blocktxids(blockhash))
}
pub fn getblocks(&self, blockhashes: &[Sha256dHash]) -> Result<Vec<Block>> {
pub fn getblocks(&self, blockhashes: &[BlockHash]) -> Result<Vec<Block>> {
let params_list: Vec<Value> = blockhashes
.iter()
.map(|hash| json!([hash.to_hex(), /*verbose=*/ false]))
@ -524,8 +525,8 @@ impl Daemon {
pub fn gettransaction(
&self,
txhash: &Sha256dHash,
blockhash: Option<Sha256dHash>,
txhash: &Txid,
blockhash: Option<BlockHash>,
) -> Result<Transaction> {
let mut args = json!([txhash.to_hex(), /*verbose=*/ false]);
if let Some(blockhash) = blockhash {
@ -536,8 +537,8 @@ impl Daemon {
pub fn gettransaction_raw(
&self,
txhash: &Sha256dHash,
blockhash: Option<Sha256dHash>,
txhash: &Txid,
blockhash: Option<BlockHash>,
verbose: bool,
) -> Result<Value> {
let mut args = json!([txhash.to_hex(), verbose]);
@ -547,7 +548,7 @@ impl Daemon {
Ok(self.request("getrawtransaction", args)?)
}
pub fn gettransactions(&self, txhashes: &[&Sha256dHash]) -> Result<Vec<Transaction>> {
pub fn gettransactions(&self, txhashes: &[&Txid]) -> Result<Vec<Transaction>> {
let params_list: Vec<Value> = txhashes
.iter()
.map(|txhash| json!([txhash.to_hex(), /*verbose=*/ false]))
@ -562,7 +563,7 @@ impl Daemon {
Ok(txs)
}
pub fn getmempooltxids(&self) -> Result<HashSet<Sha256dHash>> {
pub fn getmempooltxids(&self) -> Result<HashSet<Txid>> {
let txids: Value = self.request("getrawmempool", json!([/*verbose=*/ false]))?;
let mut result = HashSet::new();
for value in txids.as_array().chain_err(|| "non-array result")? {
@ -571,7 +572,7 @@ impl Daemon {
Ok(result)
}
pub fn getmempoolentry(&self, txid: &Sha256dHash) -> Result<MempoolEntry> {
pub fn getmempoolentry(&self, txid: &Txid) -> Result<MempoolEntry> {
let entry = self.request("getmempoolentry", json!([txid.to_hex()]))?;
let fee = (entry
.get("fee")
@ -588,16 +589,16 @@ impl Daemon {
Ok(MempoolEntry::new(fee, vsize))
}
pub fn broadcast(&self, tx: &Transaction) -> Result<Sha256dHash> {
pub fn broadcast(&self, tx: &Transaction) -> Result<Txid> {
let tx = hex::encode(serialize(tx));
let txid = self.request("sendrawtransaction", json!([tx]))?;
Ok(
Sha256dHash::from_hex(txid.as_str().chain_err(|| "non-string txid")?)
Txid::from_hex(txid.as_str().chain_err(|| "non-string txid")?)
.chain_err(|| "failed to parse txid")?,
)
}
fn get_all_headers(&self, tip: &Sha256dHash) -> Result<Vec<BlockHeader>> {
fn get_all_headers(&self, tip: &BlockHash) -> Result<Vec<BlockHeader>> {
let info: Value = self.request("getblockheader", json!([tip.to_hex()]))?;
let tip_height = info
.get("height")
@ -607,7 +608,7 @@ impl Daemon {
let all_heights: Vec<usize> = (0..=tip_height).collect();
let chunk_size = 100_000;
let mut result = vec![];
let null_hash = Sha256dHash::default();
let null_hash = BlockHash::default();
for heights in all_heights.chunks(chunk_size) {
trace!("downloading {} block headers", heights.len());
let mut headers = self.getblockheaders(&heights)?;
@ -628,7 +629,7 @@ impl Daemon {
pub fn get_new_headers(
&self,
indexed_headers: &HeaderList,
bestblockhash: &Sha256dHash,
bestblockhash: &BlockHash,
) -> Result<Vec<BlockHeader>> {
// Iterate back over headers until known blockash is found:
if indexed_headers.is_empty() {
@ -640,7 +641,7 @@ impl Daemon {
bestblockhash,
);
let mut new_headers = vec![];
let null_hash = Sha256dHash::default();
let null_hash = BlockHash::default();
let mut blockhash = *bestblockhash;
while blockhash != null_hash {
if indexed_headers.header_by_blockhash(&blockhash).is_some() {

View file

@ -1,9 +1,8 @@
use bincode;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::blockdata::block::{Block, BlockHeader};
use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut};
use bitcoin::consensus::encode::{deserialize, serialize};
use bitcoin::util::hash::BitcoinHash;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use std::collections::{HashMap, HashSet};
@ -21,6 +20,7 @@ use crate::util::{
full_hash, hash_prefix, spawn_thread, Bytes, FullHash, HashPrefix, HeaderEntry, HeaderList,
HeaderMap, SyncChannel, HASH_PREFIX_LEN,
};
use bitcoin::BitcoinHash;
#[derive(Serialize, Deserialize)]
pub struct TxInKey {
@ -36,7 +36,7 @@ pub struct TxInRow {
}
impl TxInRow {
pub fn new(txid: &Sha256dHash, input: &TxIn) -> TxInRow {
pub fn new(txid: &Txid, input: &TxIn) -> TxInRow {
TxInRow {
key: TxInKey {
code: b'I',
@ -47,7 +47,7 @@ impl TxInRow {
}
}
pub fn filter(txid: &Sha256dHash, output_index: usize) -> Bytes {
pub fn filter(txid: &Txid, output_index: usize) -> Bytes {
bincode::serialize(&TxInKey {
code: b'I',
prev_hash_prefix: hash_prefix(&txid[..]),
@ -81,7 +81,7 @@ pub struct TxOutRow {
}
impl TxOutRow {
pub fn new(txid: &Sha256dHash, output: &TxOut) -> TxOutRow {
pub fn new(txid: &Txid, output: &TxOut) -> TxOutRow {
TxOutRow {
key: TxOutKey {
code: b'O',
@ -123,7 +123,7 @@ pub struct TxRow {
}
impl TxRow {
pub fn new(txid: &Sha256dHash, height: u32) -> TxRow {
pub fn new(txid: &Txid, height: u32) -> TxRow {
TxRow {
key: TxKey {
code: b'T',
@ -137,7 +137,7 @@ impl TxRow {
[b"T", &txid_prefix[..]].concat()
}
pub fn filter_full(txid: &Sha256dHash) -> Bytes {
pub fn filter_full(txid: &Txid) -> Bytes {
[b"T", &txid[..]].concat()
}
@ -174,8 +174,8 @@ pub fn index_transaction<'a>(
txn: &'a Transaction,
height: usize,
) -> impl 'a + Iterator<Item = Row> {
let null_hash = Sha256dHash::default();
let txid: Sha256dHash = txn.txid();
let null_hash = Txid::default();
let txid = txn.txid();
let inputs = txn.input.iter().filter_map(move |input| {
if input.previous_output.txid == null_hash {
@ -213,7 +213,7 @@ pub fn index_block<'a>(block: &'a Block, height: usize) -> impl 'a + Iterator<It
.chain(std::iter::once(row))
}
pub fn last_indexed_block(blockhash: &Sha256dHash) -> Row {
pub fn last_indexed_block(blockhash: &BlockHash) -> Row {
// Store last indexed block (i.e. all previous blocks were indexed)
Row {
key: b"L".to_vec(),
@ -221,7 +221,7 @@ pub fn last_indexed_block(blockhash: &Sha256dHash) -> Row {
}
}
pub fn read_indexed_blockhashes(store: &dyn ReadStore) -> HashSet<Sha256dHash> {
pub fn read_indexed_blockhashes(store: &dyn ReadStore) -> HashSet<BlockHash> {
let mut result = HashSet::new();
for row in store.scan(b"B") {
let key: BlockKey = bincode::deserialize(&row.key).unwrap();
@ -231,10 +231,10 @@ pub fn read_indexed_blockhashes(store: &dyn ReadStore) -> HashSet<Sha256dHash> {
}
fn read_indexed_headers(store: &dyn ReadStore) -> HeaderList {
let latest_blockhash: Sha256dHash = match store.get(b"L") {
let latest_blockhash: BlockHash = match store.get(b"L") {
// latest blockheader persisted in the DB.
Some(row) => deserialize(&row).unwrap(),
None => Sha256dHash::default(),
None => BlockHash::default(),
};
trace!("latest indexed blockhash: {}", latest_blockhash);
let mut map = HeaderMap::new();
@ -244,7 +244,7 @@ fn read_indexed_headers(store: &dyn ReadStore) -> HeaderList {
map.insert(deserialize(&key.hash).unwrap(), header);
}
let mut headers = vec![];
let null_hash = Sha256dHash::default();
let null_hash = BlockHash::default();
let mut blockhash = latest_blockhash;
while blockhash != null_hash {
let header = map
@ -264,7 +264,7 @@ fn read_indexed_headers(store: &dyn ReadStore) -> HeaderList {
assert_eq!(
headers
.last()
.map(BitcoinHash::bitcoin_hash)
.map(BlockHeader::bitcoin_hash)
.unwrap_or(null_hash),
latest_blockhash
);
@ -370,7 +370,7 @@ impl Index {
.cloned()
}
pub fn update(&self, store: &impl WriteStore, waiter: &Waiter) -> Result<Sha256dHash> {
pub fn update(&self, store: &impl WriteStore, waiter: &Waiter) -> Result<BlockHash> {
let daemon = self.daemon.reconnect()?;
let tip = daemon.getbestblockhash()?;
let new_headers: Vec<HeaderEntry> = {
@ -380,13 +380,13 @@ impl Index {
if let Some(latest_header) = new_headers.last() {
info!("{:?} ({} left to index)", latest_header, new_headers.len());
};
let height_map = HashMap::<Sha256dHash, usize>::from_iter(
let height_map = HashMap::<BlockHash, usize>::from_iter(
new_headers.iter().map(|h| (*h.hash(), h.height())),
);
let chan = SyncChannel::new(1);
let sender = chan.sender();
let blockhashes: Vec<Sha256dHash> = new_headers.iter().map(|h| *h.hash()).collect();
let blockhashes: Vec<BlockHash> = new_headers.iter().map(|h| *h.hash()).collect();
let batch_size = self.batch_size;
let fetcher = spawn_thread("fetcher", move || {
for chunk in blockhashes.chunks(batch_size) {

View file

@ -1,5 +1,5 @@
use bitcoin::hash_types::Txid;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use hex;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::iter::FromIterator;
@ -139,7 +139,7 @@ impl Stats {
}
pub struct Tracker {
items: HashMap<Sha256dHash, Item>,
items: HashMap<Txid, Item>,
index: MempoolStore,
histogram: Vec<(f32, u32)>,
stats: Stats,
@ -175,7 +175,7 @@ impl Tracker {
}
}
pub fn get_txn(&self, txid: &Sha256dHash) -> Option<Transaction> {
pub fn get_txn(&self, txid: &Txid) -> Option<Transaction> {
self.items.get(txid).map(|stats| stats.tx.clone())
}
@ -200,7 +200,7 @@ impl Tracker {
let timer = self.stats.start_timer("add");
let txids_iter = new_txids.difference(&old_txids);
let entries: Vec<(&Sha256dHash, MempoolEntry)> = txids_iter
let entries: Vec<(&Txid, MempoolEntry)> = txids_iter
.filter_map(|txid| {
match daemon.getmempoolentry(txid) {
Ok(entry) => Some((txid, entry)),
@ -212,7 +212,7 @@ impl Tracker {
})
.collect();
if !entries.is_empty() {
let txids: Vec<&Sha256dHash> = entries.iter().map(|(txid, _)| *txid).collect();
let txids: Vec<&Txid> = entries.iter().map(|(txid, _)| *txid).collect();
let txs = match daemon.gettransactions(&txids) {
Ok(txs) => txs,
Err(err) => {
@ -241,12 +241,12 @@ impl Tracker {
Ok(())
}
fn add(&mut self, txid: &Sha256dHash, tx: Transaction, entry: MempoolEntry) {
fn add(&mut self, txid: &Txid, tx: Transaction, entry: MempoolEntry) {
self.index.add(&tx);
self.items.insert(*txid, Item { tx, entry });
}
fn remove(&mut self, txid: &Sha256dHash) {
fn remove(&mut self, txid: &Txid) {
let stats = self
.items
.remove(txid)

View file

@ -4,7 +4,7 @@ use bitcoin::network::constants::Network;
use bitcoin::network::message::NetworkMessage;
use bitcoin::network::message_blockdata::InvType;
use bitcoin::network::socket::Socket;
use bitcoin::util::hash::Sha256dHash;
use bitcoin::hash_types::Txid;
use bitcoin::util::Error;
use std::sync::mpsc::Sender;
@ -19,7 +19,7 @@ fn connect() -> Result<Socket, Error> {
Ok(sock)
}
fn handle(mut sock: Socket, tx: Sender<Sha256dHash>) {
fn handle(mut sock: Socket, tx: Sender<Txid>) {
let mut outgoing = vec![sock.version_message(0).unwrap()];
loop {
for msg in outgoing.split_off(0) {
@ -53,7 +53,7 @@ fn handle(mut sock: Socket, tx: Sender<Sha256dHash>) {
}
}
pub fn run() -> util::Channel<Sha256dHash> {
pub fn run() -> util::Channel<Txid> {
let chan = util::Channel::new();
let tx = chan.sender();

View file

@ -1,7 +1,7 @@
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::consensus::encode::deserialize;
use bitcoin::hash_types::{Txid, BlockHash, TxMerkleNode};
use bitcoin_hashes::hex::ToHex;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin_hashes::Hash;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
@ -19,16 +19,16 @@ use crate::store::{ReadStore, Row};
use crate::util::{FullHash, HashPrefix, HeaderEntry};
pub struct FundingOutput {
pub txn_id: Sha256dHash,
pub txn_id: Txid,
pub height: u32,
pub output_index: usize,
pub value: u64,
}
type OutPoint = (Sha256dHash, usize); // (txid, output_index)
type OutPoint = (Txid, usize); // (txid, output_index)
struct SpendingInput {
txn_id: Sha256dHash,
txn_id: Txid,
height: u32,
funding_output: OutPoint,
value: u64,
@ -62,15 +62,15 @@ impl Status {
calc_balance(&self.mempool)
}
pub fn history(&self) -> Vec<(i32, Sha256dHash)> {
let mut txns_map = HashMap::<Sha256dHash, i32>::new();
pub fn history(&self) -> Vec<(i32, Txid)> {
let mut txns_map = HashMap::<Txid, i32>::new();
for f in self.funding() {
txns_map.insert(f.txn_id, f.height as i32);
}
for s in self.spending() {
txns_map.insert(s.txn_id, s.height as i32);
}
let mut txns: Vec<(i32, Sha256dHash)> =
let mut txns: Vec<(i32, Txid)> =
txns_map.into_iter().map(|item| (item.1, item.0)).collect();
txns.sort_unstable();
txns
@ -116,15 +116,15 @@ struct TxnHeight {
height: u32,
}
fn merklize(left: Sha256dHash, right: Sha256dHash) -> Sha256dHash {
fn merklize(left: TxMerkleNode, right: TxMerkleNode) -> TxMerkleNode {
let data = [&left[..], &right[..]].concat();
Sha256dHash::hash(&data)
TxMerkleNode::hash(&data)
}
fn create_merkle_branch_and_root(
mut hashes: Vec<Sha256dHash>,
mut hashes: Vec<TxMerkleNode>,
mut index: usize,
) -> (Vec<Sha256dHash>, Sha256dHash) {
) -> (Vec<TxMerkleNode>, TxMerkleNode) {
let mut merkle = vec![];
while hashes.len() > 1 {
if hashes.len() % 2 != 0 {
@ -143,7 +143,7 @@ fn create_merkle_branch_and_root(
}
// TODO: the functions below can be part of ReadStore.
fn txrow_by_txid(store: &dyn ReadStore, txid: &Sha256dHash) -> Option<TxRow> {
fn txrow_by_txid(store: &dyn ReadStore, txid: &Txid) -> Option<TxRow> {
let key = TxRow::filter_full(&txid);
let value = store.get(&key)?;
Some(TxRow::from_row(&Row { key, value }))
@ -167,7 +167,7 @@ fn txids_by_script_hash(store: &dyn ReadStore, script_hash: &[u8]) -> Vec<HashPr
fn txids_by_funding_output(
store: &dyn ReadStore,
txn_id: &Sha256dHash,
txn_id: &Txid,
output_index: usize,
) -> Vec<HashPrefix> {
store
@ -215,7 +215,7 @@ impl Query {
let mut txns = vec![];
for txid_prefix in prefixes {
for tx_row in txrows_by_prefix(store, txid_prefix) {
let txid: Sha256dHash = deserialize(&tx_row.key.txid).unwrap();
let txid: Txid = deserialize(&tx_row.key.txid).unwrap();
let txn = self.load_txn(&txid, Some(tx_row.height))?;
txns.push(TxnHeight {
txn,
@ -345,9 +345,9 @@ impl Query {
fn lookup_confirmed_blockhash(
&self,
tx_hash: &Sha256dHash,
tx_hash: &Txid,
block_height: Option<u32>,
) -> Result<Option<Sha256dHash>> {
) -> Result<Option<BlockHash>> {
let blockhash = if self.tracker.read().unwrap().get_txn(&tx_hash).is_some() {
None // found in mempool (as unconfirmed transaction)
} else {
@ -371,7 +371,7 @@ impl Query {
}
// Internal API for transaction retrieval
fn load_txn(&self, txid: &Sha256dHash, block_height: Option<u32>) -> Result<Transaction> {
fn load_txn(&self, txid: &Txid, block_height: Option<u32>) -> Result<Transaction> {
let _timer = self.duration.with_label_values(&["load_txn"]).start_timer();
self.tx_cache.get_or_else(&txid, || {
let blockhash = self.lookup_confirmed_blockhash(txid, block_height)?;
@ -385,7 +385,7 @@ impl Query {
}
// Public API for transaction retrieval (for Electrum RPC)
pub fn get_transaction(&self, tx_hash: &Sha256dHash, verbose: bool) -> Result<Value> {
pub fn get_transaction(&self, tx_hash: &Txid, verbose: bool) -> Result<Value> {
let _timer = self
.duration
.with_label_values(&["get_transaction"])
@ -415,9 +415,9 @@ impl Query {
pub fn get_merkle_proof(
&self,
tx_hash: &Sha256dHash,
tx_hash: &Txid,
height: usize,
) -> Result<(Vec<Sha256dHash>, usize)> {
) -> Result<(Vec<TxMerkleNode>, usize)> {
let header_entry = self
.app
.index()
@ -436,7 +436,7 @@ impl Query {
&self,
height: usize,
cp_height: usize,
) -> Result<(Vec<Sha256dHash>, Sha256dHash)> {
) -> Result<(Vec<BlockHash>, TxMerkleNode)> {
if cp_height < height {
bail!("cp_height #{} < height #{}", cp_height, height);
}
@ -451,7 +451,7 @@ impl Query {
}
let heights: Vec<usize> = (0..=cp_height).collect();
let header_hashes: Vec<Sha256dHash> = self
let header_hashes: Vec<BlockHash> = self
.get_headers(&heights)
.into_iter()
.map(|h| *h.hash())
@ -465,7 +465,7 @@ impl Query {
height: usize,
tx_pos: usize,
want_merkle: bool,
) -> Result<(Sha256dHash, Vec<Sha256dHash>)> {
) -> Result<(Txid, Vec<TxMerkleNode>)> {
let header_entry = self
.app
.index()
@ -485,7 +485,7 @@ impl Query {
Ok((txid, branch))
}
pub fn broadcast(&self, txn: &Transaction) -> Result<Sha256dHash> {
pub fn broadcast(&self, txn: &Transaction) -> Result<Txid> {
self.app.daemon().broadcast(txn)
}

View file

@ -1,6 +1,6 @@
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::hash_types::BlockHash;
use bitcoin::util::hash::BitcoinHash;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin::blockdata::block::BlockHeader;
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
@ -11,7 +11,7 @@ use std::thread;
use time;
pub type Bytes = Vec<u8>;
pub type HeaderMap = HashMap<Sha256dHash, BlockHeader>;
pub type HeaderMap = HashMap<BlockHash, BlockHeader>;
// TODO: consolidate serialization/deserialize code for bincode/bitcoin.
const HASH_LEN: usize = 32;
@ -33,12 +33,12 @@ pub fn full_hash(hash: &[u8]) -> FullHash {
#[derive(Eq, PartialEq, Clone)]
pub struct HeaderEntry {
height: usize,
hash: Sha256dHash,
hash: BlockHash,
header: BlockHeader,
}
impl HeaderEntry {
pub fn hash(&self) -> &Sha256dHash {
pub fn hash(&self) -> &BlockHash {
&self.hash
}
@ -66,7 +66,7 @@ impl fmt::Debug for HeaderEntry {
}
struct HashedHeader {
blockhash: Sha256dHash,
blockhash: BlockHash,
header: BlockHeader,
}
@ -88,7 +88,7 @@ fn hash_headers(headers: Vec<BlockHeader>) -> Vec<HashedHeader> {
pub struct HeaderList {
headers: Vec<HeaderEntry>,
heights: HashMap<Sha256dHash, usize>,
heights: HashMap<BlockHash, usize>,
}
impl HeaderList {
@ -106,7 +106,7 @@ impl HeaderList {
Some(h) => h.header.prev_blockhash,
None => return vec![], // hashed_headers is empty
};
let null_hash = Sha256dHash::default();
let null_hash = BlockHash::default();
let new_height: usize = if prev_blockhash == null_hash {
0
} else {
@ -125,8 +125,8 @@ impl HeaderList {
.collect()
}
pub fn apply(&mut self, new_headers: Vec<HeaderEntry>, tip: Sha256dHash) {
if tip == Sha256dHash::default() {
pub fn apply(&mut self, new_headers: Vec<HeaderEntry>, tip: BlockHash) {
if tip == BlockHash::default() {
assert!(new_headers.is_empty());
self.heights.clear();
self.headers.clear();
@ -150,7 +150,7 @@ impl HeaderList {
let expected_prev_blockhash = if height > 0 {
*self.headers[height - 1].hash()
} else {
Sha256dHash::default()
BlockHash::default()
};
assert_eq!(entry.header().prev_blockhash, expected_prev_blockhash);
// First new header's height (may override existing headers)
@ -182,7 +182,7 @@ impl HeaderList {
assert!(self.heights.contains_key(&tip));
}
pub fn header_by_blockhash(&self, blockhash: &Sha256dHash) -> Option<&HeaderEntry> {
pub fn header_by_blockhash(&self, blockhash: &BlockHash) -> Option<&HeaderEntry> {
let height = self.heights.get(blockhash)?;
let header = self.headers.get(*height)?;
if *blockhash == *header.hash() {
@ -203,7 +203,7 @@ impl HeaderList {
self.headers.last() == other.headers.last()
}
pub fn tip(&self) -> Sha256dHash {
pub fn tip(&self) -> BlockHash {
self.headers.last().map(|h| *h.hash()).unwrap_or_default()
}
@ -285,24 +285,24 @@ mod tests {
#[test]
fn test_headers() {
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::hash_types::{BlockHash, TxMerkleNode};
use bitcoin::util::hash::BitcoinHash;
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin_hashes::Hash;
use super::HeaderList;
// Test an empty header list
let null_hash = Sha256dHash::default();
let null_hash = BlockHash::default();
let mut header_list = HeaderList::empty();
assert_eq!(header_list.tip(), null_hash);
let ordered = header_list.order(vec![]);
assert_eq!(ordered.len(), 0);
header_list.apply(vec![], null_hash);
let merkle_root = Sha256dHash::hash(&[255]);
let merkle_root = TxMerkleNode::hash(&[255]);
let mut headers = vec![BlockHeader {
version: 1,
prev_blockhash: Sha256dHash::default(),
prev_blockhash: BlockHash::default(),
merkle_root,
time: 0,
bits: 0,