MCPcopy Create free account
hub / github.com/LUX-Core/lux / ComputeNextModifier

Method ComputeNextModifier

src/stake.cpp:234–335  ·  view source on GitHub ↗

Stake Modifier (hash modifier of proof-of-stake): The purpose of stake modifier is to prevent a txout (coin) owner from computing future proof-of-stake generated by this txout at the time of transaction confirmation. To meet kernel protocol, the txout must hash with a future stake modifier to generate the proof. Stake modifier consists of bits each of which is contributed from a selected block of

Source from the content-addressed store, hash-verified

232// additional bits in the stake modifier, even after generating a chain of
233// blocks.
234bool Stake::ComputeNextModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier) {
235 nStakeModifier = 0;
236 fGeneratedStakeModifier = false;
237
238 if (!pindexPrev) {
239 fGeneratedStakeModifier = true;
240 return true; // genesis block's modifier is 0
241 }
242
243 if (pindexPrev->nHeight == 0) {
244 //Give a stake modifier to the first block
245 fGeneratedStakeModifier = true;
246 nStakeModifier = uint64_t("stakemodifier");
247 return true;
248 }
249
250 // First find current stake modifier and its generation block time
251 // if it's not old enough, return the same stake modifier
252 int64_t nModifierTime = 0;
253 if (!GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime))
254 return error("%s: unable to get last modifier", __func__);
255
256# if defined(DEBUG_DUMP_STAKING_INFO) && false
257 if (GetBoolArg("-printstakemodifier", false))
258 LogPrintf("%s: last modifier=%d time=%d\n", __func__, nStakeModifier, nModifierTime); // DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nModifierTime)
259# endif
260
261 auto const nPrevRounds = pindexPrev->GetBlockTime() / GetInterval();
262 if (nModifierTime / GetInterval() >= nPrevRounds)
263 return true;
264
265 // Sort candidate blocks by timestamp
266 vector< pair<int64_t, uint256> > vSortedCandidates;
267 vSortedCandidates.reserve(64 * GetInterval() / GetTargetSpacing(pindexPrev->nHeight));
268
269 int64_t nSelectionTime = nPrevRounds * GetInterval() - GetSelectionTime();
270 const CBlockIndex* pindex = pindexPrev;
271 while (pindex && pindex->GetBlockTime() >= nSelectionTime) {
272 if (pindex->IsProofOfStake() && pindex->hashProofOfStake == 0) {
273 return error("%s: zero stake block %s", __func__, pindex->GetBlockHash().GetHex());
274 }
275 vSortedCandidates.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash()));
276 pindex = pindex->pprev;
277 }
278
279# if defined(DEBUG_DUMP_STAKING_INFO) && false
280 int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0;
281# endif
282
283 //reverse(vSortedCandidates.begin(), vSortedCandidates.end());
284 sort(vSortedCandidates.begin(), vSortedCandidates.end());
285
286 // Select 64 blocks from candidate blocks to generate stake modifier
287 uint64_t nStakeModifierNew = 0;
288 map<uint256, const CBlockIndex*> mSelectedBlocks;
289 for (int nRound = 0; nRound < min(64, int(vSortedCandidates.size())); nRound++) {
290 // add an interval section to the current selection round
291 nSelectionTime += GetSelectionInterval(nRound);

Callers 1

AddToBlockIndexFunction · 0.80

Calls 15

GetLastStakeModifierFunction · 0.85
errorFunction · 0.85
GetBoolArgFunction · 0.85
GetIntervalFunction · 0.85
GetTargetSpacingFunction · 0.85
GetSelectionTimeFunction · 0.85
GetSelectionIntervalFunction · 0.85
GetStakeEntropyBitMethod · 0.80
replaceMethod · 0.80
GetBlockTimeMethod · 0.45
reserveMethod · 0.45

Tested by

no test coverage detected