veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
chain_slice.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_CHAIN_SLICE_HPP_
7#define ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_CHAIN_SLICE_HPP_
8
9#include <veriblock/pop/blockchain/block_index.hpp>
10
11namespace altintegration {
12
19template <typename BlockIndexT>
20struct ChainSlice {
21 using index_t = BlockIndexT;
22 using block_t = typename index_t::block_t;
23 using hash_t = typename index_t::hash_t;
24 using height_t = typename block_t::height_t;
25 using chain_t = Chain<index_t>;
26
27 using const_iterator_t = typename chain_t::const_iterator_t;
28 using const_reverse_iterator_t = typename chain_t::const_reverse_iterator_t;
29
30 ChainSlice(const chain_t& chain) : ChainSlice(chain, chain.firstHeight()) {}
31
32 explicit ChainSlice(const chain_t& chain, height_t firstHeight)
33 : ChainSlice(chain,
34 firstHeight,
35 chain.firstHeight() + chain.blocksCount() - firstHeight) {}
36
37 explicit ChainSlice(const chain_t& chain, height_t firstHeight, size_t size)
38 : chain_(chain), firstHeight_(firstHeight), size_(size) {
39 VBK_ASSERT(firstHeight >= chain.firstHeight());
40 VBK_ASSERT(firstHeight + size <= chain.firstHeight() + chain.blocksCount());
41 }
42
43 // for compatibility
44 height_t getStartHeight() const { return firstHeight(); }
45
46 bool contains(const index_t* index) const {
47 return index != nullptr && this->operator[](index->getHeight()) == index;
48 }
49
50 index_t* operator[](height_t height) const {
51 return height < firstHeight() || height > tipHeight() ? nullptr
52 : chain_[height];
53 }
54
55 index_t* next(const index_t* index) const {
56 return !contains(index) ? nullptr : (*this)[index->getHeight() + 1];
57 }
58
59 height_t firstHeight() const { return firstHeight_; }
60
61 height_t tipHeight() const { return (int)(firstHeight() + size()) - 1; }
62
63 // for compatibility
64 height_t chainHeight() const { return tip()->getHeight(); }
65
66 bool empty() const { return size() == 0; }
67
68 size_t size() const { return size_; }
69 // for compatibility
70 size_t blocksCount() const { return size(); }
71
72 index_t* tip() const { return empty() ? nullptr : chain_[tipHeight()]; }
73 index_t* first() const { return empty() ? nullptr : chain_[firstHeight()]; }
74
75 size_t firstOffset() const { return firstHeight() - chain_.firstHeight(); }
76 size_t tipOffset() const { return chain_.chainHeight() - tipHeight(); }
77
78 const_reverse_iterator_t rbegin() const {
79 return chain_.rbegin() + tipOffset();
80 }
81 const_reverse_iterator_t rend() const {
82 return chain_.rend() - firstOffset();
83 }
84
85 const_iterator_t begin() const { return chain_.begin() + firstOffset(); }
86 const_iterator_t end() const { return chain_.end() - tipOffset(); }
87
88 friend bool operator==(const ChainSlice& a, const ChainSlice& b) {
89 // one of the slices is empty, but the other is not
90 if (a.empty() != b.empty()) return false;
91 // both slices are empty
92 if (a.empty()) return true;
93 return a.tip()->getHash() == b.tip()->getHash();
94 }
95
96 friend bool operator!=(const ChainSlice& a, const ChainSlice& b) {
97 return !(a == b);
98 }
99
100 private:
101 const chain_t& chain_;
102 const height_t firstHeight_;
103 const size_t size_;
104};
105
106} // namespace altintegration
107
108#endif // ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_CHAIN_SLICE_HPP_
Defines logging helpers.
Definition: block.hpp:14
Non-owning partial chain view similar to std::span.
Definition: chain_slice.hpp:20
Fully in-memory chain representation.
Definition: chain.hpp:25