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
//! Alternative Block/Chain Ops
//!
//! Alternative chains are chains that potentially have more proof-of-work than the main-chain
//! which we are tracking to potentially re-org to.
//!
//! Cuprate uses an ID system for alt-chains. When a split is made from the main-chain we generate
//! a random [`ChainID`](cuprate_types::ChainId) and assign it to the chain:
//!
//! ```text
//!      |
//!      |
//!      |   split
//!      |-------------
//!      |            |
//!      |            |
//!     \|/          \|/
//!  main-chain    ChainID(X)
//! ```
//!
//! In that example if we were to receive an alt-block which immediately follows the top block of `ChainID(X)`
//! then that block will also be stored under `ChainID(X)`. However, if it follows from another block from `ChainID(X)`
//! we will split into a chain with a different ID:
//!
//! ```text
//!      |
//!      |
//!      |   split
//!      |-------------
//!      |            |   split
//!      |            |-------------|
//!      |            |             |
//!      |            |             |
//!      |            |             |
//!     \|/          \|/           \|/
//!  main-chain    ChainID(X)    ChainID(Z)
//! ```
//!
//! As you can see if we wanted to get all the alt-blocks in `ChainID(Z)` that now includes some blocks from `ChainID(X)` as well.
//! [`get_alt_chain_history_ranges`] covers this and is the method to get the ranges of heights needed from each [`ChainID`](cuprate_types::ChainId)
//! to get all the alt-blocks in a given [`ChainID`](cuprate_types::ChainId).
//!
//! Although this should be kept in mind as a possibility, because Cuprate's block downloader will only track a single chain it is
//! unlikely that we will be tracking [`ChainID`](cuprate_types::ChainId)s that don't immediately connect to the main-chain.
//!
//! ## Why not use the block's `previous` field?
//!
//! Although that would be easier, it makes getting a range of block extremely slow, as we have to build the weight cache to verify
//! blocks, roughly 100,000 block headers needed, this cost is too high.
mod block;
mod chain;
mod tx;

pub use block::{
    add_alt_block, flush_alt_blocks, get_alt_block, get_alt_block_extended_header_from_height,
    get_alt_block_hash,
};
pub use chain::{get_alt_chain_history_ranges, update_alt_chain_info};
pub use tx::{add_alt_transaction_blob, get_alt_transaction};