9 #include "validation.h"
15 static const unsigned int MODIFIER_INTERVAL = 60;
16 static const int MODIFIER_INTERVAL_RATIO = 3;
17 static const int64_t OLD_MODIFIER_INTERVAL = 2087;
20 static int64_t GetStakeModifierSelectionIntervalSection(
int nSection)
22 assert(nSection >= 0 && nSection < 64);
23 int64_t a = MODIFIER_INTERVAL * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1)));
30 static bool SelectBlockFromCandidates(
31 std::vector<std::pair<int64_t, uint256> >& vSortedByTimestamp,
32 std::map<uint256, const CBlockIndex*>& mapSelectedBlocks,
33 int64_t nSelectionIntervalStop,
34 uint64_t nStakeModifierPrev,
37 bool fModifierV2 =
false;
38 bool fFirstRun =
true;
39 bool fSelected =
false;
42 for (
const auto& item : vSortedByTimestamp) {
44 return error(
"%s : failed to find block index for candidate block %s", __func__, item.second.ToString().c_str());
47 if (fSelected && pindex->
GetBlockTime() > nSelectionIntervalStop)
67 ss << hashProof << nStakeModifierPrev;
76 if (fSelected && hashSelection < hashBest) {
77 hashBest = hashSelection;
79 }
else if (!fSelected) {
81 hashBest = hashSelection;
105 }
while (nStakeModifierTime < pindexFrom->GetBlockTime() + OLD_MODIFIER_INTERVAL);
114 if (!pindexFrom)
return error(
"%s : failed to get index from", __func__);
117 const int nHeightStop = std::min(
chainActive.
Height(),
Params().GetConsensus().height_last_ZC_AccumCheckpoint-1);
118 while (pindexFrom && pindexFrom->
nHeight + 1 <= nHeightStop) {
119 if (pindexFrom->
GetBlockTime() - nTimeBlockFrom > 60 * 60) {
128 return error(
"%s : failed to get kernel stake modifier", __func__);
134 static bool sortedByTimestamp(
const std::pair<uint64_t, uint256>& a,
135 const std::pair<uint64_t, uint256>& b)
137 if (a.first == b.first) {
140 return a.first < b.first;
159 fGeneratedStakeModifier =
false;
162 fGeneratedStakeModifier =
true;
165 if (pindexPrev->
nHeight == 0) {
167 fGeneratedStakeModifier =
true;
168 nStakeModifier = uint64_t(
"stakemodifier");
174 int64_t nModifierTime = 0;
181 if (nModifierTime / MODIFIER_INTERVAL >= pindexPrev->
GetBlockTime() / MODIFIER_INTERVAL)
185 std::vector<std::pair<int64_t, uint256> > vSortedByTimestamp;
186 vSortedByTimestamp.reserve(64 * MODIFIER_INTERVAL /
Params().GetConsensus().nTargetSpacing);
187 int64_t nSelectionIntervalStart = (pindexPrev->
GetBlockTime() / MODIFIER_INTERVAL ) * MODIFIER_INTERVAL - OLD_MODIFIER_INTERVAL;
190 while (pindex && pindex->
GetBlockTime() >= nSelectionIntervalStart) {
192 pindex = pindex->
pprev;
195 std::reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end());
196 std::sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end(), sortedByTimestamp);
199 uint64_t nStakeModifierNew = 0;
200 int64_t nSelectionIntervalStop = nSelectionIntervalStart;
201 std::map<uint256, const CBlockIndex*> mapSelectedBlocks;
202 for (
int nRound = 0; nRound < std::min(64, (
int)vSortedByTimestamp.size()); nRound++) {
204 nSelectionIntervalStop += GetStakeModifierSelectionIntervalSection(nRound);
207 if (!SelectBlockFromCandidates(vSortedByTimestamp, mapSelectedBlocks, nSelectionIntervalStop, nStakeModifier, &pindex))
208 return error(
"%s : unable to select block at round %d", __func__, nRound);
214 mapSelectedBlocks.emplace(pindex->
GetBlockHash(), pindex);
217 nStakeModifier = nStakeModifierNew;
218 fGeneratedStakeModifier =
true;
arith_uint256 UintToArith256(const uint256 &a)
const arith_uint256 ARITH_UINT256_ZERO
const CChainParams & Params()
Return the currently selected parameters.
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
unsigned int GetStakeEntropyBit() const
bool IsProofOfStake() const
bool GeneratedStakeModifier() const
uint256 nAccumulatorCheckpoint
uint256 GetBlockHash() const
int64_t GetBlockTime() const
int nHeight
height of the entry in the chain. The genesis block has height 0
const uint256 * phashBlock
pointer to the hash of the block, if any. memory is owned by this CBlockIndex
uint64_t GetStakeModifierV1() const
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
int Height() const
Return the maximal height in the chain.
const Consensus::Params & GetConsensus() const
256-bit unsigned big integer.
std::string GetHex() const
uint64_t GetCheapHash() const
A cheap hash function that just returns 64 bits from the result, it can be used when the contents are...
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
bool GetOldModifier(const CBlockIndex *pindexFrom, uint64_t &nStakeModifier)
bool GetOldStakeModifier(CStakeInput *stake, uint64_t &nStakeModifier)
bool ComputeNextStakeModifier(const CBlockIndex *pindexPrev, uint64_t &nStakeModifier, bool &fGeneratedStakeModifier)
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const
Returns true if the given network upgrade is active as of the given block height.
bool error(const char *fmt, const Args &... args)
const uint256 UINT256_ZERO
constant uint256 instances
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).