//Get the memory location referenced by block //Return NULL for invalid block descriptor static void* getBlockPtr(Block b) { void* ptr = (void*) megMap; if(!validBlock(b)) return NULL; int level = getBlockLevel(b); for(int i = 0; i <= level; i++) { //For each level, add the offset for table as well as the memory for //blocks before this one ptr += subblockStart[i]; ptr += b.levels[i] * blockSize[i]; } return ptr; }
//Return a BlockStatus value or -1 on error static int getBlockStatus(Block b) { if(!validBlock(b)) return -1; int level = getBlockLevel(b); byte* table; //start of table for parent blocks, or top-level block. byte mask = 0b11; int shift; //set table to address of block status bitmap of parent if(level == 0) table = (byte*) megMap; else table = (byte*) getBlockPtr(getParentBlock(b)); int baseIndex = b.levels[level]; byte entry = *(table + (baseIndex / 4)); //2 bits per entry shift = 6 - (2 * (baseIndex % 4)); //trust me it works return (entry & (mask << shift)) >> shift; }
static bool allocBlocks(int level, int numBlocks, Block* result) { //printf("Allocating %d blocks at level %d\n", numBlocks, level); if(level == 0) { //printf(" Will attempt to find top-level group of %d blocks.\n", numBlocks); return findTopLevelGroup(numBlocks, result); } //Need to find subblock(s) //Best to worst options: //-Use same parent block from last allocation //-Allocate new parent block somewhere else //-Depth-first search subdivided blocks looking for free blocks //-Return false //First try lastParents int bestOvershootParent = -1; int bestOvershoot = 0xFFFF; int overshoot = 0; for(int i = 0; i < PARENT_SAVES; i++) { if(validBlock(lastParents[level][i])) { if(findGroupInBlock(lastParents[level][i], numBlocks, result, &overshoot)) { if(overshoot < bestOvershoot) { bestOvershoot = overshoot; bestOvershootParent = i; } } } } if(bestOvershootParent != -1) { Block use = lastParents[level][bestOvershootParent]; if(!findGroupInBlock(use, numBlocks, result, NULL)) { //This should never ever happen //puts("VERY FATAL ERROR: CHECK FOUND LAST_PARENT CASE"); return false; } //puts("Allocation successful via lastParents"); //printf("Resulting block group: "); //printBlock(*result); //puts(""); allocGroup(*result, numBlocks); return true; } //lastParents must be updated //If one is not yet valid, set it to a newly allocated block //Immediately use subblocks of that new block to fulfill current request //puts("Did not find good cached parent block."); bool allValid = true; Block* toReplace; for(int i = 0; i < PARENT_SAVES; i++) { if(!validBlock(lastParents[level][i])) { allValid = false; toReplace = &lastParents[level][i]; break; } } if(!allValid) { bool success = replaceParentSave(toReplace, level - 1); if(success) { //use *toReplace (now a fresh subdivded block) as parent *result = getFirstSubblock(*toReplace); allocGroup(*result, numBlocks); //puts("Allocation successful via newParent"); return true; } } else { int worstGroup = 100; int worstBlock = -1; for(int i = 0; i < PARENT_SAVES; i++) { int thisGroup = getMaxGroup(lastParents[level][i]); if(thisGroup < worstGroup) { worstGroup = thisGroup; worstBlock = i; } } toReplace = &lastParents[level][worstBlock]; //replace worstBlock bool success = replaceParentSave(toReplace, level - 1); if(success) { *result = getFirstSubblock(*toReplace); allocGroup(*result, numBlocks); return true; //puts("Allocation sucessful via new parent."); } } //If here, then depth-first search for an appropriate parent block //that isn't necesarily listed in lastParent. Block first; for(int i = 0; i < numSubblocks[0]; i++) { Block topLevel = {{i, -1, -1, -1}}; if(getBlockStatus(topLevel) == SUBDIV) { if(groupSearch(level, numBlocks, topLevel, &first)) { *result = first; allocGroup(*result, numBlocks); return true; //puts("Allocation successful via worst-case dfs for parent"); } } } //puts("Block group allocation failed!"); return false; }
// partly copied from https://github.com/zcash/zcash/blob/master/src/miner.cpp#L581 bool equihash_(std::string solver, CBlock *pblock, int n, int k) { arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); // Hash state crypto_generichash_blake2b_state state; EhInitialiseState(n, k, state); // I = the block header minus nonce and solution. CEquihashInput I{*pblock}; CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << I; // H(I||... crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size()); // H(I||V||... crypto_generichash_blake2b_state curr_state; curr_state = state; crypto_generichash_blake2b_update(&curr_state, pblock->nNonce.begin(), pblock->nNonce.size()); // (x_1, x_2, ...) = A(I, V, n, k) LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n", solver, pblock->nNonce.ToString()); std::function<bool(std::vector<unsigned char>)> validBlock = [&pblock, &hashTarget](std::vector<unsigned char> soln) { // Write the solution to the hash and compute the result. pblock->nSolution = soln; if (UintToArith256(pblock->GetHash()) > hashTarget) { return false; } // Found a solution LogPrintf("CMMMiner:\n"); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex()); return true; }; if (solver == "tromp") { // Create solver and initialize it. equi eq(1); eq.setstate(&curr_state); // Intialization done, start algo driver. eq.digit0(0); eq.xfull = eq.bfull = eq.hfull = 0; eq.showbsizes(0); for (u32 r = 1; r < WK; r++) { (r&1) ? eq.digitodd(r, 0) : eq.digiteven(r, 0); eq.xfull = eq.bfull = eq.hfull = 0; eq.showbsizes(r); } eq.digitK(0); // Convert solution indices to byte array (decompress) and pass it to validBlock method. for (size_t s = 0; s < eq.nsols; s++) { std::vector<eh_index> index_vector(PROOFSIZE); for (size_t i = 0; i < PROOFSIZE; i++) { index_vector[i] = eq.sols[s][i]; } std::vector<unsigned char> sol_char = GetMinimalFromIndices(index_vector, DIGITBITS); if (validBlock(sol_char)) return true; } } else { try { if (EhOptimisedSolve(n, k, curr_state, validBlock)) return true; } catch (std::exception&) { LogPrintf("pow/nano.cpp: ", "execption catched..."); } } return false; }
CMotionVector CVideoObject::findShapeMVP ( const CMotionVector* pmv, const CMotionVector* pmvBY, const CMBMode* pmbmd, Int iMBX, Int iMBY ) const { CMotionVector mvRet; // try shape vector first Bool bLeftBndry, bRightBndry, bTopBndry; Int iMBnum = VPMBnum(iMBX, iMBY); bLeftBndry = bVPNoLeft(iMBnum, iMBX); bTopBndry = bVPNoTop(iMBnum); bRightBndry = bVPNoRightTop(iMBnum, iMBX); //OBSS_SAIT_991015 if (iMBX==0 && iMBY==0) { mvRet.iMVX = mvRet.iMVY = mvRet.iHalfX =mvRet.iHalfY = 0; } else mvRet = *(pmvBY - 1); /* !!! mvRet = *(pmvBY - 1); */ //~OBSS_SAIT_991015 // Modified for error resilient mode by Toshiba(1997-11-14) // if ((iMBX > 0) && ((pmbmd - 1)->m_shpmd == INTER_CAE_MVDZ || if (!bLeftBndry && ((pmbmd - 1)->m_shpmd == INTER_CAE_MVDZ || (pmbmd - 1)->m_shpmd == INTER_CAE_MVDNZ || (pmbmd - 1)->m_shpmd == MVDZ_NOUPDT || (pmbmd - 1)->m_shpmd == MVDNZ_NOUPDT)) return mvRet; if (iMBY > 0) { mvRet = *(pmvBY - m_iNumMBX); // Modified for error resilient mode by Toshiba(1997-11-14) // if ((pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDZ || if (!bTopBndry && ((pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDZ || (pmbmd - m_iNumMBX)->m_shpmd == INTER_CAE_MVDNZ || (pmbmd - m_iNumMBX)->m_shpmd == MVDZ_NOUPDT || (pmbmd - m_iNumMBX)->m_shpmd == MVDNZ_NOUPDT // Modified for error resilient mode by Toshiba(1997-11-14) // ) )) return mvRet; mvRet = *(pmvBY - m_iNumMBX + 1); // Modified for error resilient mode by Toshiba(1997-11-14) // if ((iMBX < m_iNumMBX - 1) && ((pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDZ || if (!bRightBndry && ((pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDZ || (pmbmd - m_iNumMBX + 1)->m_shpmd == INTER_CAE_MVDNZ || (pmbmd - m_iNumMBX + 1)->m_shpmd == MVDZ_NOUPDT || (pmbmd - m_iNumMBX + 1)->m_shpmd == MVDNZ_NOUPDT) ) return mvRet; } // try texture vector then; truncate half pel if(m_volmd.bShapeOnly==FALSE && (m_vopmd.vopPredType==PVOP || (m_uiSprite == 2 && m_vopmd.vopPredType==SPRITE))) // GMC { Int iSubDim; if (m_volmd.bQuarterSample) // Quarter sample iSubDim = 4; else iSubDim = 2; // Modified for error resilient mode by Toshiba(1997-11-14) // if (iMBX != 0 && validBlock (pmbmd - 1, gIndexOfCandBlk [1] [0])) if (!bLeftBndry && validBlock (pmbmd, pmbmd - 1, gIndexOfCandBlk [1] [0])) // GMC if(!((pmbmd-1)->m_bMCSEL)){ // ~GMC return CMotionVector ((pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0])->m_vctTrueHalfPel.x / iSubDim, (pmv - PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [0])->m_vctTrueHalfPel.y / iSubDim); // GMC }else{ return CMotionVector (); } // ~GMC if (iMBY != 0) { // Modified for error resilient mode by Toshiba(1997-11-14) // if (validBlock (pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1])) if (!bTopBndry && validBlock (pmbmd, pmbmd - m_iNumMBX, gIndexOfCandBlk [1] [1])) // GMC if(!((pmbmd-m_iNumMBX)->m_bMCSEL)){ // ~GMC return CMotionVector ((pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1])->m_vctTrueHalfPel.x / iSubDim, (pmv - m_iNumOfTotalMVPerRow + gIndexOfCandBlk [1] [1])->m_vctTrueHalfPel.y / iSubDim); // GMC }else{ return CMotionVector (); } // ~GMC // Modified for error resilient mode by Toshiba(1997-11-14) // if (iMBX < m_iNumMBX - 1 && validBlock (pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2])) if (!bRightBndry && validBlock (pmbmd, pmbmd - m_iNumMBX + 1, gIndexOfCandBlk [1] [2])) // GMC if(!((pmbmd-m_iNumMBX + 1)->m_bMCSEL)){ // ~GMC return CMotionVector ((pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2])->m_vctTrueHalfPel.x / iSubDim, (pmv - m_iNumOfTotalMVPerRow + PVOP_MV_PER_REF_PER_MB + gIndexOfCandBlk [1] [2])->m_vctTrueHalfPel.y / iSubDim); // GMC }else{ return CMotionVector (); } // ~GMC } } return CMotionVector (); }