func GetNextBlockTemplate(r *GetBlockTemplateResp) { var zer [32]byte common.Last.Mutex.Lock() r.Curtime = uint(time.Now().Unix()) r.Mintime = uint(common.Last.Block.GetMedianTimePast()) + 1 if r.Curtime < r.Mintime { r.Curtime = r.Mintime } height := common.Last.Block.Height + 1 bits := common.BlockChain.GetNextWorkRequired(common.Last.Block, uint32(r.Curtime)) target := btc.SetCompact(bits).Bytes() r.Capabilities = []string{"proposal"} r.Version = 4 r.PreviousBlockHash = common.Last.Block.BlockHash.String() r.Transactions, r.Coinbasevalue = GetTransactions(height, uint32(r.Mintime)) r.Coinbasevalue += btc.GetBlockReward(height) r.Coinbaseaux.Flags = "" r.Longpollid = r.PreviousBlockHash r.Target = hex.EncodeToString(append(zer[:32-len(target)], target...)) r.Mutable = []string{"time", "transactions", "prevblock"} r.Noncerange = "00000000ffffffff" r.Sigoplimit = btc.MAX_BLOCK_SIGOPS_COST / btc.WITNESS_SCALE_FACTOR r.Sizelimit = btc.MAX_BLOCK_SIZE r.Bits = fmt.Sprintf("%08x", bits) r.Height = uint(height) last_given_time = uint32(r.Curtime) last_given_mintime = uint32(r.Mintime) common.Last.Mutex.Unlock() }
func (ch *Chain) GetNextWorkRequired(lst *BlockTreeNode, ts uint32) (res uint32) { // Genesis block if lst.Parent == nil { return ch.Consensus.MaxPOWBits } if ((lst.Height + 1) % targetInterval) != 0 { // Special difficulty rule for testnet: if ch.testnet() { // If the new block's timestamp is more than 2* 10 minutes // then allow mining of a min-difficulty block. if ts > lst.Timestamp()+TargetSpacing*2 { return ch.Consensus.MaxPOWBits } else { // Return the last non-special-min-difficulty-rules-block prv := lst for prv.Parent != nil && (prv.Height%targetInterval) != 0 && prv.Bits() == ch.Consensus.MaxPOWBits { prv = prv.Parent } return prv.Bits() } } return lst.Bits() } prv := lst for i := 0; i < targetInterval-1; i++ { prv = prv.Parent } actualTimespan := int64(lst.Timestamp() - prv.Timestamp()) if actualTimespan < POWRetargetSpam/4 { actualTimespan = POWRetargetSpam / 4 } if actualTimespan > POWRetargetSpam*4 { actualTimespan = POWRetargetSpam * 4 } // Retarget bnewbn := btc.SetCompact(lst.Bits()) bnewbn.Mul(bnewbn, big.NewInt(actualTimespan)) bnewbn.Div(bnewbn, big.NewInt(POWRetargetSpam)) if bnewbn.Cmp(ch.Consensus.MaxPOWValue) > 0 { bnewbn = ch.Consensus.MaxPOWValue } res = btc.GetCompact(bnewbn) return }