veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
vbk_block_tree.hpp
1// Copyright (c) 2019-2022 Xenios SEZC
2// https://www.veriblock.org
3// Distributed under the MIT software license, see the accompanying
4// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_VBK_BLOCK_TREE_HPP_
7#define ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_VBK_BLOCK_TREE_HPP_
8
9#include <unordered_map>
10#include <utility>
11
12#include "veriblock/pop/blockchain/blocktree.hpp"
13#include "veriblock/pop/blockchain/commands/vbk_command_group_store.hpp"
14#include "veriblock/pop/blockchain/pop/fork_resolution.hpp"
15#include "veriblock/pop/blockchain/pop/pop_state_machine.hpp"
16#include "veriblock/pop/blockchain/vbk_block_addon.hpp"
17#include "veriblock/pop/blockchain/vbk_chain_params.hpp"
18#include "veriblock/pop/entities/btcblock.hpp"
19#include "veriblock/pop/finalizer.hpp"
20#include "veriblock/pop/storage/block_reader.hpp"
21
22namespace altintegration {
23
24template <>
25inline void BaseBlockTree<BtcBlock>::decreaseAppliedBlockCount(size_t) {
26 // do nothing
27 // BTC tree is not protected
28}
29
30// defined in vbk_block_tree.cpp
31extern template struct BlockIndex<BtcBlock>;
32extern template struct BlockTree<BtcBlock, BtcChainParams>;
33extern template struct BaseBlockTree<BtcBlock>;
34extern template struct BlockIndex<VbkBlock>;
35extern template struct BlockTree<VbkBlock, VbkChainParams>;
36extern template struct BaseBlockTree<VbkBlock>;
37
40
97 using BtcTree = BtcBlockTree;
98 using index_t = VbkTree::index_t;
99 using stored_index_t = VbkTree::stored_index_t;
100 using payloads_t = typename index_t::payloads_t;
101 using pid_t = typename payloads_t::id_t;
102 using endorsement_t = typename index_t::endorsement_t;
104 using PopForkComparator = PopAwareForkResolutionComparator<VbkBlock,
106 BtcTree,
108
109 ~VbkBlockTree() override = default;
110
111 VbkBlockTree(const VbkChainParams& vbkp,
112 const BtcChainParams& btcp,
113 PayloadsStorage& payloadsProvider,
114 BlockReader& blockProvider);
115
122 bool loadBlockForward(const stored_index_t& index,
123 bool fast_load,
124 ValidationState& state) override;
125
126 BtcTree& btc() { return cmp_.getProtectingBlockTree(); }
127 const BtcTree& btc() const { return cmp_.getProtectingBlockTree(); }
128
129 PopForkComparator& getComparator() { return cmp_; }
130 const PopForkComparator& getComparator() const { return cmp_; }
132 VbkCommandGroupStore& getCommandGroupStore() { return commandGroupStore_; }
134 const VbkCommandGroupStore& getCommandGroupStore() const {
135 return commandGroupStore_;
136 }
137
138 bool loadTip(const hash_t& hash, ValidationState& state) override;
139
140 // Calculates an approximate amount of missed PopTxs in provided VbkBlock index
141 uint32_t estimateMissedNumberOfVTBs(const index_t& index) const;
142
150 const std::vector<payloads_t>& payloads,
151 ValidationState& state);
152
153 void removePayloads(const hash_t& hash, const std::vector<pid_t>& pids);
154 void removePayloads(index_t& index, const std::vector<pid_t>& pids);
155
168 void unsafelyRemovePayload(const Blob<24>& hash, const pid_t& pid);
169 void unsafelyRemovePayload(index_t& index,
170 const pid_t& pid,
171 bool shouldDetermineBestChain = true);
172
173 std::string toPrettyString(size_t level = 0) const;
174
175 using base::setState;
176 bool setState(index_t& to, ValidationState& state) override;
177
178 void overrideTip(index_t& to) override;
179
180 void finalizeBlocks();
181
182 private:
183 bool loadBlockInner(const stored_index_t& index,
184 bool fast_load,
185 ValidationState& state);
186
187 bool validateBTCContext(const payloads_t& vtb, ValidationState& state);
196 bool addPayloadToAppliedBlock(index_t& index,
197 const payloads_t& payload,
198 ValidationState& state);
199
200 void determineBestChain(index_t& candidate, ValidationState& state) override;
201
202 PopForkComparator cmp_;
203 PayloadsStorage& payloadsProvider_;
204 command_group_store_t commandGroupStore_;
205};
206
208template <>
209void assertBlockCanBeRemoved(const BlockIndex<BtcBlock>& index);
211template <>
212void assertBlockCanBeRemoved(const BlockIndex<VbkBlock>& index);
213
215template <>
216void assertBlockSanity(const VbkBlock& block);
217
219template <>
220std::vector<CommandGroup> payloadsToCommandGroups(
221 VbkBlockTree& tree,
222 const std::vector<VTB>& pop,
223 const std::vector<uint8_t>& containinghash);
224
226template <>
227void payloadToCommands(VbkBlockTree& tree,
228 const VTB& pop,
229 const std::vector<uint8_t>& containingHash,
230 std::vector<CommandPtr>& cmds);
231
233template <typename JsonValue>
234JsonValue ToJSON(const BlockIndex<VbkBlock>& i) {
235 auto obj = json::makeEmptyObject<JsonValue>();
236 json::putStringKV(obj, "chainWork", i.chainWork.toHex());
237
238 std::vector<uint256> endorsements;
239 for (const auto& e : i.getContainingEndorsements()) {
240 endorsements.push_back(e.first);
241 }
242 json::putArrayKV(obj, "containingEndorsements", endorsements);
243
244 std::vector<uint256> endorsedBy;
245 for (const auto* e : i.getEndorsedBy()) {
246 endorsedBy.push_back(e->id);
247 }
248 json::putArrayKV(obj, "endorsedBy", endorsedBy);
249 json::putIntKV(obj, "height", i.getHeight());
250 json::putKV(obj, "header", ToJSON<JsonValue>(i.getHeader()));
251 json::putIntKV(obj, "status", i.getStatus());
252 json::putIntKV(obj, "altrefs", i.refCount());
253
254 auto stored = json::makeEmptyObject<JsonValue>();
255 json::putArrayKV(stored, "vtbids", i.getPayloadIds<VTB>());
256 json::putKV(obj, "stored", stored);
257
258 auto bopEndorsements = json::makeEmptyArray<JsonValue>();
259 for (const auto* e : i.getBlockOfProofEndorsement()) {
260 if (e == nullptr) {
261 continue;
262 }
263 json::arrayPushBack(bopEndorsements, ToJSON<JsonValue>(e->getId()));
264 }
265 json::putKV(obj, "blockOfProofEndorsements", bopEndorsements);
266
267 return obj;
268}
269
271template <typename JsonValue>
272JsonValue ToJSON(const BlockIndex<BtcBlock>& i) {
273 auto obj = json::makeEmptyObject<JsonValue>();
274 json::putStringKV(obj, "chainWork", i.chainWork.toHex());
275 json::putIntKV(obj, "height", i.getHeight());
276 json::putKV(obj, "header", ToJSON<JsonValue>(i.getHeader()));
277 json::putIntKV(obj, "status", i.getStatus());
278 json::putArrayKV(obj, "vbkrefs", i.getRefs());
279
280 auto bopEndorsements = json::makeEmptyArray<JsonValue>();
281 for (const auto* e : i.getBlockOfProofEndorsement()) {
282 if (e == nullptr) {
283 continue;
284 }
285 json::arrayPushBack(bopEndorsements, ToJSON<JsonValue>(e->getId()));
286 }
287 json::putKV(obj, "blockOfProofEndorsements", bopEndorsements);
288
289 return obj;
290}
291
303template <>
304template <>
307 const hash_t& h) const {
308 // do an explicit cast from hash_t -> prev_block_hash_t
309 return h.template trimLE<prev_block_hash_t::size()>();
310}
311
313inline void PrintTo(const VbkBlockTree& tree, std::ostream* os) {
314 *os << tree.toPrettyString();
315}
316
317} // namespace altintegration
318
319#endif // ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_VBK_BLOCK_TREE_HPP_
Class that is used for storing validation state.
Defines logging helpers.
Definition: block.hpp:14
BlockTree< BtcBlock, BtcChainParams > BtcBlockTree
Bitcoin tree.
void PrintTo(const ArithUint256 &uint, ::std::ostream *os)
custom gtest printer, which prints Blob of any size as hexstring @ private
Base block tree that stores all blocks, maintains tree tips, maintains active chain.
Contiguous byte array of fixed size.
Definition: blob.hpp:25
A node in a block tree.
Definition: block_index.hpp:31
An abstraction over on-disk storage iterator.
BlockTree is a tree of blocks with single "bootstrap" block as root.
Definition: blocktree.hpp:30
base class for BTC params
Accessor for ATV/VTB/VbkBlock bodies given hash.
Veriblock to Bitcoin publication, committed to Veriblock blockchain in containingBlock.
Definition: vtb.hpp:37
Veriblock block tree.
void unsafelyRemovePayload(const Blob< 24 > &hash, const pid_t &pid)
If we add payloads to the VBK tree in the following order: A1, B2, A3.
bool loadBlockForward(const stored_index_t &index, bool fast_load, ValidationState &state) override
efficiently connect index to current tree as a leaf, loaded from disk
bool addPayloads(const VbkBlock::hash_t &hash, const std::vector< payloads_t > &payloads, ValidationState &state)
Attempts to add payloads to the block and perform full validation.
Veriblock block.
Definition: vbkblock.hpp:32
VeriBlock chain parameters.
A wrapper for the payload store that constructs command objects.