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
#![allow(clippy::len_without_is_empty)]
use crate::block::Height;
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::consensus::encode;
use bitcoin::hash_types::FilterHash;
use bitcoin::util::bip158::BlockFilter;
use thiserror::Error;
use crate::network::Network;
use crate::source;
#[derive(Debug, Error)]
pub enum Error {
#[error("i/o error: {0}")]
Io(#[from] std::io::Error),
#[error("error decoding header: {0}")]
Decoding(#[from] encode::Error),
#[error("error: the store data is corrupt")]
Corruption,
#[error("the operation was interrupted")]
Interrupted,
}
pub trait Genesis {
fn genesis(network: Network) -> Self;
}
impl Genesis for BlockHeader {
fn genesis(network: Network) -> Self {
network.genesis()
}
}
impl Genesis for FilterHash {
fn genesis(network: Network) -> Self {
use bitcoin::hashes::Hash;
let genesis = network.genesis_block();
let filter = BlockFilter::new_script_filter(&genesis, |_| {
panic!("{}: genesis block should have no inputs", source!())
})
.unwrap();
FilterHash::hash(&filter.content)
}
}
impl Genesis for BlockFilter {
fn genesis(network: Network) -> Self {
let genesis = network.genesis_block();
BlockFilter::new_script_filter(&genesis, |_| {
panic!("{}: genesis block should have no inputs", source!())
})
.unwrap()
}
}
pub trait Store {
type Header: Sized;
fn genesis(&self) -> Self::Header;
fn put<I: Iterator<Item = Self::Header>>(&mut self, headers: I) -> Result<Height, Error>;
fn get(&self, height: Height) -> Result<Self::Header, Error>;
fn rollback(&mut self, height: Height) -> Result<(), Error>;
fn sync(&mut self) -> Result<(), Error>;
fn iter(&self) -> Box<dyn Iterator<Item = Result<(Height, Self::Header), Error>>>;
fn len(&self) -> Result<usize, Error>;
fn height(&self) -> Result<Height, Error>;
fn check(&self) -> Result<(), Error>;
fn heal(&self) -> Result<(), Error>;
}