void ShortestPathAnalysis::analyzeLoopsRecursively(SILLoop *Loop, int LoopDepth) { if (LoopDepth >= MaxNumLoopLevels) return; // First dive into the inner loops. for (SILLoop *SubLoop : Loop->getSubLoops()) { analyzeLoopsRecursively(SubLoop, LoopDepth + 1); } BlockInfo *HeaderInfo = getBlockInfo(Loop->getHeader()); Distances &HeaderDists = HeaderInfo->getDistances(LoopDepth); // Initial values for the entry (== header) and exit-predecessor (== header as // well). HeaderDists.DistFromEntry = 0; HeaderDists.DistToExit = 0; solveDataFlow(Loop->getBlocks(), LoopDepth); int LoopLength = getExitDistFromSuccs(Loop->getHeader(), LoopDepth) + HeaderInfo->getLength(LoopDepth); HeaderDists.DistToExit = LoopLength; // If there is a loop bypass edge, add the loop length to the loop pre-pre- // header instead to the header. This actually let us ignore the loop bypass // edge in the length calculation for the loop's parent scope. if (SILBasicBlock *Bypass = detectLoopBypassPreheader(Loop)) HeaderInfo = getBlockInfo(Bypass); // Add the full loop length (= assumed-iteration-count * length) to the loop // header so that it is considered in the parent scope. HeaderInfo->getDistances(LoopDepth - 1).LoopHeaderLength = LoopCount * LoopLength; }
void MapExtras::Block::ParseBasemats(TileInfo *tiles, BasematInfo *bmats) { BlockInfo info; info.prepare(this); COPY(bmats->layermat, info.basemats); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { using namespace df::enums::tiletype_material; auto tt = tiles->base_tiles[x][y]; auto mat = info.getBaseMaterial(tt, df::coord2d(x,y)); bmats->mattype[x][y] = mat.mat_type; bmats->matindex[x][y] = mat.mat_index; // Copy base info back to construction layer if (tiles->con_info && !tiles->con_info->constructed.getassignment(x,y)) { tiles->con_info->mattype[x][y] = mat.mat_type; tiles->con_info->matindex[x][y] = mat.mat_index; } } } }
void ShortestPathAnalysis::printBlockInfo(llvm::raw_ostream &OS, SILBasicBlock *BB, int LoopDepth) { BlockInfo *BBInfo = getBlockInfo(BB); Distances &D = BBInfo->getDistances(LoopDepth); OS << " bb" << BB->getDebugID() << ": length=" << BBInfo->Length << '+' << D.LoopHeaderLength << ", d-entry=" << D.DistFromEntry << ", d-exit=" << D.DistToExit << '\n'; }
bool State::sync(BlockChain const& _bc, h256 _block) { bool ret = false; // BLOCK BlockInfo bi; try { auto b = _bc.block(_block); bi.populate(b); bi.verifyInternals(_bc.block(_block)); } catch (...) { // TODO: Slightly nicer handling? :-) cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; exit(1); } if (bi == m_currentBlock) { // We mined the last block. // Our state is good - we just need to move on to next. m_previousBlock = m_currentBlock; resetCurrent(); m_currentNumber++; ret = true; } else if (bi == m_previousBlock) { // No change since last sync. // Carry on as we were. } else { // New blocks available, or we've switched to a different branch. All change. // Find most recent state dump and replay what's left. // (Most recent state dump might end up being genesis.) std::vector<h256> chain; while (bi.stateRoot != BlockInfo::genesis().hash && m_db.lookup(bi.stateRoot).empty()) // while we don't have the state root of the latest block... { chain.push_back(bi.hash); // push back for later replay. bi.populate(_bc.block(bi.parentHash)); // move to parent. } m_previousBlock = bi; resetCurrent(); // Iterate through in reverse, playing back each of the blocks. for (auto it = chain.rbegin(); it != chain.rend(); ++it) playback(_bc.block(*it), true); m_currentNumber = _bc.details(_block).number + 1; resetCurrent(); ret = true; } return ret; }
void BlockInfo::populateFromParent(BlockInfo const& _parent) { m_stateRoot = _parent.stateRoot(); m_number = _parent.m_number + 1; m_parentHash = _parent.m_hash; m_gasLimit = _parent.childGasLimit(); m_gasUsed = 0; m_difficulty = calculateDifficulty(_parent); }
//递归地开辟300块 BlockInfo* BlockHandle::Add(BlockInfo* block) { //开辟新块,编号都为0 BlockInfo* adder = new BlockInfo(0); adder->SetNext(block->GetNext()); block->SetNext(adder); block_count_++; if (block_count_ == block_size_) return adder; else return Add(adder); }
BlockInfo* FileHandle::GetBlockInfo(FileInfo* file, int block_pos) { BlockInfo* bp = file->GetFirstBlock(); while (bp != NULL) { if (bp->get_block_num() == block_pos) return bp; bp = bp->GetNext(); } return NULL; }
int ShortestPathAnalysis::getExitDistFromSuccs(const SILBasicBlock *BB, int LoopDepth) { int MinDist = InitialDist; for (const SILSuccessor &Succ : BB->getSuccessors()) { BlockInfo *SuccInfo = getBlockInfo(Succ); Distances &SDists = SuccInfo->getDistances(LoopDepth); if (SDists.DistToExit < MinDist) MinDist = SDists.DistToExit; } return MinDist; }
/* 返回可用块的首指针*/ BlockInfo* BlockHandle::GetUsableBlock() { if (block_count_ == 0) return NULL; BlockInfo* p = first_block_->GetNext(); first_block_->SetNext(first_block_->GetNext()->GetNext()); block_count_--; p->ResetAge(); p->SetNext(NULL); return p; }
BlockHandle::~BlockHandle() { BlockInfo* b = first_block_; //释放所有块 while (block_count_ > 0) { BlockInfo* bn = b->GetNext(); delete b; b = bn; block_count_--; } }
u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc) { // Check family: BlockInfo biParent(_bc.block(_bi.parentHash)); _bi.verifyParent(biParent); BlockInfo biGrandParent; if (biParent.number) biGrandParent.populate(_bc.block(biParent.parentHash)); sync(_bc, _bi.parentHash); resetCurrent(); m_previousBlock = biParent; return enact(_block, _bc); }
void FileHandle::AddBlockInfo(BlockInfo* block) { BlockInfo *bp = block->GetFile()->GetFirstBlock(); if (bp == NULL) block->GetFile()->SetFirstBlock(block); else { while (bp->GetNext() != NULL) bp = bp->GetNext(); bp->SetNext(block); } block->GetFile()->IncreaseRecordAmount(); block->GetFile()->IncreaseRecordLength(); }
unsigned BlockChainSync::estimatedHashes() const { BlockInfo block = host().chain().info(); time_t lastBlockTime = (block.hash() == host().chain().genesisHash()) ? 1428192000 : (time_t)block.timestamp(); time_t now = time(0); unsigned blockCount = c_chainReorgSize; if (lastBlockTime > now) clog(NetWarn) << "Clock skew? Latest block is in the future"; else blockCount += (now - lastBlockTime) / (unsigned)c_durationLimit; clog(NetAllDetail) << "Estimated hashes: " << blockCount; return blockCount; }
bool _is_intersecting(tBox& box, const BlockInfo& info) const { Real min_pos[2], max_pos[2]; info.pos(min_pos, 0,0); info.pos(max_pos, B::sizeX-1, B::sizeY-1); const Real intersection[2] = { min(max_pos[0], (Real)(box.center[0] + box.h[0]*0.5)) - max(min_pos[0], (Real)(box.center[0] - box.h[0]*0.5)), min(max_pos[1], (Real)(box.center[1] + box.h[1]*0.5)) - max(min_pos[1], (Real)(box.center[1] - box.h[1]*0.5)) }; return intersection[0]>=0 && intersection[1]>=0; }
int ShortestPathAnalysis::getEntryDistFromPreds(const SILBasicBlock *BB, int LoopDepth) { int MinDist = InitialDist; for (SILBasicBlock *Pred : BB->getPreds()) { BlockInfo *PredInfo = getBlockInfo(Pred); Distances &PDists = PredInfo->getDistances(LoopDepth); int DistFromEntry = PDists.DistFromEntry + PredInfo->Length + PDists.LoopHeaderLength; assert(DistFromEntry >= 0); if (DistFromEntry < MinDist) MinDist = DistFromEntry; } return MinDist; }
BlockInfo* BufferManager::GetFileBlock(string db_name, string tb_name, int file_type, int block_num) { fhandle_->IncreaseAge(); FileInfo *file = fhandle_->GetFileInfo(db_name, tb_name, file_type); if (file) { BlockInfo *blo = fhandle_->GetBlockInfo(file, block_num); if (blo) return blo; else /* new block */ { BlockInfo *bp = GetUsableBlock(); bp->set_block_num(block_num); bp->SetFile(file); bp->ReadInfo(path_); fhandle_->AddBlockInfo(bp); return bp; } } else { BlockInfo *bp = GetUsableBlock(); bp->set_block_num(block_num); FileInfo *fp = new FileInfo(db_name,file_type,tb_name, 0 , 0, NULL, NULL); fhandle_->AddFileInfo(fp); bp->SetFile(fp); bp->ReadInfo(path_); fhandle_->AddBlockInfo(bp); return bp; } return 0; }
void FileHandle::IncreaseAge() { FileInfo* fp = first_file_; while (fp != NULL) { BlockInfo* bp = fp->GetFirstBlock(); while (bp != NULL) { bp->IncreaseAge(); bp = bp->GetNext(); } fp = fp->GetNext(); } }
void BlockChain::import(bytes const& _block) { try { // VERIFY: populates from the block and checks the block is internally coherent. BlockInfo bi(&_block); bi.verifyInternals(&_block); auto newHash = eth::sha3(_block); // Check block doesn't already exist first! if (m_details.count(newHash)) return; // Work out its number as the parent's number + 1 auto it = m_details.find(bi.parentHash); if (it == m_details.end()) // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. return; // Check family: BlockInfo biParent(block(bi.parentHash)); bi.verifyParent(biParent); // Check transactions are valid and that they result in a state equivalent to our state_root. State s(bi.coinbaseAddress); s.sync(*this, bi.parentHash); // Get total difficulty increase and update state, checking it. BlockInfo biGrandParent; if (it->second.number) biGrandParent.populate(block(it->second.parent)); u256 td = it->second.totalDifficulty + s.playback(&_block, bi, biParent, biGrandParent); // All ok - insert into DB m_details[newHash] = BlockDetails{(uint)it->second.number + 1, bi.parentHash, td}; m_details[bi.parentHash].children.push_back(newHash); m_db->Put(m_writeOptions, ldb::Slice(toBigEndianString(newHash)), (ldb::Slice)ref(_block)); // This might be the new last block... if (td > m_details[m_lastBlockHash].totalDifficulty) m_lastBlockHash = newHash; } catch (...) { // Exit silently on exception(?) return; } }
void generateSeal(BlockInfo const& _bi) { BasicAuthority::BlockHeader h(_bi); h.m_sig = sign(m_secret, _bi.hashWithout()); RLPStream ret; h.streamRLP(ret); m_onSealGenerated(ret.out()); }
int main() { GenericFarm<Ethash> f; BlockInfo genesis = CanonBlockChain::genesis(); genesis.difficulty = 1 << 18; cdebug << genesis.boundary(); auto mine = [](GenericFarm<Ethash>& f, BlockInfo const& g, unsigned timeout) { BlockInfo bi = g; bool completed = false; f.onSolutionFound([&](ProofOfWork::Solution sol) { ProofOfWork::assignResult(sol, bi); return completed = true; }); f.setWork(bi); for (unsigned i = 0; !completed && i < timeout * 10; ++i, cout << f.miningProgress() << "\r" << flush) this_thread::sleep_for(chrono::milliseconds(100)); cout << endl << flush; cdebug << bi.mixHash << bi.nonce << (Ethash::verify(bi) ? "GOOD" : "bad"); }; Ethash::prep(genesis); genesis.difficulty = u256(1) << 40; genesis.noteDirty(); f.startCPU(); mine(f, genesis, 10); f.startGPU(); cdebug << "Good:"; genesis.difficulty = 1 << 18; genesis.noteDirty(); mine(f, genesis, 30); cdebug << "Bad:"; genesis.difficulty = (u256(1) << 40); genesis.noteDirty(); mine(f, genesis, 30); f.stop(); return 0; }
void BlockInfo::GenerateHallway(FRandomStream* randStream) { bool canRemove = IsRemoveable(); bIsSolid = false; if (!canRemove) return; bool needsGeneration = true; do { //get a random direction int direction = randStream->RandRange(0, 3); EGridDirection::Type gridDirection; switch (direction) { case 0: gridDirection = EGridDirection::GD_UP; break; case 1: gridDirection = EGridDirection::GD_RIGHT; break; case 2: gridDirection = EGridDirection::GD_DOWN; break; case 3: gridDirection = EGridDirection::GD_LEFT; break } BlockInfo* randBlock = GetAdjacent(gridDirection);//get a block in a random direction if (!randBlock || randBlock->IsEdge())//check if that block is removeable { continue; } randBlock->GenerateHallway(randStream); needsGeneration = false; } while (needsGeneration); }
FileHandle::~FileHandle() { WriteToDisk(); FileInfo* fp = first_file_; while (fp != NULL) { FileInfo* fpn = fp->GetNext(); BlockInfo* bp = fp->GetFirstBlock(); while (bp != NULL) { BlockInfo* bpn = bp->GetNext(); delete bp; bp = bpn; } delete fp; fp = fpn; } }
BlockIdentifier::BlockIdentifier() { // clear cache pointers for (int i = 0; i < 65536; i++) cache[i] = NULL; for (int i = 0; i < 16; i++) unknownBlock.colors[i] = 0xff00ff; unknownBlock.alpha = 1.0; unknownBlock.setName("Unknown"); }
void FileHandle::WriteToDisk() { FileInfo* fp = first_file_; while (fp != NULL) { BlockInfo* bp = fp->GetFirstBlock(); while (bp != NULL) { //如果该块被修改过,则写到文件中 if (bp->get_dirty()) { bp->WriteInfo(path_); bp->set_dirty(false); } bp = bp->GetNext(); } fp = fp->GetNext(); } }
void EthashSealEngine::generateSeal(BlockInfo const& _bi) { m_sealing = Ethash::BlockHeader(_bi); m_farm.setWork(m_sealing); m_farm.start(m_sealer); m_farm.setWork(m_sealing); // TODO: take out one before or one after... bytes shouldPrecompute = option("precomputeDAG"); if (!shouldPrecompute.empty() && shouldPrecompute[0] == 1) Ethash::ensurePrecomputed((unsigned)_bi.number()); }
void BlockInfo::Generate(FRandomStream* randStream) { bIsSolid = false; bool needsGeneration = true; int genTryCount = 0; do { //get a random direction int direction = randStream->RandRange(0, 3); EGridDirection::Type gridDirection; switch (direction) { case 0: gridDirection = EGridDirection::GD_UP; break; case 1: gridDirection = EGridDirection::GD_RIGHT; break; case 2: gridDirection = EGridDirection::GD_DOWN; break; case 3: gridDirection = EGridDirection::GD_LEFT; break } BlockInfo* randBlock = GetAdjacent(gridDirection);//get a block in a random direction if (!randBlock || !randBlock->IsRemoveable() || randBlock->IsEdge())//check if that block is removeable { genTryCount++; continue; } randBlock->Generate(randStream); genTryCount++; } while (needsGeneration && genTryCount < 4); }
BlockInfo* Buffer::findBlock(string& dbName){ if (fileHead->blockAmount < MAX_BLOCK){ BlockInfo* tempBlock = new BlockInfo(); fileHead->blockAmount++; return tempBlock; } else{ //LRU algorithm FileInfo* tempFile = fileHead->firstFile; BlockInfo* tempBlock = NULL; BlockInfo* minDirtyBlock = NULL; BlockInfo* minBlock = NULL; while (tempFile){ tempBlock = tempFile->firstBlock; if (tempBlock){ if (tempBlock->dirtyBit && !minDirtyBlock) minDirtyBlock = tempBlock; else if (tempBlock->dirtyBit && (minDirtyBlock->iTime > tempBlock->iTime)) minDirtyBlock = tempBlock; else if (!tempBlock->dirtyBit && !minBlock) minBlock = tempBlock; else if (!tempBlock->dirtyBit && (minBlock->iTime > tempBlock->iTime)) minBlock = tempBlock; } tempFile = tempFile->next; } if (minBlock){ minBlock->file->firstBlock = minBlock->next; tempBlock = minBlock; } else{ minDirtyBlock->file->firstBlock = minDirtyBlock->next; tempBlock = minDirtyBlock; writeBlock(dbName, tempBlock); } tempBlock->clearBlock(); return tempBlock; } }
PopulationStatistics State::populateFromChain(BlockChain const& _bc, h256 const& _h, ImportRequirements::value _ir) { PopulationStatistics ret { 0.0, 0.0 }; if (!_bc.isKnown(_h)) { // Might be worth throwing here. cwarn << "Invalid block given for state population: " << _h; return ret; } auto b = _bc.block(_h); BlockInfo bi(b); if (bi.number) { // Non-genesis: // 1. Start at parent's end state (state root). BlockInfo bip; bip.populate(_bc.block(bi.parentHash)); sync(_bc, bi.parentHash, bip, _ir); // 2. Enact the block's transactions onto this state. m_ourAddress = bi.coinbaseAddress; Timer t; auto vb = BlockChain::verifyBlock(b); ret.verify = t.elapsed(); t.restart(); enact(vb, _bc, _ir); ret.enact = t.elapsed(); } else { // Genesis required: // We know there are no transactions, so just populate directly. m_state.init(); sync(_bc, _h, bi, _ir); } return ret; }
u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const { const unsigned c_expDiffPeriod = 100000; if (!m_number) throw GenesisBlockCannotBeCalculated(); u256 o = max<u256>(c_minimumDifficulty, m_timestamp >= _parent.m_timestamp + c_durationLimit ? _parent.m_difficulty - (_parent.m_difficulty / c_difficultyBoundDivisor) : (_parent.m_difficulty + (_parent.m_difficulty / c_difficultyBoundDivisor))); unsigned periodCount = unsigned(_parent.number() + 1) / c_expDiffPeriod; if (periodCount > 1) o = max<u256>(c_minimumDifficulty, o + (u256(1) << (periodCount - 2))); // latter will eventually become huge, so ensure it's a bigint. return o; }
void MapExtras::Block::ParseBasemats(TileInfo *tiles, BasematInfo *bmats) { BlockInfo info; info.prepare(this); COPY(bmats->veinmat, info.veinmats); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { using namespace df::enums::tiletype_material; auto tt = tiles->base_tiles[x][y]; auto mat = info.getBaseMaterial(tt, df::coord2d(x,y)); bmats->set_base_mat(tiles, df::coord2d(x,y), mat.mat_type, mat.mat_subtype); } } }