src/blockchain/impl/block_tree_impl.hpp
Namespaces
Classes
Functions
Functions Documentation
function OUTCOME_HPP_DECLARE_ERROR_2
OUTCOME_HPP_DECLARE_ERROR_2(
sgns::blockchain ,
BlockTreeImpl::Error
)
Source code
#ifndef SUPERGENIUS_SRC_BLOCK_TREE_IMPL_HPP
#define SUPERGENIUS_SRC_BLOCK_TREE_IMPL_HPP
#include "blockchain/block_tree.hpp"
#include <boost/optional.hpp>
#include <functional>
#include <memory>
#include <unordered_set>
#include "blockchain/block_header_repository.hpp"
#include "blockchain/block_storage.hpp"
#include "base/logger.hpp"
#include "crypto/hasher.hpp"
#include "network/extrinsic_observer.hpp"
namespace sgns::blockchain {
class BlockTreeImpl : public BlockTree {
struct TreeNode : public std::enable_shared_from_this<TreeNode> {
TreeNode( primitives::BlockHash hash,
primitives::BlockNumber depth,
std::shared_ptr<TreeNode> parent,
bool finalized = false );
primitives::BlockHash block_hash;
primitives::BlockNumber depth;
std::weak_ptr<TreeNode> parent;
bool finalized;
std::vector<std::shared_ptr<TreeNode>> children;
std::shared_ptr<TreeNode> getByHash( const primitives::BlockHash &hash );
bool operator==( const TreeNode &other ) const;
bool operator!=( const TreeNode &other ) const;
};
struct TreeMeta {
explicit TreeMeta(TreeNode &subtree_root_node);
TreeMeta(std::unordered_set<primitives::BlockHash> leaves,
TreeNode &deepest_leaf,
TreeNode &last_finalized);
std::unordered_set<primitives::BlockHash> leaves;
std::reference_wrapper<TreeNode> deepest_leaf;
std::reference_wrapper<TreeNode> last_finalized;
};
public:
enum class Error {
// target block number is past the given maximum number
TARGET_IS_PAST_MAX = 1,
// block resides on a dead fork
BLOCK_ON_DEAD_END,
// block exists in chain but not found when following all
// leaves backwards.
BLOCK_NOT_FOUND
};
static outcome::result<std::shared_ptr<BlockTreeImpl>> create(
std::shared_ptr<BlockHeaderRepository> header_repo,
std::shared_ptr<BlockStorage> storage,
const primitives::BlockId &last_finalized_block,
std::shared_ptr<network::ExtrinsicObserver> extrinsic_observer,
std::shared_ptr<crypto::Hasher> hasher);
~BlockTreeImpl() override = default;
[[nodiscard]] outcome::result<primitives::BlockHeader> getBlockHeader(
const primitives::BlockId &block ) const override;
[[nodiscard]] outcome::result<primitives::BlockBody> getBlockBody(
const primitives::BlockId &block ) const override;
[[nodiscard]] outcome::result<primitives::Justification> getBlockJustification(
const primitives::BlockId &block ) const override;
outcome::result<void> addBlockHeader(
const primitives::BlockHeader &header) override;
outcome::result<void> addBlock(const primitives::Block &block) override;
outcome::result<void> addBlockBody(
primitives::BlockNumber block_number,
const primitives::BlockHash &block_hash,
const primitives::BlockBody &body) override;
outcome::result<void> finalize(
const primitives::BlockHash &block,
const primitives::Justification &justification) override;
BlockHashVecRes getChainByBlock(
const primitives::BlockHash &block) override;
BlockHashVecRes getChainByBlock(const primitives::BlockHash &block,
bool ascending,
uint64_t maximum) override;
BlockHashVecRes getChainByBlocks(
const primitives::BlockHash &top_block,
const primitives::BlockHash &bottom_block) override;
bool hasDirectChain(const primitives::BlockHash &ancestor,
const primitives::BlockHash &descendant) override;
BlockHashVecRes longestPath() override;
[[nodiscard]] primitives::BlockInfo deepestLeaf() const override;
[[nodiscard]] outcome::result<primitives::BlockInfo> getBestContaining(
const primitives::BlockHash &target_hash,
const boost::optional<primitives::BlockNumber> &max_number ) const override;
[[nodiscard]] std::vector<primitives::BlockHash> getLeaves() const override;
BlockHashVecRes getChildren(const primitives::BlockHash &block) override;
[[nodiscard]] primitives::BlockInfo getLastFinalized() const override;
std::string GetName() override
{
return "BlockTreeImpl";
}
private:
BlockTreeImpl(
std::shared_ptr<BlockHeaderRepository> header_repo,
std::shared_ptr<BlockStorage> storage,
std::shared_ptr<TreeNode> tree,
std::shared_ptr<TreeMeta> meta,
std::shared_ptr<network::ExtrinsicObserver> extrinsic_observer,
std::shared_ptr<crypto::Hasher> hasher);
outcome::result<primitives::BlockHash> walkBackUntilLess(
const primitives::BlockHash &start,
const primitives::BlockNumber &limit) const;
std::vector<primitives::BlockHash> getLeavesSorted() const;
static void collectDescendants(
std::shared_ptr<TreeNode> node,
std::vector<std::pair<primitives::BlockHash, primitives::BlockNumber>>
&container);
outcome::result<void> prune( std::shared_ptr<TreeNode> lastFinalizedNode );
std::shared_ptr<BlockHeaderRepository> header_repo_;
std::shared_ptr<BlockStorage> storage_;
std::shared_ptr<TreeNode> tree_;
std::shared_ptr<TreeMeta> tree_meta_;
std::shared_ptr<network::ExtrinsicObserver> extrinsic_observer_;
std::shared_ptr<crypto::Hasher> hasher_;
base::Logger log_ = base::createLogger("BlockTreeImpl");
};
} // namespace sgns::blockchain
OUTCOME_HPP_DECLARE_ERROR_2(sgns::blockchain, BlockTreeImpl::Error);
#endif // SUPERGENIUS_SRC_BLOCK_TREE_IMPL_HPP
Updated on 2026-03-04 at 13:10:44 -0800