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
use alloc::vec::Vec;
use crate::PartialBlockchainError;
use crate::block::{BlockHeader, BlockNumber, Blockchain};
use crate::transaction::PartialBlockchain;
impl PartialBlockchain {
/// Converts the [`Blockchain`] into a [`PartialBlockchain`] by selectively copying all leaves
/// that are in the given `blocks` iterator.
///
/// This tracks all blocks in the given iterator in the [`PartialBlockchain`] except for the
/// block whose block number equals [`Blockchain::chain_tip`], which is the current chain
/// tip.
///
/// # Panics
///
/// Due to being only available in test scenarios, this function panics when one of the given
/// blocks does not exist in the provided chain or if the chain does not contain at least the
/// genesis block.
pub fn from_blockchain(
chain: &Blockchain,
blocks: impl IntoIterator<Item = BlockHeader>,
) -> Result<PartialBlockchain, PartialBlockchainError> {
// We take the state at the latest block which will be used as the reference block by
// transaction or batch kernels. That way, the returned partial mmr's hash peaks will match
// the chain commitment of the reference block.
let latest_block = chain
.chain_tip()
.expect("block chain should contain at least the genesis block");
Self::from_blockchain_at(chain, latest_block, blocks)
}
/// Converts the [`Blockchain`] into a [`PartialBlockchain`] by selectively copying all leaves
/// that are in the given `blocks` iterator.
///
/// This tracks all blocks in the given iterator in the [`PartialBlockchain`] except for the
/// block whose block number equals `ref_block`.
///
/// # Panics
///
/// Due to being only available in test scenarios, this function panics when one of the given
/// blocks does not exist in the provided chain or if the chain does not contain at least the
/// genesis block.
pub fn from_blockchain_at(
chain: &Blockchain,
ref_block: BlockNumber,
blocks: impl IntoIterator<Item = BlockHeader>,
) -> Result<PartialBlockchain, PartialBlockchainError> {
let block_headers: Vec<_> = blocks.into_iter().collect();
let partial_mmr = chain
.partial_mmr_from_blocks(
&block_headers.iter().map(BlockHeader::block_num).collect(),
ref_block,
)
.expect("reference block should be in the chain and set of blocks should be valid");
PartialBlockchain::new(partial_mmr, block_headers)
}
}