Struct ChainState

Source
pub struct ChainState<PersistedState: ChainStore> {
    inner: RwLock<ChainStateInner<PersistedState>>,
}
Expand description

The high-level chain backend managing the blockchain state.

ChainState is responsible for:

  • Keeping track of the chain state with the help of a ChainStore for persisted storage.
  • Correctly updating the state using consensus functions.
  • Interfacing with other components and providing data about the current view of the chain.

Fields§

§inner: RwLock<ChainStateInner<PersistedState>>

Implementations§

Source§

impl<PersistedState: ChainStore> ChainState<PersistedState>

Source

fn maybe_reindex( &self, potential_tip: &DiskBlockHeader, ) -> Result<(), BlockchainError>

Source

pub fn push_headers( &self, headers: Vec<BlockHeader>, height: u32, ) -> Result<(), BlockchainError>

Just adds headers to the chainstate, without validating them.

Source

fn update_header(&self, header: &DiskBlockHeader) -> Result<(), BlockchainError>

Source

fn update_header_and_index( &self, header: &DiskBlockHeader, hash: BlockHash, height: u32, ) -> Result<(), BlockchainError>

Source

fn validate_header( &self, block_header: &BlockHeader, ) -> Result<BlockHash, BlockchainError>

Source

fn is_genesis(&self, header: &BlockHeader) -> bool

Whether a node is the genesis block for this net

Source

fn get_ancestor( &self, header: &BlockHeader, ) -> Result<DiskBlockHeader, BlockchainError>

Returns the ancestor of a given block

Source

fn get_branch_work(&self, header: &BlockHeader) -> Result<Work, BlockchainError>

Returns the cumulative work in this branch

Source

fn check_branch(&self, branch_tip: &BlockHeader) -> Result<(), BlockchainError>

Checks if a branch is valid (i.e. all ancestors are known)

Source

fn get_chain_depth( &self, branch_tip: &BlockHeader, ) -> Result<u32, BlockchainError>

Returns the depth of a branch (i.e. how many blocks are in the branch)

Source

fn mark_chain_as_active( &self, new_tip: &BlockHeader, fork_point: BlockHash, ) -> Result<(), BlockchainError>

Mark the current index as active, because we are in the middle of a reorg

Source

fn mark_chain_as_inactive( &self, old_tip: &BlockHeader, fork_point: BlockHash, ) -> Result<(), BlockchainError>

Mark the current index as inactive, either because we found an invalid ancestor, or we are in the middle of reorg

Source

fn find_fork_point( &self, header: &BlockHeader, ) -> Result<BlockHeader, BlockchainError>

Finds where in the current index, a given branch forks out.

Source

fn reorg_acc(&self, fork_point: &BlockHeader) -> Result<(), BlockchainError>

Changes the acc we are using to validate blocks.

Source

fn reorg(&self, new_tip: BlockHeader) -> Result<(), BlockchainError>

Source

fn change_active_chain( &self, new_tip: &BlockHeader, last_valid: BlockHash, depth: u32, )

Changes the active chain to the new branch during a reorg

Source

fn get_last_valid_block( &self, header: &BlockHeader, ) -> Result<BlockHash, BlockchainError>

Grabs the last block we validated in this branch. We don’t validate a fork, unless it becomes the best chain. This function technically finds out what is the last common block between two branches.

Source

fn maybe_reorg(&self, branch_tip: BlockHeader) -> Result<(), BlockchainError>

If we get a header that doesn’t build on top of our best chain, it may cause a reorganization. We check this here.

Source

fn push_alt_tip(&self, branch_tip: &BlockHeader) -> Result<(), BlockchainError>

Stores a new tip for a branch that is not the best one

Source

fn chain_params(&self) -> ChainParams

Returns the chain_params struct for the current network

Source

fn get_header_by_height( &self, height: u32, ) -> Result<DiskBlockHeader, BlockchainError>

Source

fn notify( &self, block: &Block, height: u32, inputs: Option<&HashMap<OutPoint, UtxoData>>, )

Source

fn new( chainstore: PersistedState, network: Network, assume_valid: AssumeValidArg, ) -> ChainState<PersistedState>

Source

fn get_disk_block_header( &self, hash: &BlockHash, ) -> Result<DiskBlockHeader, BlockchainError>

Fetches a DiskBlockHeader from the chain store given its block hash. Returns an error if it’s not present or if the database operation failed.

Source

fn get_roots_for_block( &self, height: u32, ) -> Result<Option<Stump>, BlockchainError>

Returns the parsed accumulator for a given block height, if they are present.

Source

fn reindex_chain(&self) -> Result<(), BlockchainError>

Re-indexes the chain if we find ourselves in an undefined state

Here, we have to find what’s the best chain we have, then figure out how many blocks we have validated. We then need to take extra care to align our accumulator with the validation index. If the validation_index diverges from the inner acc by even one block, all proofs will be invalid.

We start at the alleged validation index, and then we look for the last accumulator we have. If we don’t have the accumulator for the validation index, we roll back our chain to the last accumulator we have, and then re-validate them

Source

fn find_best_chain(&self) -> BestChain

Reconstructs the BestChain data based on the database indexes and headers. This is useful to recover from an invalid state or data corruption

Source

fn load_chain_state( chainstore: PersistedState, network: Network, assume_valid: AssumeValidArg, ) -> Result<ChainState<PersistedState>, BlockchainError>

Source

pub fn open( chainstore: PersistedState, network: Network, assume_valid: AssumeValidArg, ) -> Result<Self, BlockchainError>

Opens an existing chain state or creates one from genesis if the store is uninitialized.

This is the main entry point for instantiating a ChainState. If the store already has data, the state is loaded from it. Otherwise, the chain is initialized from the genesis block for the given network.

§Errors

Returns an error if the store cannot be read or if the persisted state is corrupted.

Source

fn check_db_integrity(&self) -> Result<(), BlockchainError>

Checks whether our database got a file-level corruption, and if so, reindex.

This protects us from fs corruption, like random bit-flips or power loss.

Source

fn check_chain_integrity(&self) -> Result<(), BlockchainError>

Source

fn deserialize_accumulator( acc: Option<Vec<u8>>, ) -> Result<Stump, BlockchainError>

Tries to deserialize an accumulator returning an empty [Stump] acc is None

Source

fn update_view( &self, height: u32, block: &BlockHeader, acc: Stump, ) -> Result<(), BlockchainError>

Source

fn update_tip(&self, best_block: BlockHash, height: u32)

Source

fn verify_script(&self, height: u32) -> Result<bool, PersistedState::Error>

Source

pub fn acc(&self) -> Stump

Source

fn get_next_required_work( &self, last_block: &BlockHeader, next_height: u32, next_header: &BlockHeader, ) -> Result<Target, BlockchainError>

Returns the next required work for the next block, usually it’s just the last block’s target but if we are in a retarget period, it’s calculated from the last 2016 blocks.

Source

fn check_bip94_block( &self, block: &BlockHeader, height: u32, ) -> Result<(), BlockchainError>

Check timestamp against prev for difficulty-adjustment blocks to prevent timewarp attacks. Must only be called for non-genesis block headers.

Source

pub fn validate_block_no_acc( &self, block: &Block, height: u32, inputs: HashMap<OutPoint, UtxoData>, ) -> Result<(), BlockchainError>

Validates the block without checking whether the inputs are present in the UTXO set. This function contains the core validation logic.

The methods BlockchainInterface::validate_block and UpdatableChainstate::connect_block call this and additionally verify the inclusion proof (i.e., they perform full validation).

Trait Implementations§

Source§

impl<PersistedState: ChainStore> BlockchainInterface for ChainState<PersistedState>

Source§

type Error = BlockchainError

Source§

fn get_params(&self) -> Params

Returns this chain’s params
Source§

fn acc(&self) -> Stump

Returns our current acc
Source§

fn get_fork_point(&self, block: BlockHash) -> Result<BlockHash, Self::Error>

Find the last common ancestor between the current best chain and block
Source§

fn update_acc( &self, acc: Stump, block: &Block, height: u32, proof: Proof, del_hashes: Vec<Hash>, ) -> Result<Stump, Self::Error>

Applies a changeset to an accumulator and returns the resulting one
Source§

fn get_chain_tips(&self) -> Result<Vec<BlockHash>, Self::Error>

Returns all known chain tips, including the best one and forks
Source§

fn validate_block( &self, block: &Block, proof: Proof, inputs: HashMap<OutPoint, UtxoData>, del_hashes: Vec<Hash>, acc: Stump, ) -> Result<(), Self::Error>

Validates a block according to Bitcoin’s rules, without modifying our chain
Source§

fn get_block_locator_for_tip( &self, tip: BlockHash, ) -> Result<Vec<BlockHash>, BlockchainError>

Returns a block locator from a given tip Read more
Source§

fn is_in_ibd(&self) -> bool

Tells whether or not we are on IBD
Source§

fn get_block_height(&self, hash: &BlockHash) -> Result<Option<u32>, Self::Error>

Returns the height of a block, given it’s hash
Source§

fn get_block_hash(&self, height: u32) -> Result<BlockHash, Self::Error>

Returns the block with a given height in our current tip.
Source§

fn get_tx(&self, _txid: &Txid) -> Result<Option<Transaction>, Self::Error>

Returns a bitcoin [bitcoin::Transaction] given its txid.
Source§

fn get_height(&self) -> Result<u32, Self::Error>

Get the height of our best know chain.
Source§

fn estimate_fee(&self, target: usize) -> Result<f64, Self::Error>

Returns fee estimation for inclusion in target blocks.
Source§

fn get_block(&self, _hash: &BlockHash) -> Result<Block, Self::Error>

Returns a block with a given hash if any.
Source§

fn get_best_block(&self) -> Result<(u32, BlockHash), Self::Error>

Returns the best known block
Source§

fn get_block_header(&self, hash: &BlockHash) -> Result<BlockHeader, Self::Error>

Returns associated header for block with hash
Source§

fn subscribe(&self, tx: Arc<dyn BlockConsumer>)

Register for receiving notifications for some event. Right now it only works for new blocks, but may work with transactions in the future too. if a module performs some heavy-lifting on the block’s data, it should pass in a vector or a channel where data can be transferred to the actual worker, otherwise chainstate will be stuck for as long as you have work to do.
Source§

fn get_block_locator(&self) -> Result<Vec<BlockHash>, BlockchainError>

Returns a block locator
Source§

fn get_validation_index(&self) -> Result<u32, Self::Error>

Returns the last block we validated
Source§

fn is_coinbase_mature( &self, height: u32, block: BlockHash, ) -> Result<bool, Self::Error>

Checks if a coinbase is mature
Source§

impl<T: ChainStore> TryFrom<ChainStateBuilder<T>> for ChainState<T>

Source§

type Error = BlockchainBuilderError

The type returned in the event of a conversion error.
Source§

fn try_from(builder: ChainStateBuilder<T>) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl<PersistedState: ChainStore> UpdatableChainstate for ChainState<PersistedState>

Source§

fn switch_chain(&self, new_tip: BlockHash) -> Result<(), BlockchainError>

Source§

fn get_acc(&self) -> Stump

Returns the current accumulator
Source§

fn mark_block_as_valid(&self, block: BlockHash) -> Result<(), BlockchainError>

Marks one block as being fully validated, this overrides a block that was explicitly marked as invalid.
Source§

fn mark_chain_as_assumed( &self, acc: Stump, assumed_hash: BlockHash, ) -> Result<bool, BlockchainError>

Marks a chain as fully-valid Read more
Source§

fn invalidate_block(&self, block: BlockHash) -> Result<(), BlockchainError>

Tells this blockchain to consider this block invalid, and not build on top of it
Source§

fn toggle_ibd(&self, is_ibd: bool)

Toggle IBD on/off
Source§

fn connect_block( &self, block: &Block, proof: Proof, inputs: HashMap<OutPoint, UtxoData>, del_hashes: Vec<Hash>, ) -> Result<u32, BlockchainError>

This is one of the most important methods for a ChainState, it gets a block and some utreexo data, validates this block and connects to our chain of blocks. This function is meant to be atomic and prone of running in parallel.
Source§

fn handle_transaction(&self) -> Result<(), BlockchainError>

Not used for now, but in a future blockchain with mempool, we can process transactions that are not in a block yet.
Source§

fn flush(&self) -> Result<(), BlockchainError>

Persists our data. Should be invoked periodically.
Source§

fn accept_header(&self, header: BlockHeader) -> Result<(), BlockchainError>

Accepts a new header to our chain. This method is called before connect_block, and makes some basic checks on a header and saves it on disk. We only accept a block as valid after calling connect_block. Read more
Source§

fn get_root_hashes(&self) -> Vec<BitcoinNodeHash>

Returns the root hashes of our utreexo forest
Source§

fn get_partial_chain( &self, initial_height: u32, final_height: u32, acc: Stump, ) -> Result<PartialChainState, BlockchainError>

Returns a partial chainstate from a range of blocks. Read more

Auto Trait Implementations§

§

impl<PersistedState> !Freeze for ChainState<PersistedState>

§

impl<PersistedState> !RefUnwindSafe for ChainState<PersistedState>

§

impl<PersistedState> Send for ChainState<PersistedState>
where PersistedState: Send,

§

impl<PersistedState> Sync for ChainState<PersistedState>
where PersistedState: Send + Sync,

§

impl<PersistedState> Unpin for ChainState<PersistedState>
where PersistedState: Unpin,

§

impl<PersistedState> !UnwindSafe for ChainState<PersistedState>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
Source§

impl<T> ChainBackend for T

Source§

impl<T> ThreadSafeChain for T
where T: ChainBackend + Sync + Send + 'static,