int TestNet3Chain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 14 * 24 * 60 * 60; // two weeks const int64_t nTargetSpacing = 10 * 60; const int64_t nInterval = nTargetTimespan / nTargetSpacing; // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block return proofOfWorkLimit().GetCompact(); // Only change once per interval if ((h + 1) % nInterval != 0) { // Return the last non-special-min-difficulty-rules-block while (blk.height() % nInterval != 0 && blk->bits == proofOfWorkLimit().GetCompact()) blk--; return blk->bits; } // Go back by what we want to be 14 days worth of blocks BlockIterator former = blk - (nInterval-1); // Limit adjustment step int nActualTimespan = blk->time - former->time; log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4) nActualTimespan = nTargetTimespan*4; // Retarget CBigNum bnNew; bnNew.SetCompact(blk->bits); bnNew *= nActualTimespan; bnNew /= nTargetTimespan; if (bnNew > proofOfWorkLimit()) bnNew = proofOfWorkLimit(); /// debug print log_info("GetNextWorkRequired RETARGET"); log_info("\tnTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); log_info("\tBefore: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); log_info("\tAfter: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); return bnNew.GetCompact(); }
int LitecoinChain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks const int64_t nTargetSpacing = 2.5 * 60; const int64_t nInterval = nTargetTimespan / nTargetSpacing; // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block return _genesisBlock.getBits(); // proofOfWorkLimit().GetCompact(); Actually not for the genesisblock - here it is 0x1e0ffff0, not 0x1e0fffff // Only change once per interval if ((h + 1) % nInterval != 0) return blk->bits; // Litecoin: This fixes an issue where a 51% attack can change difficulty at will. // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz int blockstogoback = nInterval-1; if ((h + 1) != nInterval) blockstogoback = nInterval; // Go back by what we want to be 3.5 days worth of blocks BlockIterator former = blk - blockstogoback; // Limit adjustment step int nActualTimespan = blk->time - former->time; log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4) nActualTimespan = nTargetTimespan*4; // Retarget CBigNum bnNew; bnNew.SetCompact(blk->bits); bnNew *= nActualTimespan; bnNew /= nTargetTimespan; if (bnNew > proofOfWorkLimit()) bnNew = proofOfWorkLimit(); /// debug print log_info("GetNextWorkRequired RETARGET"); log_info("\tnTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); log_info("\tBefore: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); log_info("\tAfter: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); return bnNew.GetCompact(); }
int TerracoinChain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 60 * 60; // one hour weeks const int64_t nTargetSpacing = 2 * 60; // new block every two minutes const int64_t nInterval = nTargetTimespan / nTargetSpacing; // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block return proofOfWorkLimit().GetCompact(); // Only change once per interval if ((h + 1) % nInterval != 0) return blk->bits; // Go back by what we want to be 14 days worth of blocks BlockIterator former = blk - (nInterval-1); // Limit adjustment step int nActualTimespan = blk->time - former->time; log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4) nActualTimespan = nTargetTimespan*4; // Retarget CBigNum bnNew; bnNew.SetCompact(blk->bits); bnNew *= nActualTimespan; bnNew /= nTargetTimespan; if (bnNew > proofOfWorkLimit()) bnNew = proofOfWorkLimit(); /// debug print log_info("GetNextWorkRequired RETARGET"); log_info("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); log_info("Before: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); log_info("After: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); return bnNew.GetCompact(); }
Value GetBlock::operator()(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw RPC::error(RPC::invalid_params, "getblock <hash>\n" "Returns details of a block with given block-hash."); std::string strHash = params[0].get_str(); uint256 hash(strHash); BlockIterator blk = _node.blockChain().iterator(hash); Block block; _node.blockChain().getBlock(hash, block); if (block.isNull()) throw RPC::error(RPC::invalid_request, "Block not found"); Object result; result.push_back(Pair("hash", blk->hash.GetHex())); result.push_back(Pair("blockcount", blk.height())); result.push_back(Pair("version", block.getVersion())); result.push_back(Pair("merkleroot", block.getMerkleRoot().GetHex())); result.push_back(Pair("time", (boost::int64_t)block.getBlockTime())); result.push_back(Pair("nonce", (boost::uint64_t)block.getNonce())); result.push_back(Pair("difficulty", _node.blockChain().getDifficulty(blk))); Array txhashes; BOOST_FOREACH (const Transaction&tx, block.getTransactions()) txhashes.push_back(tx.getHash().GetHex()); result.push_back(Pair("tx", txhashes)); BlockIterator prev = blk + 1; BlockIterator next = blk - 1; if (!!prev) result.push_back(Pair("hashprevious", prev->hash.GetHex())); if (!!next ) result.push_back(Pair("hashnext", next->hash.GetHex())); return result; }