github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/chain/chain_diff.go (about) 1 package chain 2 3 import ( 4 "math/big" 5 "github.com/piotrnar/gocoin/lib/btc" 6 ) 7 8 const ( 9 POWRetargetSpam = 14 * 24 * 60 * 60 // two weeks 10 TargetSpacing = 10 * 60 11 targetInterval = POWRetargetSpam / TargetSpacing 12 ) 13 14 func (ch *Chain) GetNextWorkRequired(lst *BlockTreeNode, ts uint32) (res uint32) { 15 // Genesis block 16 if lst.Parent == nil { 17 return ch.Consensus.MaxPOWBits 18 } 19 20 if ((lst.Height+1) % targetInterval) != 0 { 21 // Special difficulty rule for testnet: 22 if ch.testnet() { 23 // If the new block's timestamp is more than 2* 10 minutes 24 // then allow mining of a min-difficulty block. 25 if ts > lst.Timestamp() + TargetSpacing*2 { 26 return ch.Consensus.MaxPOWBits 27 } else { 28 // Return the last non-special-min-difficulty-rules-block 29 prv := lst 30 for prv.Parent!=nil && (prv.Height%targetInterval)!=0 && prv.Bits()==ch.Consensus.MaxPOWBits { 31 prv = prv.Parent 32 } 33 return prv.Bits() 34 } 35 } 36 return lst.Bits() 37 } 38 39 prv := lst 40 for i:=0; i<targetInterval-1; i++ { 41 prv = prv.Parent 42 } 43 44 actualTimespan := int64(lst.Timestamp() - prv.Timestamp()) 45 46 if actualTimespan < POWRetargetSpam/4 { 47 actualTimespan = POWRetargetSpam/4 48 } 49 if actualTimespan > POWRetargetSpam*4 { 50 actualTimespan = POWRetargetSpam*4 51 } 52 53 // Retarget 54 bnewbn := btc.SetCompact(lst.Bits()) 55 bnewbn.Mul(bnewbn, big.NewInt(actualTimespan)) 56 bnewbn.Div(bnewbn, big.NewInt(POWRetargetSpam)) 57 58 if bnewbn.Cmp(ch.Consensus.MaxPOWValue) > 0 { 59 bnewbn = ch.Consensus.MaxPOWValue 60 } 61 62 res = btc.GetCompact(bnewbn) 63 64 return 65 } 66 67 // MorePOW returns true if b1 has more POW than b2. 68 func (b1 *BlockTreeNode) MorePOW(b2 *BlockTreeNode) bool { 69 var b1sum, b2sum float64 70 for b1.Height > b2.Height { 71 b1sum += btc.GetDifficulty(b1.Bits()) 72 b1 = b1.Parent 73 } 74 for b2.Height > b1.Height { 75 b2sum += btc.GetDifficulty(b2.Bits()) 76 b2 = b2.Parent 77 } 78 for b1 != b2 { 79 b1sum += btc.GetDifficulty(b1.Bits()) 80 b2sum += btc.GetDifficulty(b2.Bits()) 81 b1 = b1.Parent 82 b2 = b2.Parent 83 } 84 return b1sum > b2sum 85 }