veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
block_provider_impl.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_ADAPTORS_BLOCK_PROVIDER_IMPL_HPP
7#define VERIBLOCK_POP_CPP_STORAGE_ADAPTORS_BLOCK_PROVIDER_IMPL_HPP
8
9#include <veriblock/pop/c/extern.h>
10
11#include <algorithm>
12#include <cstdint>
13#include <memory>
14#include <utility>
15#include <vector>
16#include <veriblock/pop/serde.hpp>
17#include <veriblock/pop/storage/block_batch.hpp>
18#include <veriblock/pop/storage/block_reader.hpp>
19
20#include "storage_interface.hpp"
21#include "veriblock/pop/entities/altblock.hpp"
22#include "veriblock/pop/entities/btcblock.hpp"
23#include "veriblock/pop/entities/vbkblock.hpp"
24#include "veriblock/pop/logger.hpp"
25#include "veriblock/pop/storage/block_iterator.hpp"
26#include "veriblock/pop/storage/stored_alt_block_addon.hpp"
27#include "veriblock/pop/storage/stored_block_index.hpp"
28#include "veriblock/pop/storage/stored_btc_block_addon.hpp"
29#include "veriblock/pop/storage/stored_vbk_block_addon.hpp"
30#include "veriblock/pop/uint.hpp"
31#include "veriblock/pop/validation_state.hpp"
32
33namespace altintegration {
34struct AltChainParams;
35
36namespace adaptors {
37
38const char DB_BTC_BLOCK = 'Q';
39const char DB_BTC_PREV_BLOCK = 'R';
40const char DB_BTC_TIP = 'q';
41const char DB_VBK_BLOCK = 'W';
42const char DB_VBK_PREV_BLOCK = 'T';
43const char DB_VBK_TIP = 'w';
44const char DB_ALT_BLOCK = 'E';
45const char DB_ALT_PREV_BLOCK = 'Y';
46const char DB_ALT_TIP = 'e';
47
48template <typename block_t>
49std::vector<uint8_t> tip_key();
50
51template <>
52std::vector<uint8_t> tip_key<AltBlock>();
53
54template <>
55std::vector<uint8_t> tip_key<VbkBlock>();
56
57template <>
58std::vector<uint8_t> tip_key<BtcBlock>();
59
60template <typename block_t>
61std::vector<uint8_t> block_key(const typename block_t::hash_t& hash);
62
63template <>
64std::vector<uint8_t> block_key<AltBlock>(const AltBlock::hash_t& hash);
65
66template <>
67std::vector<uint8_t> block_key<VbkBlock>(const VbkBlock::hash_t& hash);
68
69template <>
70std::vector<uint8_t> block_key<BtcBlock>(const BtcBlock::hash_t& hash);
71
72template <typename block_t>
73std::vector<uint8_t> block_prev_key(const typename block_t::prev_hash_t& hash);
74
75template <>
76std::vector<uint8_t> block_prev_key<AltBlock>(
77 const AltBlock::prev_hash_t& hash);
78
79template <>
80std::vector<uint8_t> block_prev_key<VbkBlock>(
81 const VbkBlock::prev_hash_t& hash);
82
83template <>
84std::vector<uint8_t> block_prev_key<BtcBlock>(
85 const BtcBlock::prev_hash_t& hash);
86
87template <typename BlockT>
88struct BlockIteratorImpl : public BlockIterator<BlockT> {
89 ~BlockIteratorImpl() override = default;
90
91 BlockIteratorImpl(std::shared_ptr<StorageIterator> it,
92 const AltChainParams& params)
93 : it_(std::move(it)), params_(params) {}
94
95 void next() override { it_->next(); }
96
97 bool value(StoredBlockIndex<BlockT>& out) const override {
98 std::vector<uint8_t> bytes;
99 if (!it_->value(bytes)) {
100 return false;
101 }
102
103 ValidationState dummy;
105 bytes, out, dummy)) {
106 VBK_LOG_ERROR("Can not deserialize StoredBlockIndex<%s>: %s",
107 BlockT::name(),
108 dummy.toString());
109 return false;
110 }
111
112 return true;
113 }
114
115 bool key(typename BlockT::hash_t& out) const override {
116 std::vector<uint8_t> bytes;
117 if (!it_->key(bytes)) {
118 return false;
119 }
120 // remove prefix
121 out = {bytes.begin() + 1, bytes.end()};
122 return true;
123 }
124
125 bool valid() const override {
126 static const uint8_t prefix = block_key<BlockT>({})[0];
127
128 std::vector<uint8_t> key;
129 return it_->valid() && it_->key(key) && !key.empty() && key[0] == prefix;
130 }
131
132 void seek_start() override {
133 static const uint8_t prefix = block_key<BlockT>({})[0];
134
135 it_->seek({prefix});
136 }
137
138 private:
139 std::shared_ptr<StorageIterator> it_;
140 const AltChainParams& params_;
141};
142
144 ~BlockReaderImpl() override = default;
145
146 BlockReaderImpl(Storage& storage, const AltChainParams& params)
147 : storage_(storage), params_(params) {}
148
149 bool getAltTip(AltBlock::hash_t& out) const override {
150 std::vector<uint8_t> bytes_out;
151 if (!storage_.read(tip_key<AltBlock>(), bytes_out)) {
152 return false;
153 }
154 out = bytes_out;
155 return true;
156 }
157 bool getVbkTip(VbkBlock::hash_t& out) const override {
158 std::vector<uint8_t> bytes_out;
159 if (!storage_.read(tip_key<VbkBlock>(), bytes_out)) {
160 return false;
161 }
162 out = bytes_out;
163 return true;
164 }
165 bool getBtcTip(BtcBlock::hash_t& out) const override {
166 std::vector<uint8_t> bytes_out;
167 if (!storage_.read(tip_key<BtcBlock>(), bytes_out)) {
168 return false;
169 }
170 out = bytes_out;
171 return true;
172 }
173
174 bool getBlock(const AltBlock::prev_hash_t& hash,
175 StoredBlockIndex<AltBlock>& out) const override {
176 return getBlock<AltBlock>(hash, out);
177 }
178
179 bool getBlock(const VbkBlock::prev_hash_t& hash,
180 StoredBlockIndex<VbkBlock>& out) const override {
181 return getBlock<VbkBlock>(hash, out);
182 }
183
184 bool getBlock(const BtcBlock::prev_hash_t& hash,
185 StoredBlockIndex<BtcBlock>& out) const override {
186 return getBlock<BtcBlock>(hash, out);
187 }
188
189 std::shared_ptr<BlockIterator<AltBlock>> getAltBlockIterator()
190 const override {
191 return std::make_shared<BlockIteratorImpl<AltBlock>>(
192 storage_.generateIterator(), params_);
193 }
194 std::shared_ptr<BlockIterator<VbkBlock>> getVbkBlockIterator()
195 const override {
196 return std::make_shared<BlockIteratorImpl<VbkBlock>>(
197 storage_.generateIterator(), params_);
198 }
199 std::shared_ptr<BlockIterator<BtcBlock>> getBtcBlockIterator()
200 const override {
201 return std::make_shared<BlockIteratorImpl<BtcBlock>>(
202 storage_.generateIterator(), params_);
203 }
204
205 private:
206 template <typename block_t>
207 bool getBlock(const typename block_t::prev_hash_t& prev_hash,
208 StoredBlockIndex<block_t>& out) const {
209 std::vector<uint8_t> hash_out;
210 if (!storage_.read(block_prev_key<block_t>(prev_hash), hash_out)) {
211 return false;
212 }
213
214 typename block_t::hash_t hash = hash_out;
215 std::vector<uint8_t> bytes_out;
216 if (!storage_.read(block_key<block_t>(hash), bytes_out)) {
217 return false;
218 }
219
220 ValidationState dummy;
222 bytes_out, out, dummy)) {
223 VBK_LOG_ERROR("Can not deserialize StoredBlockIndex<%s> block: %s",
224 block_t::name(),
225 dummy.toString());
226 return false;
227 }
228
229 return true;
230 }
231
232 Storage& storage_;
233 const AltChainParams& params_;
234};
235
236struct BlockBatchImpl : public BlockBatch {
237 ~BlockBatchImpl() override = default;
238
239 BlockBatchImpl(WriteBatch& batch) : batch_(batch) {}
240
241 void writeBlock(const AltBlock::hash_t& hash,
242 const AltBlock::prev_hash_t& prev_hash,
243 const StoredBlockIndex<AltBlock>& blk) override {
244 batch_.write(block_prev_key<AltBlock>(prev_hash), hash);
245 batch_.write(block_key<AltBlock>(hash), SerializeToVbkEncoding(blk));
246 }
247
248 void writeBlock(const VbkBlock::hash_t& hash,
249 const VbkBlock::prev_hash_t& prev_hash,
250 const StoredBlockIndex<VbkBlock>& blk) override {
251 batch_.write(block_prev_key<VbkBlock>(prev_hash), hash.asVector());
252 batch_.write(block_key<VbkBlock>(hash), SerializeToVbkEncoding(blk));
253 }
254
255 void writeBlock(const BtcBlock::hash_t& hash,
256 const BtcBlock::prev_hash_t& prev_hash,
257 const StoredBlockIndex<BtcBlock>& blk) override {
258 batch_.write(block_prev_key<BtcBlock>(prev_hash), hash.asVector());
259 batch_.write(block_key<BtcBlock>(hash), SerializeToVbkEncoding(blk));
260 }
261
262 void writeTip(const AltBlock::hash_t& hash) override {
263 batch_.write(tip_key<AltBlock>(), hash);
264 }
265
266 void writeTip(const VbkBlock::hash_t& hash) override {
267 batch_.write(tip_key<VbkBlock>(), hash.asVector());
268 }
269
270 void writeTip(const BtcBlock::hash_t& hash) override {
271 batch_.write(tip_key<BtcBlock>(), hash.asVector());
272 }
273
274 private:
275 WriteBatch& batch_;
276};
277
278} // namespace adaptors
279
280} // namespace altintegration
281
282#endif
Class that is used for storing validation state.
Defines logging helpers.
Definition: block.hpp:14
bool DeserializeFromVbkEncoding(ReadStream &stream, AltBlockAddon &out, ValidationState &state)
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::vector< uint8_t > SerializeToVbkEncoding(const T &obj)
Serialize to VBK encoding.
Definition: serde.hpp:440
Base class for all Altchain-related configs.
Contiguous byte array of fixed size.
Definition: blob.hpp:25
An interface which represents single write batch of a group of blocks.
Definition: block_batch.hpp:22
An abstraction over on-disk storage block iterator.
An abstraction over on-disk storage iterator.
void writeBlock(const AltBlock::hash_t &hash, const AltBlock::prev_hash_t &prev_hash, const StoredBlockIndex< AltBlock > &blk) override
Save BlockIndex on disk.
void writeBlock(const BtcBlock::hash_t &hash, const BtcBlock::prev_hash_t &prev_hash, const StoredBlockIndex< BtcBlock > &blk) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void writeTip(const VbkBlock::hash_t &hash) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void writeTip(const BtcBlock::hash_t &hash) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void writeBlock(const VbkBlock::hash_t &hash, const VbkBlock::prev_hash_t &prev_hash, const StoredBlockIndex< VbkBlock > &blk) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void writeTip(const AltBlock::hash_t &hash) override
Save Tree tip on disk.
void seek_start() override
Set iterator to the start of the collection.
void next() override
Iterate to the next block.
bool value(StoredBlockIndex< BlockT > &out) const override
Return the current block value.
bool key(typename BlockT::hash_t &out) const override
Return the current block hash key.
bool valid() const override
Return if valid iterator or not.