Пример #1
0
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();
}
Пример #2
0
/**
 * 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
}