Skip to content

Commit 01c151e

Browse files
move chain to chain.rs
1 parent 87e7f1f commit 01c151e

File tree

4 files changed

+106
-96
lines changed

4 files changed

+106
-96
lines changed

src/lib.rs

Lines changed: 2 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#![allow(non_snake_case)]
44

55
use std::ffi::NulError;
6-
use std::marker::PhantomData;
76
use std::{fmt, panic};
87

98
use crate::core::{ScriptPubkeyExt, TransactionExt, TxOutExt};
@@ -94,96 +93,6 @@ impl fmt::Display for KernelError {
9493
}
9594
}
9695

97-
/// Iterator for traversing blocks sequentially from genesis to tip.
98-
pub struct ChainIterator<'a> {
99-
chain: Chain<'a>,
100-
current_height: usize,
101-
}
102-
103-
impl<'a> ChainIterator<'a> {
104-
fn new(chain: Chain<'a>) -> Self {
105-
Self {
106-
chain,
107-
current_height: 0,
108-
}
109-
}
110-
}
111-
112-
impl<'a> Iterator for ChainIterator<'a> {
113-
type Item = BlockTreeEntry<'a>;
114-
115-
fn next(&mut self) -> Option<Self::Item> {
116-
let height = self.current_height;
117-
self.current_height += 1;
118-
self.chain.at_height(height)
119-
}
120-
}
121-
122-
/// Represents a chain instance for querying and traversal.
123-
pub struct Chain<'a> {
124-
inner: *const btck_Chain,
125-
marker: PhantomData<&'a ChainstateManager>,
126-
}
127-
128-
impl<'a> Chain<'a> {
129-
pub unsafe fn from_ptr(ptr: *const btck_Chain) -> Self {
130-
Chain {
131-
inner: ptr,
132-
marker: PhantomData,
133-
}
134-
}
135-
136-
/// Returns the tip (highest block) of the active chain.
137-
pub fn tip(&self) -> BlockTreeEntry<'a> {
138-
let ptr = unsafe { btck_chain_get_tip(self.inner) };
139-
unsafe { BlockTreeEntry::from_ptr(ptr) }
140-
}
141-
142-
/// Returns the genesis block (height 0) of the chain.
143-
pub fn genesis(&self) -> BlockTreeEntry<'a> {
144-
let ptr = unsafe { btck_chain_get_genesis(self.inner) };
145-
unsafe { BlockTreeEntry::from_ptr(ptr) }
146-
}
147-
148-
/// Returns the block at the specified height, if it exists.
149-
pub fn at_height(&self, height: usize) -> Option<BlockTreeEntry<'a>> {
150-
let tip_height = self.height();
151-
if height > tip_height as usize {
152-
return None;
153-
}
154-
155-
let ptr = unsafe { btck_chain_get_by_height(self.inner, height as i32) };
156-
if ptr.is_null() {
157-
return None;
158-
}
159-
160-
Some(unsafe { BlockTreeEntry::from_ptr(ptr) })
161-
}
162-
163-
/// Checks if the given block entry is part of the active chain.
164-
pub fn contains(&self, entry: &BlockTreeEntry<'a>) -> bool {
165-
let result = unsafe { btck_chain_contains(self.inner, entry.as_ptr()) };
166-
c_helpers::present(result)
167-
}
168-
169-
/// Returns an iterator over all blocks from genesis to tip.
170-
pub fn iter(&self) -> ChainIterator<'a> {
171-
ChainIterator::new(*self)
172-
}
173-
174-
pub fn height(&self) -> i32 {
175-
self.tip().height()
176-
}
177-
}
178-
179-
impl<'a> Clone for Chain<'a> {
180-
fn clone(&self) -> Self {
181-
*self
182-
}
183-
}
184-
185-
impl<'a> Copy for Chain<'a> {}
186-
18796
pub use crate::core::{
18897
verify, Block, BlockHash, BlockSpentOutputs, BlockTreeEntry, ScriptPubkey, ScriptVerifyError,
18998
ScriptVerifyStatus, Transaction, TransactionSpentOutputs, TxOut,
@@ -198,7 +107,8 @@ pub use crate::notifications::{
198107
};
199108

200109
pub use crate::state::{
201-
ChainParams, ChainType, ChainstateManager, ChainstateManagerOptions, Context, ContextBuilder,
110+
Chain, ChainParams, ChainType, ChainstateManager, ChainstateManagerOptions, Context,
111+
ContextBuilder,
202112
};
203113

204114
pub use crate::core::verify_flags::{

src/state/chain.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use std::marker::PhantomData;
2+
3+
use libbitcoinkernel_sys::{
4+
btck_Chain, btck_chain_contains, btck_chain_get_by_height, btck_chain_get_genesis,
5+
btck_chain_get_tip,
6+
};
7+
8+
use crate::{ffi::c_helpers, BlockTreeEntry};
9+
10+
use super::ChainstateManager;
11+
12+
/// Iterator for traversing blocks sequentially from genesis to tip.
13+
pub struct ChainIterator<'a> {
14+
chain: Chain<'a>,
15+
current_height: usize,
16+
}
17+
18+
impl<'a> ChainIterator<'a> {
19+
fn new(chain: Chain<'a>) -> Self {
20+
Self {
21+
chain,
22+
current_height: 0,
23+
}
24+
}
25+
}
26+
27+
impl<'a> Iterator for ChainIterator<'a> {
28+
type Item = BlockTreeEntry<'a>;
29+
30+
fn next(&mut self) -> Option<Self::Item> {
31+
let height = self.current_height;
32+
self.current_height += 1;
33+
self.chain.at_height(height)
34+
}
35+
}
36+
37+
/// Represents a chain instance for querying and traversal.
38+
pub struct Chain<'a> {
39+
inner: *const btck_Chain,
40+
marker: PhantomData<&'a ChainstateManager>,
41+
}
42+
43+
impl<'a> Chain<'a> {
44+
pub unsafe fn from_ptr(ptr: *const btck_Chain) -> Self {
45+
Chain {
46+
inner: ptr,
47+
marker: PhantomData,
48+
}
49+
}
50+
51+
/// Returns the tip (highest block) of the active chain.
52+
pub fn tip(&self) -> BlockTreeEntry<'a> {
53+
let ptr = unsafe { btck_chain_get_tip(self.inner) };
54+
unsafe { BlockTreeEntry::from_ptr(ptr) }
55+
}
56+
57+
/// Returns the genesis block (height 0) of the chain.
58+
pub fn genesis(&self) -> BlockTreeEntry<'a> {
59+
let ptr = unsafe { btck_chain_get_genesis(self.inner) };
60+
unsafe { BlockTreeEntry::from_ptr(ptr) }
61+
}
62+
63+
/// Returns the block at the specified height, if it exists.
64+
pub fn at_height(&self, height: usize) -> Option<BlockTreeEntry<'a>> {
65+
let tip_height = self.height();
66+
if height > tip_height as usize {
67+
return None;
68+
}
69+
70+
let ptr = unsafe { btck_chain_get_by_height(self.inner, height as i32) };
71+
if ptr.is_null() {
72+
return None;
73+
}
74+
75+
Some(unsafe { BlockTreeEntry::from_ptr(ptr) })
76+
}
77+
78+
/// Checks if the given block entry is part of the active chain.
79+
pub fn contains(&self, entry: &BlockTreeEntry<'a>) -> bool {
80+
let result = unsafe { btck_chain_contains(self.inner, entry.as_ptr()) };
81+
c_helpers::present(result)
82+
}
83+
84+
/// Returns an iterator over all blocks from genesis to tip.
85+
pub fn iter(&self) -> ChainIterator<'a> {
86+
ChainIterator::new(*self)
87+
}
88+
89+
pub fn height(&self) -> i32 {
90+
self.tip().height()
91+
}
92+
}
93+
94+
impl<'a> Clone for Chain<'a> {
95+
fn clone(&self) -> Self {
96+
*self
97+
}
98+
}
99+
100+
impl<'a> Copy for Chain<'a> {}

src/state/chainstate.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@ use libbitcoinkernel_sys::{
1212
btck_chainstate_manager_options_set_worker_threads_num, btck_chainstate_manager_process_block,
1313
};
1414

15-
use crate::{
16-
ffi::c_helpers, Block, BlockHash, BlockSpentOutputs, BlockTreeEntry, Chain, KernelError,
17-
};
15+
use crate::{ffi::c_helpers, Block, BlockHash, BlockSpentOutputs, BlockTreeEntry, KernelError};
1816

19-
use super::Context;
17+
use super::{Chain, Context};
2018

2119
/// The chainstate manager is the central object for doing validation tasks as
2220
/// well as retrieving data from the chain. Internally it is a complex data

src/state/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
pub mod chain;
12
pub mod chainstate;
23
pub mod context;
34

5+
pub use chain::{Chain, ChainIterator};
46
pub use chainstate::{ChainstateManager, ChainstateManagerOptions};
57
pub use context::{ChainParams, ChainType, Context, ContextBuilder};

0 commit comments

Comments
 (0)