// darksilk: attempt to generate suitable proof-of-stake bool CBlock::SignBlock(CWallet& wallet, CAmount nFees) { // if we are trying to sign // something except proof-of-stake block template if (!vtx[0].vout[0].IsEmpty()) return false; // if we are trying to sign // a complete proof-of-stake block if (IsProofOfStake()) return true; static int64_t nLastCoinStakeSearchTime = GetAdjustedTime(); // startup timestamp CKey key; CTransaction txCoinStake; txCoinStake.nTime &= ~STAKE_TIMESTAMP_MASK; int64_t nSearchTime = txCoinStake.nTime; // search to current time if (nSearchTime > nLastCoinStakeSearchTime) { int64_t nSearchInterval = 1; if (wallet.CreateCoinStake(wallet, nBits, nSearchInterval, nFees, txCoinStake, key)) { if (txCoinStake.nTime >= pindexBest->GetPastTimeLimit()+1) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp vtx[0].nTime = nTime = txCoinStake.nTime; // we have to make sure that we have no future timestamps in // our transactions set for (vector<CTransaction>::iterator it = vtx.begin(); it != vtx.end();) if (it->nTime > nTime) { it = vtx.erase(it); } else { ++it; } vtx.insert(vtx.begin() + 1, txCoinStake); hashMerkleRoot = BuildMerkleTree(); // append a signature to our block return key.Sign(GetHash(), vchBlockSig); } } nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; nLastCoinStakeSearchTime = nSearchTime; } return false; }