veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
util.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 VERIBLOCK_POP_CPP_STORAGE_UTIL_HPP
7#define VERIBLOCK_POP_CPP_STORAGE_UTIL_HPP
8
9#include <vector>
10#include <veriblock/pop/blockchain/alt_block_tree.hpp>
11#include <veriblock/pop/logger.hpp>
12#include <veriblock/pop/storage/block_reader.hpp>
13#include <veriblock/pop/validation_state.hpp>
14
15#include "block_batch.hpp"
16
17namespace altintegration {
18
22template <typename BlockTreeT>
23bool loadTree(BlockTreeT& tree,
24 const typename BlockTreeT::hash_t& tiphash,
25 std::vector<typename BlockTreeT::stored_index_t>& blocks,
26 bool fast_load,
27 ValidationState& state) {
28 using stored_index_t = typename BlockTreeT::stored_index_t;
29
30 if (blocks.size() == 0) return true;
31
32 VBK_LOG_INFO("Loading %d %s blocks with tip %s",
33 blocks.size(),
34 BlockTreeT::block_t::name(),
35 HexStr(tiphash));
36 VBK_ASSERT(tree.isBootstrapped() && "tree must be bootstrapped");
37
38 // first, sort them by height
39 std::sort(blocks.begin(),
40 blocks.end(),
41 [](const stored_index_t& a, const stored_index_t& b) {
42 return a.height < b.height;
43 });
44
45 for (const auto& block : blocks) {
46 // load blocks one by one
47 if (!tree.loadBlockForward(block, fast_load, state)) {
48 return state.Invalid("load-tree");
49 }
50 }
51
52 if (!tree.loadTip(tiphash, state)) {
53 return state.Invalid("load-tree");
54 }
55
56 auto* t = tree.getBestChain().tip();
57 VBK_ASSERT(t != nullptr);
58
59 return true;
60}
61
63template <typename BlockIndexT>
64void validateBlockIndex(const BlockIndexT&);
65
67template <typename BlockTreeT>
68void saveTree(
69 BlockTreeT& tree,
70 BlockBatch& batch,
71 std::function<void(const typename BlockTreeT::index_t&)> validator) {
72 using index_t = typename BlockTreeT::index_t;
73 std::vector<const index_t*> dirty_indices;
74
75 // map pair<hash, shared_ptr<index_t>> to vector<index_t*>
76 for (auto& index : tree.getAllBlocks()) {
77 if (index->isDirty()) {
78 index->unsetDirty();
79 dirty_indices.push_back(index);
80 }
81 }
82
83 // sort by height in descending order, because we need to calculate index hash
84 // during saving. this is needed to be progpow-cache friendly, as cache will
85 // be warm for last blocks.
86 std::sort(dirty_indices.begin(),
87 dirty_indices.end(),
88 [](const index_t* a, const index_t* b) {
89 return b->getHeight() < a->getHeight();
90 });
91
92 // write indices
93 for (const index_t* index : dirty_indices) {
94 validator(*index);
95 batch.writeBlock(index->getHash(),
96 tree.makePrevHash(index->getHash()),
97 index->toStoredBlockIndex());
98 }
99
100 batch.writeTip(tree.getBestChain().tip()->getHash());
101}
102
104template <typename BlockTreeT>
105void saveTree(BlockTreeT& tree, BlockBatch& batch) {
106 saveTree(tree, batch, &validateBlockIndex<typename BlockTreeT::index_t>);
107}
108
109struct AltBlockTree;
110
112void saveTrees(const AltBlockTree& tree, BlockBatch& batch);
113
115bool loadTrees(AltBlockTree& tree, bool fast_load, ValidationState& state);
116
117} // namespace altintegration
118
119#endif // VERIBLOCK_POP_CPP_STORAGE_UTIL_HPP
Class that is used for storing validation state.
Defines logging helpers.
Definition: block.hpp:14
void saveTrees(const AltBlockTree &tree, BlockBatch &batch)
Save all (BTC/VBK/ALT) trees on disk in a single Batch.
std::string HexStr(const T itbegin, const T itend)
Convert bytes to hex.
Definition: strutil.hpp:44
bool loadTree(BlockTreeT &tree, const typename BlockTreeT::hash_t &tiphash, std::vector< typename BlockTreeT::stored_index_t > &blocks, bool fast_load, ValidationState &state)
efficiently loads blocks into tree (they must be sorted by height) and does validation of these block...
Definition: util.hpp:23
bool loadTrees(AltBlockTree &tree, bool fast_load, ValidationState &state)
Load all (ALT/VBK/BTC) trees from disk into memory.
Represents simplified view on Altchain's block tree, maintains VBK tree and BTC tree.
An interface which represents single write batch of a group of blocks.
Definition: block_batch.hpp:22