#include "kernel_worker.h"
#include "txdb.h"
-extern uint32_t nStakeMaxAge;
extern uint32_t nStakeTargetSpacing;
using namespace std;
+uint32_t nStakeMinAge = 30 * nOneDay; // 30 days as zero time weight
+uint32_t nStakeMaxAge = 90 * nOneDay; // 90 days as full weight
+
// Protocol switch time for fixed kernel modifier interval
uint32_t nModifierSwitchTime = 1413763200; // Mon, 20 Oct 2014 00:00:00 GMT
uint32_t nModifierTestSwitchTime = 1397520000; // Tue, 15 Apr 2014 00:00:00 GMT
const auto *pindex = pindexPrev;
while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart)
{
- vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash()));
+ vSortedByTimestamp.push_back({ pindex->GetBlockTime(), pindex->GetBlockHash() });
pindex = pindex->pprev;
}
int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0;
// write the entropy bit of the selected block
nStakeModifierNew |= (((uint64_t)pindex->GetStakeEntropyBit()) << nRound);
// add the selected block from candidates to selected list
- mapSelectedBlocks.insert(make_pair(pindex->GetBlockHash(), pindex));
+ mapSelectedBlocks.insert({ pindex->GetBlockHash(), pindex });
if (fDebug && GetBoolArg("-printstakemodifier"))
printf("ComputeNextStakeModifier: selected round %d stop=%s height=%d bit=%d\n", nRound, DateTimeStrFormat(nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit());
}
// The stake modifier used to hash for a stake kernel is chosen as the stake
// modifier about a selection interval later than the coin generating the kernel
-static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
+static bool GetKernelStakeModifier(const uint256 &hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
{
nStakeModifier = 0;
if (!mapBlockIndex.count(hashBlockFrom))
return true;
}
-bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier)
+bool GetKernelStakeModifier(const uint256 &hashBlockFrom, uint64_t& nStakeModifier)
{
int nStakeModifierHeight;
int64_t nStakeModifierTime;
// Scan given kernel for solution
bool ScanKernelForward(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, pair<uint32_t, uint32_t> &SearchInterval, vector<pair<uint256, uint32_t> > &solutions)
{
- // TODO: custom threads amount
-
- uint32_t nThreads = boost::thread::hardware_concurrency();
- uint32_t nPart = (SearchInterval.second - SearchInterval.first) / nThreads;
-
+ solutions.clear();
+ {
+ using namespace boost;
- KernelWorker *workers = new KernelWorker[nThreads];
+ auto nThreads = boost::thread::hardware_concurrency();
+ if (nThreads == 0) {
+ nThreads = 1;
+ printf("Warning: hardware_concurrency() failed in %s:%d\n", __FILE__, __LINE__);
+ }
+ auto vWorkers = vector<KernelWorker>(nThreads);
+ auto nPart = (SearchInterval.second - SearchInterval.first) / nThreads;
+ thread_group group;
- boost::thread_group group;
- for(size_t i = 0; i < nThreads; i++)
- {
- uint32_t nBegin = SearchInterval.first + nPart * i;
- uint32_t nEnd = SearchInterval.first + nPart * (i + 1);
- workers[i] = KernelWorker(kernel, nBits, nInputTxTime, nValueIn, nBegin, nEnd);
- boost::function<void()> workerFnc = boost::bind(&KernelWorker::Do, &workers[i]);
- group.create_thread(workerFnc);
- }
+ for(size_t i = 0; i < vWorkers.size(); i++)
+ {
+ auto nBegin = SearchInterval.first + nPart * i;
+ auto nEnd = SearchInterval.first + nPart * (i + 1);
- group.join_all();
- solutions.clear();
+ vWorkers[i] = KernelWorker(kernel, nBits, nInputTxTime, nValueIn, nBegin, nEnd);
+ auto workerFnc = bind(&KernelWorker::Do, &vWorkers[i]);
+ group.create_thread(workerFnc);
+ }
- for(size_t i = 0; i < nThreads; i++)
- {
- vector<pair<uint256, uint32_t> > ws = workers[i].GetSolutions();
- solutions.insert(solutions.end(), ws.begin(), ws.end());
- }
+ group.join_all();
- delete [] workers;
+ for(auto& worker : vWorkers)
+ {
+ auto ws = worker.GetSolutions();
+ solutions.insert(solutions.end(), ws.begin(), ws.end());
+ }
- if (solutions.size() == 0)
- {
- // no solutions
- return false;
+ return (solutions.size() != 0);
}
return true;
ss << pindex->nFlags << pindex->hashProofOfStake << pindex->nStakeModifier;
auto hashChecksum = Hash(ss.begin(), ss.end());
hashChecksum >>= (256 - 32);
- return static_cast<uint32_t>(hashChecksum.Get64());
+ return hashChecksum.Get32();
}
// Check stake modifier hard checkpoints
bool CheckStakeModifierCheckpoints(int nHeight, uint32_t nStakeModifierChecksum)
{
auto& checkpoints = (fTestNet ? mapStakeModifierCheckpointsTestNet : mapStakeModifierCheckpoints);
-
if (checkpoints.count(nHeight))
return nStakeModifierChecksum == checkpoints[nHeight];
return true;