6#ifndef ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_BLOCKCHAIN_UTIL_HPP_
7#define ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_BLOCKCHAIN_UTIL_HPP_
9#include <veriblock/pop/validation_state.hpp>
11#include "block_index.hpp"
13#include "command_group.hpp"
18template <
typename Block>
19void determineBestChain(Chain<Block>& currentBest, BlockIndex<Block>& indexNew);
22template <
typename Block,
typename ChainParams>
23uint32_t getNextWorkRequired(
const BlockIndex<Block>& prevBlock,
25 const ChainParams& params);
28template <
typename Block>
29ArithUint256 getBlockProof(
const Block& block);
32template <
typename Block>
33int64_t getMedianTimePast(
const BlockIndex<Block>& prev);
36template <
typename Block,
typename ChainParams>
37bool checkBlockTime(
const BlockIndex<Block>& prev,
39 ValidationState& state,
40 const ChainParams& param);
43template <
typename Block,
typename ChainParams>
44bool contextuallyCheckBlock(
const BlockIndex<Block>& prev,
46 ValidationState& state,
47 const ChainParams& params,
48 bool shouldVerifyNextWork =
true);
51template <
typename ProtectedBlockTree>
52bool recoverEndorsements(ProtectedBlockTree& ed_,
53 typename ProtectedBlockTree::index_t& toRecover,
54 Chain<typename ProtectedBlockTree::index_t>& chain,
55 ValidationState& state) {
56 std::vector<std::function<void()>> actions;
57 auto& containingEndorsements = toRecover.getContainingEndorsements();
58 actions.reserve(containingEndorsements.size());
59 auto& ing = ed_.getComparator().getProtectingBlockTree();
61 for (
const auto& p : containingEndorsements) {
66 return state.Invalid(
"bad-id",
70 auto* endorsed = ed_.getBlockIndex(e.endorsedHash);
71 if (endorsed ==
nullptr) {
74 format(
"Can not find endorsed block in {}", e.toPrettyString()));
77 if (chain[endorsed->getHeight()] ==
nullptr ||
78 chain[endorsed->getHeight()]->getHash() != e.endorsedHash ||
79 endorsed->getHash() != e.endorsedHash) {
82 format(
"Endorsed block does not match {}", e.toPrettyString()));
85 if (e.containingHash != toRecover.getHash()) {
88 format(
"Containing block does not match {}", e.toPrettyString()));
91 auto* blockOfProof = as_mut(ing).getBlockIndex(e.blockOfProof);
93 if (blockOfProof ==
nullptr) {
96 format(
"Block Of Proof {} does not exist in SP chain",
101 const auto* endorsement = &e;
105 actions.push_back([endorsed, blockOfProof, endorsement] {
106 auto& by = endorsed->getEndorsedBy();
107 VBK_ASSERT_MSG(std::find(by.begin(), by.end(), endorsement) == by.end(),
108 "same endorsement is added to endorsedBy second time");
109 bool isDirty = endorsed->isDirty();
110 endorsed->insertEndorsedBy(endorsement);
114 endorsed->unsetDirty();
117 const auto& bop = blockOfProof->getBlockOfProofEndorsement();
119 std::find(bop.begin(), bop.end(), endorsement) == bop.end(),
120 "same endorsement is added to blockOfProof second time");
121 isDirty = blockOfProof->isDirty();
122 blockOfProof->insertBlockOfProofEndorsement(endorsement);
125 blockOfProof->unsetDirty();
132 for (
auto& f : actions) {
140template <
typename ProtectedBlockTree>
141void recoverEndorsementsFast(ProtectedBlockTree& ed_,
142 typename ProtectedBlockTree::index_t& toRecover) {
143 std::vector<std::function<void()>> actions;
144 auto& containingEndorsements = toRecover.getContainingEndorsements();
145 actions.reserve(containingEndorsements.size());
146 auto& ing = ed_.getComparator().getProtectingBlockTree();
148 for (
const auto& p : containingEndorsements) {
151 auto* endorsed = ed_.getBlockIndex(e.endorsedHash);
152 auto* blockOfProof = as_mut(ing).getBlockIndex(e.blockOfProof);
155 const auto* endorsement = &e;
159 actions.push_back([endorsed, blockOfProof, endorsement] {
160 auto& by = endorsed->getEndorsedBy();
161 VBK_ASSERT_MSG(std::find(by.begin(), by.end(), endorsement) == by.end(),
162 "same endorsement is added to endorsedBy second time");
163 bool isDirty = endorsed->isDirty();
164 endorsed->insertEndorsedBy(endorsement);
168 endorsed->unsetDirty();
171 const auto& bop = blockOfProof->getBlockOfProofEndorsement();
173 std::find(bop.begin(), bop.end(), endorsement) == bop.end(),
174 "same endorsement is added to blockOfProof second time");
175 isDirty = blockOfProof->isDirty();
176 blockOfProof->insertBlockOfProofEndorsement(endorsement);
179 blockOfProof->unsetDirty();
186 for (
auto& f : actions) {
192template <
typename Block>
193void assertBlockCanBeRemoved(
const Block& block);
196template <
typename Block>
197void assertBlockSanity(
const Block& block) {
198 VBK_ASSERT_MSG(block.getHash() != block.getPreviousBlock(),
199 "Previous block hash should NOT be equal to the current block "
200 "hash: %s. A collision in altchain hash?",
205template <
typename Tree,
typename Pop>
206void payloadToCommands(Tree& tree,
208 const std::vector<uint8_t>& containingHash,
209 std::vector<CommandPtr>& cmds);
214template <
typename Tree,
typename Payload>
215void payloadToCommandGroup(Tree& tree,
216 const Payload& payload,
217 const std::vector<uint8_t>& containingHash,
224 cg.payload_type_name = &Payload::name();
225 cg.id = payload.getId().asVector();
227 payloadToCommands(tree, payload, containingHash, cg.commands);
231template <
typename Tree,
typename PayloadsT>
232std::vector<CommandGroup> payloadsToCommandGroups(
234 const PayloadsT& pop,
235 const std::vector<uint8_t>& containinghash);
238template <
typename Tree,
typename Pop>
239void vectorPopToCommandGroup(Tree& tree,
240 const std::vector<Pop>& pop,
241 const std::vector<uint8_t>& containingHash,
242 std::vector<CommandGroup>& cgs) {
243 for (
const auto& b : pop) {
245 cg.payload_type_name = &Pop::name();
246 cg.id = b.getId().asVector();
247 payloadToCommands(tree, b, containingHash, cg.commands);
249 cgs.push_back(std::move(cg));
254template <
typename BlockTree>
255bool areOnSameChain(
const typename BlockTree::block_t& blk1,
256 const typename BlockTree::block_t& blk2,
257 const BlockTree& tree) {
258 auto* blk_index1 = tree.getBlockIndex(blk1.getHash());
259 auto* blk_index2 = tree.getBlockIndex(blk2.getHash());
261 VBK_ASSERT_MSG(blk_index1,
"unknown block %s", blk1.toPrettyString());
262 VBK_ASSERT_MSG(blk_index2,
"unknown block %s", blk2.toPrettyString());
264 if (blk_index1->getHeight() > blk_index2->getHeight()) {
265 return blk_index1->getAncestor(blk_index2->getHeight()) == blk_index2;
267 return blk_index2->getAncestor(blk_index1->getHeight()) == blk_index1;
std::string HexStr(const T itbegin, const T itend)
Convert bytes to hex.