veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
altintegration::BlockTree< Block, ChainParams > Struct Template Reference

BlockTree is a tree of blocks with single "bootstrap" block as root. More...

Detailed Description

template<typename Block, typename ChainParams>
struct altintegration::BlockTree< Block, ChainParams >
Template Parameters
Block

Definition at line 30 of file blocktree.hpp.

#include <blocktree.hpp>

+ Inheritance diagram for altintegration::BlockTree< Block, ChainParams >:
+ Collaboration diagram for altintegration::BlockTree< Block, ChainParams >:

Public Types

using base = BaseBlockTree< Block >
 
using block_t = Block
 
using params_t = ChainParams
 
using index_t = typename base::index_t
 
using stored_index_t = typename base::stored_index_t
 
using hash_t = typename Block::hash_t
 
using prev_block_hash_t = typename Block::prev_hash_t
 
using height_t = typename Block::height_t
 
- Public Types inherited from altintegration::BaseBlockTree< Block >
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

 BlockTree (const ChainParams &param, const BlockReader &blockProvider)
 
const ChainParams & getParams () const
 
virtual void bootstrapWithGenesis (const block_t &block)
 Bootstrap blockchain with a single genesis block. More...
 
virtual void bootstrapWithChain (height_t startHeight, const std::vector< block_t > &chain)
 Bootstrap network with a chain that starts at 'startHeight'. More...
 
bool acceptBlockHeader (const block_t &block, ValidationState &state)
 
bool acceptBlockHeader (const std::shared_ptr< block_t > &block, ValidationState &state)
 
std::string toPrettyString (size_t level=0) const
 
bool loadBlockForward (const stored_index_t &index, bool fast_load, ValidationState &state) override
 
bool isBlockOld (height_t height) const
 block is considered old if it is behind current tip further than 'old blocks window' blocks More...
 
bool isBlockOld (const hash_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...
 
void finalizeBlocks ()
 
- Public Member Functions inherited from altintegration::BaseBlockTree< Block >
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...
 

Protected Member Functions

bool acceptBlockHeaderImpl (const std::shared_ptr< block_t > &block, ValidationState &state, bool shouldContextuallyCheck)
 
void bootstrap (height_t height, const block_t &block, ValidationState &state)
 
void bootstrap (height_t height, std::shared_ptr< block_t > block, ValidationState &state)
 
bool validateAndAddBlock (const std::shared_ptr< block_t > &block, ValidationState &state, bool shouldContextuallyCheck, index_t **ret)
 
void determineBestChain (index_t &candidate, ValidationState &state) override
 
void onBlockInserted (index_t *newIndex) final
 whenever new block is inserted, BlockTree has to update its ChainWork More...
 
- Protected Member Functions inherited from altintegration::BaseBlockTree< Block >
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

const ChainParams * param_ = nullptr
 
- Protected Attributes inherited from altintegration::BaseBlockTree< Block >
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_
 

Additional Inherited Members

- Public Attributes inherited from altintegration::BaseBlockTree< Block >
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...
 

Member Typedef Documentation

◆ base

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::base = BaseBlockTree<Block>

Definition at line 31 of file blocktree.hpp.

◆ block_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::block_t = Block

Definition at line 32 of file blocktree.hpp.

◆ hash_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::hash_t = typename Block::hash_t

Definition at line 36 of file blocktree.hpp.

◆ height_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::height_t = typename Block::height_t

Definition at line 38 of file blocktree.hpp.

◆ index_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::index_t = typename base::index_t

Definition at line 34 of file blocktree.hpp.

◆ params_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::params_t = ChainParams

Definition at line 33 of file blocktree.hpp.

◆ prev_block_hash_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::prev_block_hash_t = typename Block::prev_hash_t

Definition at line 37 of file blocktree.hpp.

◆ stored_index_t

template<typename Block , typename ChainParams >
using altintegration::BlockTree< Block, ChainParams >::stored_index_t = typename base::stored_index_t

Definition at line 35 of file blocktree.hpp.

Constructor & Destructor Documentation

◆ BlockTree()

template<typename Block , typename ChainParams >
altintegration::BlockTree< Block, ChainParams >::BlockTree ( const ChainParams &  param,
const BlockReader blockProvider 
)
inline

Definition at line 42 of file blocktree.hpp.

43 : base(blockProvider), param_(&param) {}

Member Function Documentation

◆ acceptBlockHeader() [1/2]

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::acceptBlockHeader ( const block_t &  block,
ValidationState state 
)
inline

Definition at line 103 of file blocktree.hpp.

103 {
104 return acceptBlockHeaderImpl(std::make_shared<block_t>(block), state, true);
105 }

◆ acceptBlockHeader() [2/2]

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::acceptBlockHeader ( const std::shared_ptr< block_t > &  block,
ValidationState state 
)
inline

Definition at line 107 of file blocktree.hpp.

108 {
109 return acceptBlockHeaderImpl(block, state, true);
110 }

◆ acceptBlockHeaderImpl()

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::acceptBlockHeaderImpl ( const std::shared_ptr< block_t > &  block,
ValidationState state,
bool  shouldContextuallyCheck 
)
inlineprotected

Definition at line 191 of file blocktree.hpp.

193 {
194 index_t* index = nullptr;
195 if (!validateAndAddBlock(block, state, shouldContextuallyCheck, &index)) {
196 return false;
197 }
198
199 VBK_ASSERT(index);
200 if (!shouldContextuallyCheck) {
201 // this is a bootstrap block
202 index->setFlag(BLOCK_BOOTSTRAP);
203 }
204
205 base::tryAddTip(index);
206
207 // don't defer fork resolution in the acceptBlockHeader+addPayloads flow
208 // until the validation hole is plugged
209 determineBestChain(*index, state);
210
211 return true;
212 }
@ BLOCK_BOOTSTRAP
this is a bootstrap block
void determineBestChain(index_t &candidate, ValidationState &state) override
Definition: blocktree.hpp:293

◆ bootstrap() [1/2]

template<typename Block , typename ChainParams >
void altintegration::BlockTree< Block, ChainParams >::bootstrap ( height_t  height,
const block_t &  block,
ValidationState state 
)
inlineprotected

Definition at line 214 of file blocktree.hpp.

216 {
217 bootstrap(height, std::make_shared<block_t>(block), state);
218 }

◆ bootstrap() [2/2]

template<typename Block , typename ChainParams >
void altintegration::BlockTree< Block, ChainParams >::bootstrap ( height_t  height,
std::shared_ptr< block_t >  block,
ValidationState state 
)
inlineprotected

Definition at line 220 of file blocktree.hpp.

222 {
223 bool ok = checkBlock(*block, state, *param_);
224 VBK_ASSERT_MSG(ok,
225 "found statelessly invalid bootstrap block in %s tree: %s",
226 block_t::name(),
227 state.toString());
228
229 auto* index = base::insertBlockHeader(block, height);
230 VBK_ASSERT(index != nullptr &&
231 "insertBlockHeader should have never returned nullptr");
232
233 index->setHeight(height);
234 base::activeChain_ = Chain<index_t>(height, index);
235 index->setIsBootstrap(true);
236
237 VBK_ASSERT(index->finalized);
238 VBK_ASSERT(base::isBootstrapped());
239 VBK_ASSERT(base::getBlockIndex(index->getHash()) != nullptr &&
240 "getBlockIndex must be able to find the block added by "
241 "insertBlockHeader");
242
243 base::tryAddTip(index);
244 index->setFlag(BLOCK_ACTIVE);
245 bool success = index->raiseValidity(BLOCK_CAN_BE_APPLIED);
246 VBK_ASSERT(success);
247 index->setFlag(BLOCK_BOOTSTRAP);
248 base::appliedBlockCount = 1;
249 }
@ BLOCK_CAN_BE_APPLIED
the chain with the block at its tip is fully valid, so if we do SetState on this block,...
@ BLOCK_ACTIVE
the block is currently applied via SetState.
bool checkBlock(const BtcBlock &block, ValidationState &state, const BtcChainParams &params)
Stateless validation for a single block.
Chain< index_t > activeChain_
currently applied chain
bool isBootstrapped() const
Check if the blockchain is bootstrapped.
index_t * getBlockIndex(const T &hash)
Get BlockIndex by block hash.

◆ bootstrapWithChain()

template<typename Block , typename ChainParams >
virtual void altintegration::BlockTree< Block, ChainParams >::bootstrapWithChain ( height_t  startHeight,
const std::vector< block_t > &  chain 
)
inlinevirtual

This function does all blockchain integrity checks, does blockchain cleanup and in general, very slow.

Parameters
[in]startHeightstart height of the chain
[in]chainbootstrap chain

Definition at line 68 of file blocktree.hpp.

69 {
70 VBK_ASSERT(!base::isBootstrapped() && "already bootstrapped");
71 VBK_ASSERT(!this->isLoadingBlocks_);
72 VBK_ASSERT(!this->isLoaded_);
73 VBK_ASSERT_MSG(!chain.empty(), "bootstrap chain must not be empty");
74 VBK_ASSERT_MSG(
75 chain.size() >= param_->numBlocksForBootstrap(),
76 "bootstrap chain is too small (%d) expected at least %d blocks",
77 chain.size(),
78 param_->numBlocksForBootstrap());
79
80 ValidationState state;
81
82 // pick first block from the chain, bootstrap with a single block
83 auto genesis = chain[0];
84 this->bootstrap(startHeight, genesis, state);
85
86 // apply the rest of the blocks from the chain on top of our bootstrap
87 // block. disable difficulty checks, because we have not enough blocks in
88 // our store (yet) to check it correctly
89 for (size_t i = 1, size = chain.size(); i < size; i++) {
90 auto& block = chain[i];
91 bool ok = this->acceptBlockHeaderImpl(
92 std::make_shared<block_t>(block), state, false);
93 VBK_ASSERT_MSG(ok,
94 "found statelssly invalid bootstrap block: %d, %s",
95 i,
96 state.toString());
97 auto* index = base::getBlockIndex(block.getHash());
98 VBK_ASSERT(index);
99 index->setIsBootstrap(true);
100 }
101 }
bool isLoadingBlocks_
if true, we're in "loading blocks" state
bool isLoaded_
if true, we can no longer execute loadBlock/loadTip on this tree.

◆ bootstrapWithGenesis()

template<typename Block , typename ChainParams >
virtual void altintegration::BlockTree< Block, ChainParams >::bootstrapWithGenesis ( const block_t &  block)
inlinevirtual

Definition at line 50 of file blocktree.hpp.

50 {
51 VBK_ASSERT(!base::isBootstrapped() && "already bootstrapped");
52 VBK_ASSERT(!this->isLoaded_);
53 VBK_ASSERT(!this->isLoadingBlocks_);
54 ValidationState state;
55 this->bootstrap(0, block, state);
56 this->isLoadingBlocks_ = false;
57 }

◆ determineBestChain()

template<typename Block , typename ChainParams >
void altintegration::BlockTree< Block, ChainParams >::determineBestChain ( index_t candidate,
ValidationState state 
)
inlineoverrideprotectedvirtual

important to use this->setState for proper vtable resolution

Implements altintegration::BaseBlockTree< Block >.

Definition at line 293 of file blocktree.hpp.

293 {
294 auto bestTip = base::getBestChain().tip();
295 VBK_ASSERT(bestTip != nullptr && "must be bootstrapped");
296
297 if (bestTip == &candidate) {
298 return;
299 }
300
301 // do not even consider invalid candidates
302 if (!candidate.isValid()) {
303 return;
304 }
305
306 if (bestTip->chainWork < candidate.chainWork) {
308 this->setState(candidate, state);
309 }
310 }
const Chain< index_t > & getBestChain() const
Getter for currently Active Chain.

◆ finalizeBlocks()

template<typename Block , typename ChainParams >
void altintegration::BlockTree< Block, ChainParams >::finalizeBlocks ( )
inline

Definition at line 182 of file blocktree.hpp.

182 {
183 VBK_ASSERT(!this->isLoadingBlocks_);
184 base::finalizeBlocks(this->getParams().getMaxReorgBlocks(),
185 this->getParams().preserveBlocksBehindFinal());
186 }

◆ getParams()

template<typename Block , typename ChainParams >
const ChainParams & altintegration::BlockTree< Block, ChainParams >::getParams ( ) const
inline

Definition at line 45 of file blocktree.hpp.

45{ return *param_; }

◆ isBlockOld() [1/2]

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::isBlockOld ( const hash_t &  hash) const
inline

Definition at line 172 of file blocktree.hpp.

172 {
173 auto* index = base::getBlockIndex(hash);
174 if (index == nullptr) {
175 // block is unknown, so not "old"
176 return false;
177 }
178
179 return isBlockOld(index->getHeight());
180 }
bool isBlockOld(height_t height) const
block is considered old if it is behind current tip further than 'old blocks window' blocks
Definition: blocktree.hpp:164

◆ isBlockOld() [2/2]

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::isBlockOld ( height_t  height) const
inline

Definition at line 164 of file blocktree.hpp.

164 {
165 auto* tip = base::getBestChain().tip();
166 VBK_ASSERT(tip);
167
168 return tip->getHeight() - height > getParams().getOldBlocksWindow();
169 }

◆ loadBlockForward()

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::loadBlockForward ( const stored_index_t index,
bool  fast_load,
ValidationState state 
)
inlineoverridevirtual
Invariant
NOT atomic.

Reimplemented from altintegration::BaseBlockTree< Block >.

Definition at line 123 of file blocktree.hpp.

125 {
126 if (!fast_load && !checkBlock(*index.header, state, *param_)) {
127 return state.Invalid("bad-header");
128 }
129
130 const auto hash = index.header->getHash();
131 if (!base::loadBlockForward(index, fast_load, state)) {
132 return false;
133 }
134
135 auto* current = base::getBlockIndex(hash);
136 VBK_ASSERT(current);
137 VBK_ASSERT(!this->isLoaded_);
138 VBK_ASSERT(this->isLoadingBlocks_);
139
140 // we only check blocks contextually if they are not bootstrap blocks, and
141 // previous block exists
142 if (!fast_load && !current->isRoot() &&
143 !current->hasFlags(BLOCK_BOOTSTRAP) &&
144 !contextuallyCheckBlock(
145 *current->pprev, current->getHeader(), state, *param_)) {
146 return state.Invalid("bad-block-contextually");
147 }
148
149 // recover chainwork
150 current->chainWork = getBlockProof(current->getHeader());
151 if (!current->isRoot()) {
152 current->chainWork += current->pprev->chainWork;
153 }
154
155 // clear blockOfProofEndorsements inmem field
156 current->clearBlockOfProofEndorsement();
157
158 current->raiseValidity(BLOCK_VALID_TREE);
159 return true;
160 }
@ BLOCK_VALID_TREE
acceptBlockHeader succeded.
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.

◆ onBlockInserted()

template<typename Block , typename ChainParams >
void altintegration::BlockTree< Block, ChainParams >::onBlockInserted ( index_t newIndex)
inlinefinalprotectedvirtual

Reimplemented from altintegration::BaseBlockTree< Block >.

Definition at line 313 of file blocktree.hpp.

313 {
314 newIndex->chainWork = getBlockProof(newIndex->getHeader());
315 if (!newIndex->isRoot()) {
316 newIndex->chainWork += newIndex->pprev->chainWork;
317 }
318 }

◆ toPrettyString()

template<typename Block , typename ChainParams >
std::string altintegration::BlockTree< Block, ChainParams >::toPrettyString ( size_t  level = 0) const
inline

Definition at line 112 of file blocktree.hpp.

112 {
113 std::string pad(level, ' ');
114 return format("{}{}BlockTree{{blocks={}\n{}\n{}}}",
115 pad,
116 Block::name(),
117 base::getBlocks().size(),
118 base::toPrettyString(level + 2),
119 pad);
120 }

◆ validateAndAddBlock()

template<typename Block , typename ChainParams >
bool altintegration::BlockTree< Block, ChainParams >::validateAndAddBlock ( const std::shared_ptr< block_t > &  block,
ValidationState state,
bool  shouldContextuallyCheck,
index_t **  ret 
)
inlineprotected

Definition at line 251 of file blocktree.hpp.

254 {
255 if (!checkBlock(*block, state, *param_)) {
256 return state.Invalid(block_t::name() + "-check-block");
257 }
258
259 // we must know previous block
260 auto* prev = base::getBlockIndex(block->getPreviousBlock());
261 if (prev == nullptr) {
262 return state.Invalid(
263 block_t::name() + "-bad-prev-block",
264 "can not find previous block: " + HexStr(block->getPreviousBlock()));
265 }
266
267 if (shouldContextuallyCheck &&
268 !contextuallyCheckBlock(*prev, *block, state, *param_)) {
269 return state.Invalid(block_t::name() + "-contextually-check-block");
270 }
271
272 auto index = base::insertBlockHeader(block);
273 VBK_ASSERT(index != nullptr &&
274 "insertBlockHeader should have never returned nullptr");
275
276 if (ret) {
277 *ret = index;
278 }
279
280 index->raiseValidity(BLOCK_CONNECTED);
281
282 // if prev block is invalid, mark this block as invalid
283 if (!prev->isValid()) {
284 index->setFlag(BLOCK_FAILED_CHILD);
285 return state.Invalid(
286 block_t::name() + "-bad-chain",
287 format("Previous block is invalid={}", prev->toPrettyString()));
288 }
289
290 return true;
291 }
@ BLOCK_CONNECTED
the block is connected via connectBlock, which means that this block and all its ancestors are at lea...
@ BLOCK_FAILED_CHILD
block is state{lessly,fully} valid and the altchain did not report it as invalid, but some of the anc...
std::string HexStr(const T itbegin, const T itend)
Convert bytes to hex.
Definition: strutil.hpp:44

Member Data Documentation

◆ param_

template<typename Block , typename ChainParams >
const ChainParams* altintegration::BlockTree< Block, ChainParams >::param_ = nullptr
protected

Definition at line 189 of file blocktree.hpp.


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