uint32_t nIntervalEnd;
};
-// Scan given midstate for solution
-bool ScanMidstateForward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::vector<std::pair<uint256, uint32_t> > &solutions)
+// Scan given kernel for solution
+bool ScanKernelForward(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::vector<std::pair<uint256, uint32_t> > &solutions)
{
// TODO: custom threads amount
uint32_t nThreads = boost::thread::hardware_concurrency();
uint32_t nPart = (SearchInterval.second - SearchInterval.first) / nThreads;
+ // Init new sha256 context and update it
+ // with first 24 bytes of kernel
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, kernel, 8 + 16);
+
ScanMidstateWorker *workers = new ScanMidstateWorker[nThreads];
boost::thread_group group;
}
// Scan given midstate for solution
-bool ScanMidstateBackward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::pair<uint256, uint32_t> &solution)
+bool ScanContextBackward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::pair<uint256, uint32_t> &solution)
{
CBigNum bnTargetPerCoinDay;
bnTargetPerCoinDay.SetCompact(nBits);
// Sets hashProofOfStake on success return
bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, uint32_t nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, uint32_t nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake=false);
-// Precompute hashing state for static part of kernel
-void GetKernelMidstate(uint64_t nStakeModifier, uint32_t nBlockTime, uint32_t nTxOffset, uint32_t nInputTxTime, uint32_t nOut, SHA256_CTX &ctx);
+// Scan given kernel for solutions
+bool ScanKernelForward(unsigned char *kernel, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::vector<std::pair<uint256, uint32_t> > &solutions);
-// Scan given midstate for kernel solutions
-bool ScanMidstateForward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::vector<std::pair<uint256, uint32_t> > &solutions);
-bool ScanMidstateBackward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::pair<uint256, uint32_t> &solution);
+// Scan given context for kernel solutions
+bool ScanContextBackward(SHA256_CTX &ctx, uint32_t nBits, uint32_t nInputTxTime, int64_t nValueIn, std::pair<uint32_t, uint32_t> &SearchInterval, std::pair<uint256, uint32_t> &solution);
// Check kernel hash target and coinstake signature
// Sets hashProofOfStake on success return
// (txid, vout.n) => (SHA256_CTX, (tx.nTime, nAmount))
typedef std::map<std::pair<uint256, unsigned int>, std::pair<SHA256_CTX, std::pair<uint32_t, uint64_t> > > MidstateMap;
-// Fill the inputs map with precalculated states and metadata
+// Fill the inputs map with precalculated contexts and metadata
bool FillMap(CWallet *pwallet, uint32_t nUpperTime, MidstateMap &inputsMap)
{
// Choose coins to use
if (nStakeMinAge + block.nTime > nTime - nMaxStakeSearchInterval)
continue;
+ // Get stake modifier
uint64_t nStakeModifier = 0;
if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
continue;
+ // Build static part of kernel
+ CDataStream ssKernel(SER_GETHASH, 0);
+ ssKernel << nStakeModifier;
+ ssKernel << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << pcoin->first->nTime << pcoin->second;
+ CDataStream::const_iterator itK = ssKernel.begin();
+
+ // Init new sha256 context and update it
+ // with first 24 bytes of kernel
SHA256_CTX ctx;
- // Calculate midstate using (modifier, block time, tx offset, tx time, output number)
- GetKernelMidstate(nStakeModifier, block.nTime, txindex.pos.nTxPos - txindex.pos.nBlockPos, pcoin->first->nTime, pcoin->second, ctx);
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, (unsigned char*)&itK[0], 8 + 16);
// (txid, vout.n) => (SHA256_CTX, (tx.nTime, nAmount))
inputsMap[key] = make_pair(ctx, make_pair(pcoin->first->nTime, pcoin->first->vout[pcoin->second].nValue));
nStakeInputsMapSize = inputsMap.size();
if (fDebug)
- printf("Stake miner: map of %" PRIu64 " precalculated contexts has been created\n", nStakeInputsMapSize);
+ printf("FillMap() : Map of %" PRIu64 " precalculated contexts has been created by stake miner\n", nStakeInputsMapSize);
}
return true;
SHA256_CTX ctx = input->second.first;
// scan(State, Bits, Time, Amount, ...)
- if (ScanMidstateBackward(ctx, nBits, input->second.second.first, input->second.second.second, interval, solution))
+ if (ScanContextBackward(ctx, nBits, input->second.second.first, input->second.second.second, interval, solution))
{
// Solution found
LuckyInput = input->first; // (txid, nout)
interval.first += (nStakeMinAge + block.nTime - interval.first);
interval.second = interval.first + nDays * 86400;
- SHA256_CTX ctx;
- GetKernelMidstate(nStakeModifier, block.nTime, txindex.pos.nTxPos - txindex.pos.nBlockPos, tx.nTime, nOut, ctx);
+ // Build static part of kernel
+ CDataStream ssKernel(SER_GETHASH, 0);
+ ssKernel << nStakeModifier;
+ ssKernel << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << tx.nTime << nOut;
+ CDataStream::const_iterator itK = ssKernel.begin();
std::vector<std::pair<uint256, uint32_t> > solutions;
- if (ScanMidstateForward(ctx, nBits, tx.nTime, tx.vout[nOut].nValue, interval, solutions))
+ if (ScanKernelForward((unsigned char *)&itK[0], nBits, tx.nTime, tx.vout[nOut].nValue, interval, solutions))
{
- Array sols;
+ Array results;
BOOST_FOREACH(const PAIRTYPE(uint256, uint32_t) solution, solutions)
{
- Object r;
- r.push_back(Pair("hash", solution.first.GetHex()));
- r.push_back(Pair("time", DateTimeStrFormat(solution.second)));
+ Object item;
+ item.push_back(Pair("hash", solution.first.GetHex()));
+ item.push_back(Pair("time", DateTimeStrFormat(solution.second)));
- sols.push_back(r);
+ results.push_back(item);
}
- return sols;
+ return results;
}
}
else