veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
alt_chain_params.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_ALT_CHAIN_PARAMS_HPP_
7#define ALT_INTEGRATION_INCLUDE_VERIBLOCK_BLOCKCHAIN_ALT_CHAIN_PARAMS_HPP_
8
9#include <limits>
10#include <string>
11#include <vector>
12#include <veriblock/pop/blockchain/block_index.hpp>
13#include <veriblock/pop/entities/altblock.hpp>
14#include <veriblock/pop/serde.hpp>
15#include <veriblock/pop/validation_state.hpp>
16
17namespace altintegration {
18
26 double startOfSlope() const noexcept { return mStartOfSlope; }
27
30 double slopeNormal() const noexcept { return mSlopeNormal; }
31
33 double slopeKeystone() const noexcept { return mSlopeKeystone; }
34
37 uint32_t keystoneRound() const noexcept { return mKeystoneRound; }
38
41 uint32_t payoutRounds() const noexcept { return mPayoutRounds; }
42
45 uint32_t flatScoreRound() const noexcept { return mFlatScoreRound; }
46
48 bool useFlatScoreRound() const noexcept { return mUseFlatScoreRound; }
49
52 const std::vector<double>& roundRatios() const noexcept {
53 return mRoundRatios;
54 }
55
57 double maxScoreThresholdNormal() const noexcept {
58 return mMaxScoreThresholdNormal;
59 }
60
62 double maxScoreThresholdKeystone() const noexcept {
63 return mMaxScoreThresholdKeystone;
64 }
65
67 uint32_t difficultyAveragingInterval() const noexcept {
68 return mDifficultyAveragingInterval;
69 }
70
73 const std::vector<double>& relativeScoreLookupTable() const noexcept {
74 return mLookupTable;
75 }
76
78 int32_t getPopPayoutDelay() const noexcept { return mPopPayoutDelay; }
79
80 // it is public for C wrapper
81 public:
82 double mStartOfSlope = 1.0;
83 double mSlopeNormal = 0.2;
84 double mSlopeKeystone = 0.21325;
85 uint32_t mKeystoneRound = 3;
86 uint32_t mPayoutRounds = 4;
87 uint32_t mFlatScoreRound = 2;
88 bool mUseFlatScoreRound = true;
89 double mMaxScoreThresholdNormal = 2.0;
90 double mMaxScoreThresholdKeystone = 3.0;
91 uint32_t mDifficultyAveragingInterval = 50;
92 int32_t mPopPayoutDelay = 50;
93
94 std::vector<double> mRoundRatios{0.97, 1.03, 1.07, 3.00};
95
96 std::vector<double> mLookupTable{
97 1.00000000, 1.00000000, 1.00000000, 1.00000000, 1.00000000, 1.00000000,
98 1.00000000, 1.00000000, 1.00000000, 1.00000000, 1.00000000, 1.00000000,
99 0.48296816, 0.31551694, 0.23325824, 0.18453616, 0.15238463, 0.12961255,
100 0.11265630, 0.09955094, 0.08912509, 0.08063761, 0.07359692, 0.06766428,
101 0.06259873, 0.05822428, 0.05440941, 0.05105386, 0.04807993, 0.04542644,
102 0.04304458, 0.04089495, 0.03894540, 0.03716941, 0.03554497, 0.03405359,
103 0.03267969, 0.03141000, 0.03023319, 0.02913950, 0.02812047, 0.02716878,
104 0.02627801, 0.02544253, 0.02465739, 0.02391820, 0.02322107, 0.02256255,
105 0.02193952, 0.02134922};
106};
107
109template <typename JsonValue>
110JsonValue ToJSON(const PopPayoutsParams& p) {
111 auto obj = json::makeEmptyObject<JsonValue>();
112 json::putArrayKV(obj, "lookupTable", p.relativeScoreLookupTable());
113 json::putArrayKV(obj, "roundRatios", p.roundRatios());
114 json::putIntKV(
115 obj, "difficultyAveragingInterval", p.difficultyAveragingInterval());
116 json::putDoubleKV(
117 obj, "maxScoreThresholdKeystone", p.maxScoreThresholdKeystone());
118 json::putDoubleKV(
119 obj, "maxScoreThresholdNormal", p.maxScoreThresholdNormal());
120 json::putBoolKV(obj, "useFlatScoreRound", p.useFlatScoreRound());
121 json::putIntKV(obj, "flatScoreRound", p.flatScoreRound());
122 json::putIntKV(obj, "payoutRounds", p.payoutRounds());
123 json::putIntKV(obj, "keystoneRound", p.keystoneRound());
124 json::putDoubleKV(obj, "slopeKeystone", p.slopeKeystone());
125 json::putDoubleKV(obj, "slopeNormal", p.slopeNormal());
126 json::putDoubleKV(obj, "startOfSlope", p.startOfSlope());
127 json::putIntKV(obj, "popPayoutDelay", p.getPopPayoutDelay());
128 return obj;
129}
130
138 virtual ~AltChainParams() = default;
139
140 size_t maxWorkerQueueSize() const noexcept {
141 const auto ret = getMaxATVsInAltBlock() + getMaxVTBsInAltBlock() +
143 static const auto MAX = 400000;
144 VBK_ASSERT_MSG(ret < MAX,
145 "Worker size queue can not be more than %d, otherwise it "
146 "would take more than 50MB of RAM",
147 MAX);
148 return ret;
149 }
150
153 uint32_t getKeystoneInterval() const noexcept { return mKeystoneInterval; }
154
156 uint32_t getFinalityDelay() const noexcept { return mFinalityDelay; }
157
159 const std::vector<uint32_t>& getForkResolutionLookUpTable() const noexcept {
160 // TODO(warchant): this should be recalculated. see paper.
161 return mForkResolutionLookUpTable;
162 }
163
166 uint32_t getEndorsementSettlementInterval() const noexcept {
167 return mEndorsementSettlementInterval;
168 }
169
171 const PopPayoutsParams& getPayoutParams() const noexcept {
172 return *mPopPayoutsParams;
173 }
174
176 size_t getMaxVbkBlocksInAltBlock() const noexcept {
177 VBK_ASSERT(mMaxVbkBlocksInAltBlock <= MAX_POPDATA_VBK);
178 return mMaxVbkBlocksInAltBlock;
179 }
180
182 size_t getMaxVTBsInAltBlock() const noexcept {
183 VBK_ASSERT(mMaxVTBsInAltBlock <= MAX_POPDATA_VTB);
184 return mMaxVTBsInAltBlock;
185 }
186
188 size_t getMaxATVsInAltBlock() const noexcept {
189 VBK_ASSERT(mMaxATVsInAltBlock <= MAX_POPDATA_ATV);
190 return mMaxATVsInAltBlock;
191 }
192
194 size_t getMaxPopDataSize() const noexcept { return mMaxPopDataSize; }
195
197 uint32_t maxAltchainFutureBlockTime() const noexcept {
198 return mMaxAltchainFutureBlockTime;
199 }
200
205 int32_t getMaxReorgBlocks() const noexcept {
206 VBK_ASSERT(static_cast<int64_t>(mMaxReorgBlocks) >
207 static_cast<int64_t>(mEndorsementSettlementInterval));
208 return mMaxReorgBlocks;
209 }
210
215 uint32_t preserveBlocksBehindFinal() const noexcept {
216 VBK_ASSERT(mPreserveBlocksBehindFinal >= mEndorsementSettlementInterval);
217 return mPreserveBlocksBehindFinal;
218 }
219
221 virtual int64_t getIdentifier() const noexcept = 0;
222
228 virtual AltBlock getBootstrapBlock() const noexcept = 0;
229
239 virtual std::vector<uint8_t> getHash(
240 const std::vector<uint8_t>& bytes) const noexcept = 0;
241
256 virtual bool checkBlockHeader(const std::vector<uint8_t>& bytes,
257 const std::vector<uint8_t>& root,
258 ValidationState& state) const noexcept = 0;
259
260 public:
261 std::shared_ptr<PopPayoutsParams> mPopPayoutsParams =
262 std::make_shared<PopPayoutsParams>();
263
264 int32_t mMaxReorgBlocks = ALT_MAX_REORG_BLOCKS_MIN_VALUE; // blocks
265 uint32_t mMaxAltchainFutureBlockTime = 10 * 60; // 10 min
266 uint32_t mKeystoneInterval = 5;
267 uint32_t mFinalityDelay = 100;
268 uint32_t mEndorsementSettlementInterval = 50;
269 uint32_t mPreserveBlocksBehindFinal = mEndorsementSettlementInterval;
270 uint32_t mMaxPopDataSize = MAX_POPDATA_SIZE;
271
272 size_t mMaxVbkBlocksInAltBlock = 200;
273 size_t mMaxVTBsInAltBlock = 200;
274 size_t mMaxATVsInAltBlock = 1000;
275
276 std::vector<uint32_t> mForkResolutionLookUpTable{
277 100, 100, 95, 89, 80, 69, 56, 40, 21};
278};
279
281 AltChainParamsRegTest(int id = 0) : id(id) {}
282 ~AltChainParamsRegTest() override = default;
283
284 AltBlock getBootstrapBlock() const noexcept override {
285 AltBlock b;
286 b.hash = std::vector<uint8_t>(SHA256_HASH_SIZE, 1);
287 b.previousBlock = std::vector<uint8_t>(SHA256_HASH_SIZE, 0);
288 b.height = 0;
289 b.timestamp = 0;
290 return b;
291 }
292
293 int64_t getIdentifier() const noexcept override { return id; }
294
295 std::vector<uint8_t> getHash(
296 const std::vector<uint8_t>& bytes) const noexcept override {
297 return AssertDeserializeFromRaw<AltBlock>(bytes).getHash();
298 }
299
300 bool checkBlockHeader(const std::vector<uint8_t>& bytes,
301 const std::vector<uint8_t>&,
302 ValidationState& state) const noexcept override {
303 AltBlock block;
304 return DeserializeFromRaw<AltBlock>(bytes, block, state);
305 }
306
307 int64_t id = 0;
308};
309
311template <typename JsonValue>
312JsonValue ToJSON(const AltChainParams& p, bool reverseAltHashes = true) {
313 auto obj = json::makeEmptyObject<JsonValue>();
314 json::putIntKV(obj, "networkId", p.getIdentifier());
315 json::putArrayKV(
316 obj, "forkResolutionLookupTable", p.getForkResolutionLookUpTable());
317 json::putIntKV(obj, "maxVbkBlocksInAltBlock", p.getMaxVbkBlocksInAltBlock());
318 json::putIntKV(obj, "maxVTBsInAltBlock", p.getMaxVTBsInAltBlock());
319 json::putIntKV(obj, "maxATVsInAltBlock", p.getMaxATVsInAltBlock());
320 json::putIntKV(obj, "maxReorgBlocks", p.getMaxReorgBlocks());
321 json::putIntKV(obj,
322 "endorsementSettlementInterval",
324 json::putIntKV(obj, "finalityDelay", p.getFinalityDelay());
325 json::putIntKV(obj, "keystoneInterval", p.getKeystoneInterval());
326 json::putIntKV(
327 obj, "maxAltchainFutureBlockTime", p.maxAltchainFutureBlockTime());
328 json::putKV(obj, "payoutParams", ToJSON<JsonValue>(p.getPayoutParams()));
329 json::putKV(obj,
330 "bootstrapBlock",
331 ToJSON<JsonValue>(p.getBootstrapBlock(), reverseAltHashes));
332 return obj;
333}
334
335} // namespace altintegration
336
337#endif
Class that is used for storing validation state.
Defines logging helpers.
Definition: block.hpp:14
constexpr const auto MAX_POPDATA_ATV
absolute maximum number of ATV blocks per ALT block
Definition: consts.hpp:82
static const int32_t ALT_MAX_REORG_BLOCKS_MIN_VALUE
minimum number of blocks in ALT tree
Definition: consts.hpp:128
constexpr const auto SHA256_HASH_SIZE
sha256 hash size
Definition: consts.hpp:39
constexpr const auto MAX_POPDATA_VBK
absolute maximum number of VBK blocks per ALT block
Definition: consts.hpp:78
constexpr const auto MAX_POPDATA_SIZE
maximum size of single PopData in a single ALT block, in bytes.
Definition: consts.hpp:76
constexpr const auto MAX_POPDATA_VTB
absolute maximum number of VTB blocks per ALT block
Definition: consts.hpp:80
Represents a view on Altchain block - i.e.
Definition: altblock.hpp:29
std::vector< uint8_t > getHash(const std::vector< uint8_t > &bytes) const noexcept override
Calculate hash from block header.
AltBlock getBootstrapBlock() const noexcept override
"genesis" block for POP mining.
int64_t getIdentifier() const noexcept override
unique POP ID for the chain; identifies altchain in VBK
bool checkBlockHeader(const std::vector< uint8_t > &bytes, const std::vector< uint8_t > &, ValidationState &state) const noexcept override
Returns true if input bytes:
Base class for all Altchain-related configs.
const std::vector< uint32_t > & getForkResolutionLookUpTable() const noexcept
pop score lookup table for fork resolution
uint32_t getKeystoneInterval() const noexcept
number of blocks in single keystone interval.
uint32_t maxAltchainFutureBlockTime() const noexcept
Maximum future block time for altchain blocks.
virtual std::vector< uint8_t > getHash(const std::vector< uint8_t > &bytes) const noexcept=0
Calculate hash from block header.
size_t getMaxVTBsInAltBlock() const noexcept
total maximum number of VTBs per 1 ALT block
size_t getMaxPopDataSize() const noexcept
maximum size (in bytes) of single PopData per single ALT block
size_t getMaxATVsInAltBlock() const noexcept
total maximum number of ATVs per 1 ALT block
virtual AltBlock getBootstrapBlock() const noexcept=0
"genesis" block for POP mining.
const PopPayoutsParams & getPayoutParams() const noexcept
getter for reward parameters
uint32_t preserveBlocksBehindFinal() const noexcept
when finalizeBlockImpl is called, this many blocks behind final block will be preserved in RAM.
uint32_t getFinalityDelay() const noexcept
number of blocks in VBK used for finalization
virtual int64_t getIdentifier() const noexcept=0
unique POP ID for the chain; identifies altchain in VBK
size_t getMaxVbkBlocksInAltBlock() const noexcept
total maximum number of VBK blocks per 1 ALT block
int32_t getMaxReorgBlocks() const noexcept
Max number of blocks that can be reorganized in altchain.
uint32_t getEndorsementSettlementInterval() const noexcept
Validity window for ATVs.
virtual bool checkBlockHeader(const std::vector< uint8_t > &bytes, const std::vector< uint8_t > &root, ValidationState &state) const noexcept=0
Returns true if input bytes:
Defines config for POP payouts.
double maxScoreThresholdKeystone() const noexcept
limit block with keystones score to this value
uint32_t payoutRounds() const noexcept
total number of payout rounds.
bool useFlatScoreRound() const noexcept
should we use flat rewards at all
int32_t getPopPayoutDelay() const noexcept
number of blocks in ALT between endorsed block and payout block
uint32_t flatScoreRound() const noexcept
we use this round number to pay flat reward (does not depend on pop difficulty)
double slopeKeystone() const noexcept
slope for keystone rounds
const std::vector< double > & roundRatios() const noexcept
we have these payout modifiers for different rounds.
const std::vector< double > & relativeScoreLookupTable() const noexcept
reward score table we score each VeriBlock and lower the reward for late blocks
double startOfSlope() const noexcept
we start decreasing rewards after this score
uint32_t difficultyAveragingInterval() const noexcept
collect this amount of blocks BEFORE the block to calculate pop difficulty
uint32_t keystoneRound() const noexcept
among all rounds, this number represents round for keystone blocks.
double slopeNormal() const noexcept
we decrease reward coefficient for this value for each additional score point above startOfDecreasing...
double maxScoreThresholdNormal() const noexcept
limit block score to this value