bool SysTestBase::GetRegID(string& strAddr,CRegID& regID) { CAccount account; CKeyID keyid; if (!GetKeyId(strAddr, keyid)) { return false; } CUserID userId = keyid; LOCK(cs_main); CAccountViewCache accView(*pAccountViewTip, true); if (!accView.GetAccount(userId, account)) { return false; } if((!account.IsRegister())||account.regID.IsEmpty()) { return false; } regID = account.regID; return true; }
bool CreatePosTx(const CBlockIndex *pPrevIndex, CBlock *pBlock, set<CKeyID>&setCreateKey, CAccountViewCache &view, CTransactionDBCache &txCache, CScriptDBViewCache &scriptCache) { set<CKeyID> setKeyID; setKeyID.clear(); set<CAccount, CAccountComparator> setAcctInfo; { LOCK2(cs_main, pwalletMain->cs_wallet); if((unsigned int)(chainActive.Tip()->nHeight + 1) != pBlock->GetHeight()) return false; pwalletMain->GetKeys(setKeyID, true); // first:get keyID from pwalletMain if (setKeyID.empty()) { return ERRORMSG("CreatePosTx setKeyID empty"); } LogPrint("INFO","CreatePosTx block time:%d\n", pBlock->GetTime()); for(const auto &keyid:setKeyID) { //second:get account by keyID //find CAccount info by keyid if(setCreateKey.size()) { bool bfind = false; for(auto &item: setCreateKey){ if(item == keyid){ bfind = true; break; } } if (!bfind) continue; } CUserID userId = keyid; CAccount acctInfo; if (view.GetAccount(userId, acctInfo)) { // check acctInfo is or not allowed to mining , //available // LogPrint("miner", "account info:regid=%s keyid=%s ncoinday=%lld isMiner=%d\n", acctInfo.regID.ToString(), // acctInfo.keyID.ToString(), acctInfo.GetAccountPos(pBlock->nHeight), acctInfo.IsMiner(pBlock->nHeight)); if (acctInfo.IsRegister() && acctInfo.GetAccountPos(pBlock->GetHeight()) > 0 && acctInfo.IsMiner(pBlock->GetHeight())) { setAcctInfo.insert(std::move(acctInfo)); // LogPrint("miner", "miner account info:%s\n", acctInfo.ToString()); } } } } if (setAcctInfo.empty()) { setCreateKey.clear(); LogPrint("INFO", "CreatePosTx setSecureAcc empty"); return false; } uint64_t maxNonce = SysCfg().GetBlockMaxNonce(); //cacul times uint256 prevblockhash = pPrevIndex->GetBlockHash(); const uint256 targetHash = CBigNum().SetCompact(pBlock->GetBits()).getuint256(); //target hash difficult set<CAccount, CAccountComparator>::iterator iterAcct = setAcctInfo.begin(); for (;iterAcct!=setAcctInfo.end();++iterAcct) { //third: 根据不同的账户 ,去计算挖矿 CAccount &item = const_cast<CAccount&>(*iterAcct); uint64_t posacc = item.GetAccountPos(pBlock->GetHeight()); if (0 == posacc) { //have no pos LogPrint("ERROR", "CreatePosTx posacc zero\n"); continue; } LogPrint("miner", "miner account:%s\n", item.ToString()); // LogPrint("INFO", "target hash:%s\n", targetHash.ToString()); // LogPrint("INFO", "posacc:%d\n", posacc); uint256 adjusthash = GetAdjustHash(targetHash, posacc, pBlock->GetHeight()-1); //adjust nbits // LogPrint("INFO", "adjusthash:%s\n", adjusthash.ToString()); //need compute this block proofofwork struct PosTxInfo postxinfo; postxinfo.nVersion = pBlock->GetVersion(); postxinfo.hashPrevBlock = prevblockhash; postxinfo.hashMerkleRoot = item.GetHash(); postxinfo.nValues = item.llValues; postxinfo.nHeight = pBlock->GetHeight(); postxinfo.nFuel = pBlock->GetFuel(); postxinfo.nFuelRate = pBlock->GetFuelRate(); postxinfo.nTime = pBlock->GetTime(); //max(pPrevIndex->GetMedianTimePast() + 1, GetAdjustedTime()); unsigned int nNonce = 0; for (; nNonce < maxNonce; ++nNonce) { //循环的 更改随机数,计算curhash看是否满足 postxinfo.nNonce = nNonce; pBlock->SetNonce(nNonce); uint256 curhash = postxinfo.GetHash(); if (UintToArith256(curhash) <= UintToArith256(adjusthash)) { CRegID regid; if (pAccountViewTip->GetRegId(item.keyID, regid)) { CRewardTransaction *prtx = (CRewardTransaction *) pBlock->vptx[0].get(); prtx->account = regid; //存矿工的 账户ID prtx->nHeight = pPrevIndex->nHeight+1; pBlock->SetHashMerkleRoot(pBlock->BuildMerkleTree()); pBlock->SetHashPos(curhash); LogPrint("INFO", "find pos tx hash succeed: \n" " pos hash:%s \n" "adjust hash:%s \r\n", curhash.GetHex(), adjusthash.GetHex()); vector<unsigned char> vSign; if (pwalletMain->Sign(item.keyID, pBlock->SignatureHash(), vSign, item.MinerPKey.IsValid())) { LogPrint("INFO", "Create new block hash:%s\n", pBlock->GetHash().GetHex()); LogPrint("miner", "Miner account info:%s\n", item.ToString()); LogPrint("miner", "CreatePosTx block hash:%s, postxinfo:%s\n",pBlock->GetHash().GetHex(), postxinfo.ToString().c_str()); pBlock->SetSignature(vSign); return true; } else { LogPrint("ERROR", "sign fail\r\n"); } } else { LogPrint("ERROR", "GetKey fail or GetVec6 fail\r\n"); } } } } return false; }