veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
altintegration::BaseBlockTree< Block > Struct Template Referenceabstract

Base block tree that stores all blocks, maintains tree tips, maintains active chain. More...

Detailed Description

template<typename Block>
struct altintegration::BaseBlockTree< Block >
Template Parameters
Block

Definition at line 35 of file base_block_tree.hpp.

#include <base_block_tree.hpp>

+ Inheritance diagram for altintegration::BaseBlockTree< Block >:
+ Collaboration diagram for altintegration::BaseBlockTree< Block >:

Public Types

using block_t = Block
 
using block_height_t = typename block_t::height_t
 
using hash_t = typename Block::hash_t
 
using prev_block_hash_t = typename Block::prev_hash_t
 
using index_t = BlockIndex< Block >
 
using stored_index_t = StoredBlockIndex< Block >
 
using on_invalidate_t = void(const index_t &)
 
using block_index_t = std::unordered_map< prev_block_hash_t, std::unique_ptr< index_t > >
 

Public Member Functions

const std::unordered_set< index_t * > & getTips () const
 
std::vector< index_t * > getBlocks () const
 
std::vector< index_t * > getAllBlocks () const
 
const BlockReadergetBlockProvider () const
 
 BaseBlockTree (const BlockReader &blockProvider)
 
 BaseBlockTree (const BaseBlockTree &)=delete
 
BaseBlockTreeoperator= (const BaseBlockTree &)=delete
 
 BaseBlockTree (BaseBlockTree &&)=default
 
BaseBlockTreeoperator= (BaseBlockTree &&)=default
 
const Chain< index_t > & getBestChain () const
 Getter for currently Active Chain. More...
 
template<typename T >
prev_block_hash_t makePrevHash (const T &h) const
 
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
index_tgetBlockIndex (const T &hash)
 Get BlockIndex by block hash. More...
 
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
const index_tgetBlockIndex (const T &hash) const
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More...
 
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
index_tfindBlockIndex (const T &hash)
 Get BlockIndex by block hash. More...
 
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
const index_tfindBlockIndex (const T &hash) const
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More...
 
virtual bool loadTip (const hash_t &hash, ValidationState &state)
 
virtual bool loadBlockForward (const stored_index_t &index, bool fast_load, ValidationState &state)
 Efficiently connects BlockIndex to this tree as a leaf, when it is loaded from disk. More...
 
void removeSubtree (index_t &toRemove)
 Removes block and all its successors. More...
 
void removeSubtree (const hash_t &toRemove)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More...
 
void removeLeaf (index_t &toRemove)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More...
 
void invalidateSubtree (index_t &toBeInvalidated, enum BlockValidityStatus reason, bool shouldDetermineBestChain=true)
 Mark given block as invalid. More...
 
void invalidateSubtree (const hash_t &toBeInvalidated, enum BlockValidityStatus reason, bool shouldDetermineBestChain=true)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More...
 
void revalidateSubtree (const hash_t &hash, enum BlockValidityStatus reason, bool shouldDetermineBestChain=true)
 
void revalidateSubtree (index_t &toBeValidated, enum BlockValidityStatus reason, bool shouldDetermineBestChain=true)
 
bool isBootstrapped () const
 Check if the blockchain is bootstrapped. More...
 
virtual bool setState (const hash_t &block, ValidationState &state)
 
virtual bool setState (index_t &index, ValidationState &)
 
virtual void overrideTip (index_t &to)
 
index_tgetRoot () const
 
const FinalizedPayloadsIndex< index_t > & getFinalizedPayloadsIndex () const
 
const PayloadsIndex< index_t > & getPayloadsIndex () const
 
DeferForkResolutionGuard deferForkResolutionGuard ()
 
BaseBlockTree< VbkBlock >::prev_block_hash_t makePrevHash (const hash_t &h) const
 HACK: getBlockIndex accepts either hash_t or prev_block_hash_t then, depending on what it received, it should do trim LE on full hash to receive short hash, which is stored inside a map. More...
 

Public Attributes

signals::Signal< void(const index_t &)> onBlockBeforeDeallocated
 before we deallocate any block index we emit it to this signal More...
 
signals::Signal< on_invalidate_t > onBlockValidityChanged
 signals to the end user that block have been invalidated More...
 
signals::Signal< void(const index_t &index)> onBeforeOverrideTip
 chain reorg signal - the tip is being changed More...
 

Protected Member Functions

void deallocateBlock (index_t &block)
 Permanently erases block from a block tree. More...
 
std::string toPrettyString (size_t level=0) const
 
void decreaseAppliedBlockCount (size_t erasedBlocks)
 
void decreaseAppliedBlockCount (size_t)
 

Protected Attributes

bool isLoadingBlocks_ = false
 if true, we're in "loading blocks" state More...
 
bool isLoaded_ = false
 if true, we can no longer execute loadBlock/loadTip on this tree. More...
 
block_index_t blocks_
 stores ALL blocks, including valid and invalid More...
 
std::unordered_set< index_t * > tips_
 stores ONLY VALID tips, including currently active tip More...
 
Chain< index_tactiveChain_
 currently applied chain More...
 
FinalizedPayloadsIndex< index_tfinalizedPayloadsIndex_
 stores mapping of payload id -> its containing ALT/VBK block which are already finalized. More...
 
PayloadsIndex< index_tpayloadsIndex_
 stores mapping of payload id -> its containing ALT/VBK blocks which are not yet finalized. More...
 
const BlockReaderblockProvider_
 

Member Typedef Documentation

◆ block_height_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::block_height_t = typename block_t::height_t

Definition at line 37 of file base_block_tree.hpp.

◆ block_index_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::block_index_t = std::unordered_map<prev_block_hash_t, std::unique_ptr<index_t> >

Definition at line 43 of file base_block_tree.hpp.

◆ block_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::block_t = Block

Definition at line 36 of file base_block_tree.hpp.

◆ hash_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::hash_t = typename Block::hash_t

Definition at line 38 of file base_block_tree.hpp.

◆ index_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::index_t = BlockIndex<Block>

Definition at line 40 of file base_block_tree.hpp.

◆ on_invalidate_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::on_invalidate_t = void(const index_t&)

Definition at line 42 of file base_block_tree.hpp.

◆ prev_block_hash_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::prev_block_hash_t = typename Block::prev_hash_t

Definition at line 39 of file base_block_tree.hpp.

◆ stored_index_t

template<typename Block >
using altintegration::BaseBlockTree< Block >::stored_index_t = StoredBlockIndex<Block>

Definition at line 41 of file base_block_tree.hpp.

Constructor & Destructor Documentation

◆ ~BaseBlockTree()

template<typename Block >
virtual altintegration::BaseBlockTree< Block >::~BaseBlockTree ( )
inlinevirtual

Definition at line 69 of file base_block_tree.hpp.

69 {
70 if (!isBootstrapped()) {
71 return;
72 }
73
74 deallocateTree(getRoot());
75 }
bool isBootstrapped() const
Check if the blockchain is bootstrapped.

◆ BaseBlockTree()

template<typename Block >
altintegration::BaseBlockTree< Block >::BaseBlockTree ( const BlockReader blockProvider)
inline

Definition at line 77 of file base_block_tree.hpp.

78 : blockProvider_(blockProvider) {}

Member Function Documentation

◆ deallocateBlock()

template<typename Block >
void altintegration::BaseBlockTree< Block >::deallocateBlock ( index_t block)
inlineprotected
Invariant
should be the only function that deallocates blocks.
erased block must be a tip.
erased block must be "deleted".
erased block must exist in block tree.

Definition at line 497 of file base_block_tree.hpp.

497 {
498 VBK_TRACE_ZONE_SCOPED;
499 VBK_ASSERT_MSG(block.isDeleted(),
500 "cannot erase a block that is not deleted %s",
501 block.toPrettyString());
502 VBK_ASSERT_MSG(
503 block.isTip(),
504 "cannot erase a block that has ancestors as that would split "
505 "the tree: %s",
506 block.toPrettyString());
507
508 onBlockBeforeDeallocated.emit(block);
509 auto shortHash = makePrevHash(block.getHash());
510 auto count = blocks_.erase(shortHash);
511 VBK_ASSERT_MSG(count == 1,
512 "state corruption: block %s is not in the store",
513 block.toPrettyString());
514 }
signals::Signal< void(const index_t &)> onBlockBeforeDeallocated
before we deallocate any block index we emit it to this signal
block_index_t blocks_
stores ALL blocks, including valid and invalid

◆ decreaseAppliedBlockCount() [1/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::decreaseAppliedBlockCount ( size_t  erasedBlocks)
inlineprotected

Definition at line 857 of file base_block_tree.hpp.

857 {
858 VBK_ASSERT_MSG(appliedBlockCount >= erasedBlocks,
859 "Tree: %s, Applied: %d, erased: %d",
860 block_t::name(),
861 appliedBlockCount,
862 erasedBlocks);
863 appliedBlockCount -= erasedBlocks;
864 }

◆ decreaseAppliedBlockCount() [2/2]

void altintegration::BaseBlockTree< BtcBlock >::decreaseAppliedBlockCount ( size_t  )
inlineprotected

Definition at line 25 of file vbk_block_tree.hpp.

25 {
26 // do nothing
27 // BTC tree is not protected
28}

◆ deferForkResolutionGuard()

template<typename Block >
DeferForkResolutionGuard altintegration::BaseBlockTree< Block >::deferForkResolutionGuard ( )
inline

Definition at line 816 of file base_block_tree.hpp.

816 {
817 return DeferForkResolutionGuard(*this);
818 }

◆ findBlockIndex() [1/2]

template<typename Block >
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
index_t * altintegration::BaseBlockTree< Block >::findBlockIndex ( const T &  hash)
inline
Template Parameters
Tblock type
Parameters
[in]hashblock hash
Returns
nullptr if block is not found, or ptr to block otherwise.

Definition at line 139 of file base_block_tree.hpp.

139 {
140 const auto& t = as_const(*this);
141 return const_cast<index_t*>(t.findBlockIndex(hash));
142 }

◆ findBlockIndex() [2/2]

template<typename Block >
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
const index_t * altintegration::BaseBlockTree< Block >::findBlockIndex ( const T &  hash) const
inline

Definition at line 149 of file base_block_tree.hpp.

149 {
150 VBK_TRACE_ZONE_SCOPED;
151 auto shortHash = makePrevHash(hash);
152 auto it = blocks_.find(shortHash);
153 return it == blocks_.end() ? nullptr : it->second.get();
154 }

◆ getAllBlocks()

template<typename Block >
std::vector< index_t * > altintegration::BaseBlockTree< Block >::getAllBlocks ( ) const
inline

Definition at line 58 of file base_block_tree.hpp.

58 {
59 std::vector<index_t*> blocks;
60 blocks.reserve(blocks_.size());
61 for (const auto& el : blocks_) {
62 blocks.push_back(el.second.get());
63 }
64 return blocks;
65 }

◆ getBestChain()

template<typename Block >
const Chain< index_t > & altintegration::BaseBlockTree< Block >::getBestChain ( ) const
inline
Returns
reference for current chain.

Definition at line 94 of file base_block_tree.hpp.

94{ return this->activeChain_; }
Chain< index_t > activeChain_
currently applied chain

◆ getBlockIndex() [1/2]

template<typename Block >
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
index_t * altintegration::BaseBlockTree< Block >::getBlockIndex ( const T &  hash)
inline
Template Parameters
Tblock type
Parameters
[in]hashblock hash
Returns
nullptr if block is not found, or ptr to block otherwise.

Definition at line 113 of file base_block_tree.hpp.

113 {
114 const auto& t = as_const(*this);
115 return const_cast<index_t*>(t.getBlockIndex(hash));
116 }

◆ getBlockIndex() [2/2]

template<typename Block >
template<typename T , typename = typename std::enable_if< std::is_same<T, hash_t>::value || std::is_same<T, prev_block_hash_t>::value>::type>
const index_t * altintegration::BaseBlockTree< Block >::getBlockIndex ( const T &  hash) const
inline

Definition at line 123 of file base_block_tree.hpp.

123 {
124 auto blockIndex = findBlockIndex(hash);
125 return blockIndex != nullptr && blockIndex->isDeleted() ? nullptr
126 : blockIndex;
127 }
index_t * findBlockIndex(const T &hash)
Get BlockIndex by block hash.

◆ getBlockProvider()

template<typename Block >
const BlockReader & altintegration::BaseBlockTree< Block >::getBlockProvider ( ) const
inline

Definition at line 67 of file base_block_tree.hpp.

67{ return blockProvider_; }

◆ getBlocks()

template<typename Block >
std::vector< index_t * > altintegration::BaseBlockTree< Block >::getBlocks ( ) const
inline

Definition at line 47 of file base_block_tree.hpp.

47 {
48 std::vector<index_t*> blocks;
49 blocks.reserve(blocks_.size());
50 for (const auto& el : blocks_) {
51 if (!el.second->isDeleted()) {
52 blocks.push_back(el.second.get());
53 }
54 }
55 return blocks;
56 }

◆ getFinalizedPayloadsIndex()

template<typename Block >
const FinalizedPayloadsIndex< index_t > & altintegration::BaseBlockTree< Block >::getFinalizedPayloadsIndex ( ) const
inline

Definition at line 779 of file base_block_tree.hpp.

779 {
781 }
FinalizedPayloadsIndex< index_t > finalizedPayloadsIndex_
stores mapping of payload id -> its containing ALT/VBK block which are already finalized.

◆ getPayloadsIndex()

template<typename Block >
const PayloadsIndex< index_t > & altintegration::BaseBlockTree< Block >::getPayloadsIndex ( ) const
inline

Definition at line 783 of file base_block_tree.hpp.

783 {
784 return payloadsIndex_;
785 }
PayloadsIndex< index_t > payloadsIndex_
stores mapping of payload id -> its containing ALT/VBK blocks which are not yet finalized.

◆ getRoot()

template<typename Block >
index_t & altintegration::BaseBlockTree< Block >::getRoot ( ) const
inline

Definition at line 422 of file base_block_tree.hpp.

422 {
423 VBK_ASSERT_MSG(isBootstrapped(), "must be bootstrapped");
424 auto* root = getBestChain().first();
425 VBK_ASSERT_MSG(root, "must be bootstrapped");
426 return *root;
427 }
const Chain< index_t > & getBestChain() const
Getter for currently Active Chain.

◆ getTips()

template<typename Block >
const std::unordered_set< index_t * > & altintegration::BaseBlockTree< Block >::getTips ( ) const
inline

Definition at line 46 of file base_block_tree.hpp.

46{ return tips_; }
std::unordered_set< index_t * > tips_
stores ONLY VALID tips, including currently active tip

◆ invalidateSubtree() [1/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::invalidateSubtree ( const hash_t &  toBeInvalidated,
enum BlockValidityStatus  reason,
bool  shouldDetermineBestChain = true 
)
inline
Invariant
block must exist in a tree

Definition at line 320 of file base_block_tree.hpp.

322 {
323 auto* index = getBlockIndex(toBeInvalidated);
324 VBK_ASSERT(index && "cannot find the subtree to invalidate");
325 return invalidateSubtree(*index, reason, shouldDetermineBestChain);
326 }
void invalidateSubtree(index_t &toBeInvalidated, enum BlockValidityStatus reason, bool shouldDetermineBestChain=true)
Mark given block as invalid.
index_t * getBlockIndex(const T &hash)
Get BlockIndex by block hash.

◆ invalidateSubtree() [2/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::invalidateSubtree ( index_t toBeInvalidated,
enum BlockValidityStatus  reason,
bool  shouldDetermineBestChain = true 
)
inline

Also marks all successors as FAILED_CHILD.

Parameters
[in]toBeInvalidatedblock to be invalidated
[in]reasoninvalidation reason. BLOCK_FAILED_BLOCK is used to indicate that block is invalid because of consensus rules (altchain decided to invalidate it). BLOCK_FAILED_POP is used to indicate that block is invalid because it contains invalid POP data.
[in]shouldDetermineBestChainwhen true, will trigger fork resolution with all tips. If it is known that block is on a fork (not on active chain), it is safe to omit fork resolution here. Otherwise, leaves tree in undefined state.

Definition at line 265 of file base_block_tree.hpp.

267 {
268 VBK_TRACE_ZONE_SCOPED;
269 VBK_LOG_DEBUG("Invalidating %s subtree: reason=%d block=%s",
270 block_t::name(),
271 (int)reason,
272 toBeInvalidated.toShortPrettyString());
273
274 VBK_ASSERT_MSG(!toBeInvalidated.isRoot(),
275 "cannot invalidate the root block");
276
277 VBK_ASSERT(isValidInvalidationReason(reason) &&
278 "invalid invalidation reason");
279
280 if (toBeInvalidated.hasFlags(reason)) {
281 return;
282 }
283
284 // all descendants of an invalid block are already flagged as
285 // BLOCK_FAILED_CHILD
286 if (!toBeInvalidated.isValid()) {
287 doInvalidate(toBeInvalidated, reason);
288 return;
289 }
290
291 bool isOnMainChain = activeChain_.contains(&toBeInvalidated);
292 if (isOnMainChain) {
293 ValidationState dummy;
294 bool success = this->setState(*toBeInvalidated.pprev, dummy);
295 VBK_ASSERT(success);
296 }
297
298 doInvalidate(toBeInvalidated, reason);
299
300 // flag the child subtrees (excluding current block) as BLOCK_FAILED_CHILD
301 for (auto* ptr : toBeInvalidated.pnext) {
302 auto* pnext = ptr;
303 forEachNodePreorder<block_t>(*pnext, [&](index_t& index) {
304 bool failed = index.isFailed();
305 doInvalidate(index, BLOCK_FAILED_CHILD);
306 return !failed;
307 });
308 }
309
310 // after invalidation, the previous block might have become a tip
311 tryAddTip(toBeInvalidated.pprev);
312
313 if (shouldDetermineBestChain) {
314 updateTips();
315 }
316 }
@ BLOCK_FAILED_CHILD
block is state{lessly,fully} valid and the altchain did not report it as invalid, but some of the anc...
constexpr bool isValidInvalidationReason(const BlockValidityStatus &reason)
Check if the reason value can be used as the reason for invalidateSubtree and revalidateSubtree.

◆ isBootstrapped()

template<typename Block >
bool altintegration::BaseBlockTree< Block >::isBootstrapped ( ) const
inline
Returns
true if the blockchain is bootstrapped, false otherwise

Definition at line 386 of file base_block_tree.hpp.

386 {
387 if (!blocks_.empty() && activeChain_.tip() != nullptr) {
388 return true;
389 }
390
391 if (blocks_.empty() && activeChain_.tip() == nullptr) {
392 return false;
393 }
394
395 VBK_ASSERT_MSG(
396 false,
397 "state corruption: the blockchain is neither bootstrapped nor empty");
398 return false;
399 }

◆ loadBlockForward()

template<typename Block >
virtual bool altintegration::BaseBlockTree< Block >::loadBlockForward ( const stored_index_t index,
bool  fast_load,
ValidationState state 
)
inlinevirtual
Parameters
[in]indexblock to be connected
[in]fast_loadflag
[out]statevalidation state
Returns
true if block is valid and successfully loaded, false otherwise.
Invariant
NOT atomic. If returned false, leaves BaseBlockTree in undefined state.

Reimplemented in altintegration::AltBlockTree, altintegration::BlockTree< Block, ChainParams >, altintegration::BlockTree< VbkBlock, VbkChainParams >, and altintegration::VbkBlockTree.

Definition at line 189 of file base_block_tree.hpp.

191 {
192 return loadBlockInner(index, true, fast_load, state);
193 }

◆ loadTip()

template<typename Block >
virtual bool altintegration::BaseBlockTree< Block >::loadTip ( const hash_t &  hash,
ValidationState state 
)
inlinevirtual

Definition at line 156 of file base_block_tree.hpp.

156 {
157 VBK_TRACE_ZONE_SCOPED;
158 VBK_ASSERT_MSG(this->isLoadingBlocks_,
159 "%s tree must be in LoadingBlocks state!",
160 block_t::name());
161 VBK_ASSERT_MSG(
162 !this->isLoaded_, "%s tree is already loaded!", block_t::name());
163
164 auto* tip = getBlockIndex(hash);
165 if (tip == nullptr) {
166 return state.Invalid(
167 block_t::name() + "-no-tip",
168 format("tip {} doesn't exist in block tree", HexStr(hash)));
169 }
170
171 this->overrideTip(*tip);
172
173 // we no longer can execute loadTip/loadBlocks
174 this->isLoaded_ = true;
175 this->isLoadingBlocks_ = false;
176 return true;
177 }
std::string HexStr(const T itbegin, const T itend)
Convert bytes to hex.
Definition: strutil.hpp:44
bool isLoadingBlocks_
if true, we're in "loading blocks" state
bool isLoaded_
if true, we can no longer execute loadBlock/loadTip on this tree.

◆ makePrevHash() [1/2]

BaseBlockTree< VbkBlock >::prev_block_hash_t altintegration::BaseBlockTree< VbkBlock >::makePrevHash< BaseBlockTree< VbkBlock >::hash_t > ( const hash_t &  h) const
inline

In this weird case, when Block=VbkBlock, we may call getBlockIndex(block->previousBlock), it is a call getBlockIndex(Blob<12>). But whengetBlockIndex` accepts it, it does an implicit cast to full hash (hash_t), adding zeroes in the end. Then, .trimLE returns 12 zeroes.

This hack allows us to inject explicit conversion hash_t (Blob<24>) -> prev_block_hash_t (Blob<12>).

Definition at line 305 of file vbk_block_tree.hpp.

307 {
308 // do an explicit cast from hash_t -> prev_block_hash_t
309 return h.template trimLE<prev_block_hash_t::size()>();
310}

◆ makePrevHash() [2/2]

template<typename Block >
template<typename T >
prev_block_hash_t altintegration::BaseBlockTree< Block >::makePrevHash ( const T &  h) const
inline

Definition at line 98 of file base_block_tree.hpp.

98 {
99 // given any type T, just return an implicit cast to prev_block_hash_t
100 return h;
101 }

◆ overrideTip()

template<typename Block >
virtual void altintegration::BaseBlockTree< Block >::overrideTip ( index_t to)
inlinevirtual

Definition at line 416 of file base_block_tree.hpp.

416 {
417 onBeforeOverrideTip.emit(to);
418 activeChain_.setTip(&to);
419 appliedBlockCount = activeChain_.blocksCount();
420 }
signals::Signal< void(const index_t &index)> onBeforeOverrideTip
chain reorg signal - the tip is being changed

◆ removeLeaf()

template<typename Block >
void altintegration::BaseBlockTree< Block >::removeLeaf ( index_t toRemove)
inline

Definition at line 243 of file base_block_tree.hpp.

243 {
244 auto nondeletedDescendantCount = toRemove.nondeletedDescendantCount();
245
246 VBK_ASSERT_MSG(nondeletedDescendantCount == 0,
247 "not a leaf block %s, has %d non-deleted descendants",
248 toRemove.toPrettyString(),
249 nondeletedDescendantCount);
250 return this->removeSubtree(toRemove);
251 }
void removeSubtree(index_t &toRemove)
Removes block and all its successors.

◆ removeSubtree() [1/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::removeSubtree ( const hash_t &  toRemove)
inline
Invariant
block must exist in a tree

Definition at line 235 of file base_block_tree.hpp.

235 {
236 auto* index = getBlockIndex(toRemove);
237 VBK_ASSERT_MSG(
238 index, "cannot find the subtree to remove: %s", HexStr(toRemove));
239 return this->removeSubtree(*index);
240 }

◆ removeSubtree() [2/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::removeSubtree ( index_t toRemove)
inline
Parameters
toRemoveblock to be removed.
Warning
fails on assert if unknown hash is provided

Definition at line 200 of file base_block_tree.hpp.

200 {
201 VBK_TRACE_ZONE_SCOPED;
202 VBK_LOG_DEBUG("remove subtree %s", toRemove.toPrettyString());
203
204 VBK_ASSERT_MSG(!toRemove.isRoot(), "cannot remove the root block");
205 // save the pointer to the previous block
206 auto* prev = toRemove.pprev;
207
208 bool isOnMainChain = activeChain_.contains(&toRemove);
209 if (isOnMainChain) {
210 ValidationState dummy;
211 bool success = this->setState(*prev, dummy);
212 VBK_ASSERT_MSG(success, "err: %s", dummy.toString());
213 }
214
215 forEachNodePostorder<block_t>(
216 toRemove,
217 [&](index_t& next) {
218 onBeforeLeafRemoved(next);
219 tips_.erase(&next);
220 VBK_ASSERT(!next.isDeleted());
221 next.deleteTemporarily();
222 },
223 [&](index_t& next) { return !next.isDeleted(); });
224
225 // after removal, try to add tip
226 tryAddTip(prev);
227
228 if (isOnMainChain) {
229 updateTips();
230 }
231 }

◆ revalidateSubtree() [1/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::revalidateSubtree ( const hash_t &  hash,
enum BlockValidityStatus  reason,
bool  shouldDetermineBestChain = true 
)
inline

Definition at line 328 of file base_block_tree.hpp.

330 {
331 auto* index = this->getBlockIndex(hash);
332 VBK_ASSERT(index && "cannot find the subtree to revalidate");
333 revalidateSubtree(*index, reason, shouldDetermineBestChain);
334 }

◆ revalidateSubtree() [2/2]

template<typename Block >
void altintegration::BaseBlockTree< Block >::revalidateSubtree ( index_t toBeValidated,
enum BlockValidityStatus  reason,
bool  shouldDetermineBestChain = true 
)
inline

Definition at line 340 of file base_block_tree.hpp.

342 {
343 VBK_TRACE_ZONE_SCOPED;
344 VBK_LOG_DEBUG("Revalidating %s subtree: reason=%d block=%s",
345 block_t::name(),
346 (int)reason,
347 toBeValidated.toShortPrettyString());
348
349 VBK_ASSERT_MSG(!toBeValidated.isRoot(), "cannot revalidate the root block");
350
351 VBK_ASSERT_MSG(isValidInvalidationReason(reason),
352 "invalid revalidation reason");
353
354 if (!toBeValidated.hasFlags(reason)) {
355 return;
356 }
357
358 // if the block has any invalidity flags other than `reason`, its
359 // descendants are already flagged as BLOCK_FAILED_CHILD and should stay so
360 if (toBeValidated.hasFlags(static_cast<enum BlockValidityStatus>(
361 BLOCK_FAILED_MASK & ~reason))) {
362 doReValidate(toBeValidated, reason);
363 return;
364 }
365
366 doReValidate(toBeValidated, reason);
367
368 for (auto* pnext : toBeValidated.pnext) {
369 forEachNodePreorder<block_t>(*pnext, [&](index_t& index) -> bool {
370 doReValidate(index, BLOCK_FAILED_CHILD);
371 bool failed = index.isFailed();
372 return !failed;
373 });
374 }
375
376 if (shouldDetermineBestChain) {
377 updateTips();
378 }
379 }
BlockValidityStatus
Flags that describe block status.
@ BLOCK_FAILED_MASK
all invalidity flags

◆ setState() [1/2]

template<typename Block >
virtual bool altintegration::BaseBlockTree< Block >::setState ( const hash_t &  block,
ValidationState state 
)
inlinevirtual

Definition at line 401 of file base_block_tree.hpp.

401 {
402 auto* index = getBlockIndex(block);
403 if (index == nullptr) {
404 return state.Invalid(block_t::name() + "-setstate-unknown-block",
405 "could not find the block to set the state to");
406 }
407 return setState(*index, state);
408 }

◆ setState() [2/2]

template<typename Block >
virtual bool altintegration::BaseBlockTree< Block >::setState ( index_t index,
ValidationState  
)
inlinevirtual

Reimplemented in altintegration::AltBlockTree.

Definition at line 410 of file base_block_tree.hpp.

410 {
411 VBK_TRACE_ZONE_SCOPED;
412 overrideTip(index);
413 return true;
414 }

◆ toPrettyString()

template<typename Block >
std::string altintegration::BaseBlockTree< Block >::toPrettyString ( size_t  level = 0) const
inlineprotected

Definition at line 742 of file base_block_tree.hpp.

742 {
743 auto tip = activeChain_.tip();
744 std::string pad(level, ' ');
745
746 std::string blocksStr{};
747 // sort blocks by height
748 std::vector<std::pair<int, index_t*>> byheight;
749 byheight.reserve(blocks_.size());
750 for (const auto& p : blocks_) {
751 // FIXME: ugly hack due to trees being compared via toPrettyString in
752 // tests
753 if (!p.second->isDeleted()) {
754 byheight.emplace_back(p.second->getHeight(), p.second.get());
755 }
756 }
757 std::sort(byheight.rbegin(), byheight.rend());
758 for (const auto& p : byheight) {
759 blocksStr += (p.second->toPrettyString(level + 2) + "\n");
760 }
761
762 std::string tipsStr{};
763 for (const auto* _tip : tips_) {
764 tipsStr += (_tip->toPrettyString(level + 2) + "\n");
765 }
766
767 return format("{}{{tip={}}}\n{}{{blocks=\n{}{}}}\n{}{{tips=\n{}{}}}",
768 pad,
769 (tip ? tip->toPrettyString() : "<empty>"),
770 pad,
771 blocksStr,
772 pad,
773 pad,
774 tipsStr,
775 pad);
776 }

Member Data Documentation

◆ activeChain_

template<typename Block >
Chain<index_t> altintegration::BaseBlockTree< Block >::activeChain_
protected

Definition at line 1158 of file base_block_tree.hpp.

◆ blockProvider_

template<typename Block >
const BlockReader& altintegration::BaseBlockTree< Block >::blockProvider_
protected

Definition at line 1167 of file base_block_tree.hpp.

◆ blocks_

template<typename Block >
block_index_t altintegration::BaseBlockTree< Block >::blocks_
protected

Definition at line 1154 of file base_block_tree.hpp.

◆ finalizedPayloadsIndex_

template<typename Block >
FinalizedPayloadsIndex<index_t> altintegration::BaseBlockTree< Block >::finalizedPayloadsIndex_
protected

For BTC tree does nothing. stores payloads only from finalized blocks.

Definition at line 1162 of file base_block_tree.hpp.

◆ isLoaded_

template<typename Block >
bool altintegration::BaseBlockTree< Block >::isLoaded_ = false
protected

Definition at line 1152 of file base_block_tree.hpp.

◆ isLoadingBlocks_

template<typename Block >
bool altintegration::BaseBlockTree< Block >::isLoadingBlocks_ = false
protected

Definition at line 1150 of file base_block_tree.hpp.

◆ onBeforeOverrideTip

template<typename Block >
signals::Signal<void(const index_t& index)> altintegration::BaseBlockTree< Block >::onBeforeOverrideTip

Definition at line 1146 of file base_block_tree.hpp.

◆ onBlockBeforeDeallocated

template<typename Block >
signals::Signal<void(const index_t&)> altintegration::BaseBlockTree< Block >::onBlockBeforeDeallocated

Definition at line 1142 of file base_block_tree.hpp.

◆ onBlockValidityChanged

template<typename Block >
signals::Signal<on_invalidate_t> altintegration::BaseBlockTree< Block >::onBlockValidityChanged

Definition at line 1144 of file base_block_tree.hpp.

◆ payloadsIndex_

template<typename Block >
PayloadsIndex<index_t> altintegration::BaseBlockTree< Block >::payloadsIndex_
protected

For BTC tree does nothing.

Definition at line 1165 of file base_block_tree.hpp.

◆ tips_

template<typename Block >
std::unordered_set<index_t*> altintegration::BaseBlockTree< Block >::tips_
protected

Definition at line 1156 of file base_block_tree.hpp.


The documentation for this struct was generated from the following file: