1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
pub mod assert;
pub mod block;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use nakamoto_common::bitcoin;
use nakamoto_common::bitcoin::blockdata::constants;
use nakamoto_common::bitcoin::consensus::encode::Decodable;
use lazy_static::*;
use nakamoto_common::block::BlockHeader;
use nakamoto_common::nonempty::NonEmpty;
pub use fastrand;
lazy_static! {
pub static ref BITCOIN_HEADERS: NonEmpty<BlockHeader> = {
let genesis = constants::genesis_block(bitcoin::Network::Bitcoin).header;
let mut f = File::open(&*self::headers::PATH).unwrap();
let mut buf = [0; 80];
let mut headers = NonEmpty::new(genesis);
while f.read_exact(&mut buf).is_ok() {
let header = BlockHeader::consensus_decode(&mut buf.as_slice()).unwrap();
headers.push(header);
}
headers
};
}
pub mod headers {
use super::*;
lazy_static! {
pub static ref PATH: PathBuf =
Path::new(env!("CARGO_MANIFEST_DIR")).join("data/headers.bin");
}
}
pub mod logger {
use log::*;
struct Logger {
level: Level,
}
impl Log for Logger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &Record) {
use colored::Colorize;
match record.target() {
"test" => {
println!(
"{} {}",
"test:".yellow(),
record.args().to_string().yellow()
)
}
"sim" => {
println!("{} {}", "sim:".bold(), record.args().to_string().bold())
}
target => {
if self.enabled(record.metadata()) {
let s = format!("{:<5} {}", format!("{}:", target), record.args());
println!("{}", s.dimmed());
}
}
}
}
fn flush(&self) {}
}
pub fn init(level: Level) {
let logger = Logger { level };
log::set_boxed_logger(Box::new(logger)).ok();
log::set_max_level(level.to_level_filter());
}
}
pub mod arbitrary {
#[derive(Debug, Clone)]
pub struct InRange<const N: u64, const M: u64>(pub u64);
impl<const N: u64, const M: u64> quickcheck::Arbitrary for InRange<N, M> {
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
let rng = fastrand::Rng::with_seed(u64::arbitrary(g));
Self(rng.u64(N..=M))
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let InRange(n) = self;
if *n > N {
Box::new((N..*n).map(InRange))
} else {
Box::new(std::iter::empty())
}
}
}
}