CBlockTemplate* CreateNewBlock(CAccountViewCache &view, CTransactionDBCache &txCache, CScriptDBViewCache &scriptCache){ // // Create new block auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); if (!pblocktemplate.get()) return NULL; CBlock *pblock = &pblocktemplate->block; // pointer for convenience // Create coinbase tx CRewardTransaction rtx; // Add our coinbase tx as first transaction pblock->vptx.push_back(make_shared<CRewardTransaction>(rtx)); pblocktemplate->vTxFees.push_back(-1); // updated at end pblocktemplate->vTxSigOps.push_back(-1); // updated at end // Largest block you're willing to create: unsigned int nBlockMaxSize = SysCfg().GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = max((unsigned int) 1000, min((unsigned int) (MAX_BLOCK_SIZE - 1000), nBlockMaxSize)); // How much of the block should be dedicated to high-priority transactions, // included regardless of the fees they pay unsigned int nBlockPrioritySize = SysCfg().GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE); nBlockPrioritySize = min(nBlockMaxSize, nBlockPrioritySize); // Minimum block size you want to create; block will be filled with free transactions // until there are no more or the block reaches this size: unsigned int nBlockMinSize = SysCfg().GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE); nBlockMinSize = min(nBlockMaxSize, nBlockMinSize); // Collect memory pool transactions into the block int64_t nFees = 0; { LOCK2(cs_main, mempool.cs); CBlockIndex* pIndexPrev = chainActive.Tip(); pblock->SetFuelRate(GetElementForBurn(pIndexPrev)); // This vector will be sorted into a priority queue: vector<TxPriority> vecPriority; GetPriorityTx(vecPriority, pblock->GetFuelRate()); // Collect transactions into block uint64_t nBlockSize = ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); uint64_t nBlockTx(0); bool fSortedByFee(true); uint64_t nTotalRunStep(0); int64_t nTotalFuel(0); TxPriorityCompare comparer(fSortedByFee); make_heap(vecPriority.begin(), vecPriority.end(), comparer); while (!vecPriority.empty()) { // Take highest priority transaction off the priority queue: double dPriority = vecPriority.front().get<0>(); double dFeePerKb = vecPriority.front().get<1>(); shared_ptr<CBaseTransaction> stx = vecPriority.front().get<2>(); CBaseTransaction *pBaseTx = stx.get(); //const CTransaction& tx = *(vecPriority.front().get<2>()); pop_heap(vecPriority.begin(), vecPriority.end(), comparer); vecPriority.pop_back(); // Size limits unsigned int nTxSize = ::GetSerializeSize(*pBaseTx, SER_NETWORK, PROTOCOL_VERSION); if (nBlockSize + nTxSize >= nBlockMaxSize) continue; // Skip free transactions if we're past the minimum block size: if (fSortedByFee && (dFeePerKb < CTransaction::nMinRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) continue; // Prioritize by fee once past the priority size or we run out of high-priority // transactions: if (!fSortedByFee && ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority))) { fSortedByFee = true; comparer = TxPriorityCompare(fSortedByFee); make_heap(vecPriority.begin(), vecPriority.end(), comparer); } if(uint256() != std::move(txCache.IsContainTx(std::move(pBaseTx->GetHash())))) { LogPrint("INFO","CreatePosTx duplicate tx\n"); continue; } CTxUndo txundo; CValidationState state; if(pBaseTx->IsCoinBase()){ ERRORMSG("TX type is coin base tx error......"); // assert(0); //never come here } if (CONTRACT_TX == pBaseTx->nTxType) { LogPrint("vm", "tx hash=%s CreateNewBlock run contract\n", pBaseTx->GetHash().GetHex()); } CAccountViewCache viewTemp(view, true); CScriptDBViewCache scriptCacheTemp(scriptCache, true); pBaseTx->nFuelRate = pblock->GetFuelRate(); if (!pBaseTx->ExecuteTx(nBlockTx + 1, viewTemp, state, txundo, pIndexPrev->nHeight + 1, txCache, scriptCacheTemp)) { continue; } // Run step limits if(nTotalRunStep + pBaseTx->nRunStep >= MAX_BLOCK_RUN_STEP) continue; assert(viewTemp.Flush()); assert(scriptCacheTemp.Flush()); nFees += pBaseTx->GetFee(); nBlockSize += stx->GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION); nTotalRunStep += pBaseTx->nRunStep; nTotalFuel += pBaseTx->GetFuel(pblock->GetFuelRate()); nBlockTx++; pblock->vptx.push_back(stx); LogPrint("fuel", "miner total fuel:%d, tx fuel:%d runStep:%d fuelRate:%d txhash:%s\n",nTotalFuel, pBaseTx->GetFuel(pblock->GetFuelRate()), pBaseTx->nRunStep, pblock->GetFuelRate(), pBaseTx->GetHash().GetHex()); } nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; LogPrint("INFO","CreateNewBlock(): total size %u\n", nBlockSize); assert(nFees-nTotalFuel >= 0); ((CRewardTransaction*) pblock->vptx[0].get())->rewardValue = nFees - nTotalFuel + GetBlockSubsidy(pIndexPrev->nHeight + 1); // Fill in header pblock->SetHashPrevBlock(pIndexPrev->GetBlockHash()); UpdateTime(*pblock, pIndexPrev); pblock->SetBits(GetNextWorkRequired(pIndexPrev, pblock)); pblock->SetNonce(0); pblock->SetHeight(pIndexPrev->nHeight + 1); pblock->SetFuel(nTotalFuel); } return pblocktemplate.release(); }
/** * main function in input */ void inputData() { #ifdef NEED_MACHINE_EDGE initTemp(&temp); #endif jobVertexCount = 0; jobEdgeCount = 0; tabuLength = currentTabuLength = 0; currentT = currentNo = 0; isInitialSolution = true; memset(jobVertex, 0, sizeof(jobVertex)); memset(jobEdge, 0, sizeof(jobEdge)); memset(machineSequence, 0, sizeof(machineSequence)); longestTime = 0, smallestTime = 0x7fffffff; // printf("input the number of the job and the machine\n"); scanf("%d%d", &jobNumber, &machineNumber); getchar(); for(int i = 1; i <= jobNumber; ++i) { // puts("input the number of the process"); int k = 0; int _machine, _duration; // the test input which is easy to input #ifdef TEST_INPUT scanf("%d", &k); for(int j = 1; j <= k; ++j) { // puts("machine, duration"); scanf("%d%d", &_machine, &_duration); buildJobVertex(_machine, i); #ifdef NEED_MACHINE_EDGE insertTemp(_machine, _duration, jobVertexCount); #endif if(j == 1) { headVertex[i] = jobVertexCount; } if(j == k) { tailVertex[i] = jobVertexCount; } buildJobEdge(i, _duration); } #endif // the release(required) input which is hard and confucious // and some info useless #ifdef RELEASE_INPUT char inputString[500]; gets(inputString); int l = strlen(inputString); int t = 0; // while(isdigit(inputString[t])) ++t; for(; t < l; ++t) { if(isdigit(inputString[t])) { ++k; _machine = 0; _duration = 0; while(isdigit(inputString[t])) { _machine *= 10; _machine += inputString[t] - '0'; ++t; } while(!isdigit(inputString[t])) ++t; while(isdigit(inputString[t])) { _duration *= 10; _duration += inputString[t] - '0'; ++t; } buildJobVertex(_machine, i); if(k == 1) { headVertex[i] = jobVertexCount; } buildJobEdge(i, _duration); } } tailVertex[i] = jobVertexCount; #endif } /* #ifdef RELEASE_INPUT int useless; scanf("%d", &useless); #endif */ // buildHeadJobEdge(); // buildHeadJobVertex(); buildTailJobEdge(); #ifdef NEED_MACHINE_EDGE // is it necessary to build machineEdge? viewTemp(); free(temp); temp = NULL; printGraph(); #endif }