github.com/turingchain2020/turingchain@v1.1.21/common/difficulty/difficulty.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package difficulty 难度计算基础函数 6 package difficulty 7 8 import ( 9 "math/big" 10 ) 11 12 var ( 13 // bigOne is 1 represented as a big.Int. It is defined here to avoid 14 // the overhead of creating it multiple times. 15 bigOne = big.NewInt(1) 16 17 // oneLsh256 is 1 shifted left 256 bits. It is defined here to avoid 18 // the overhead of creating it multiple times. 19 oneLsh256 = new(big.Int).Lsh(bigOne, 256) 20 ) 21 22 // HashToBig converts a chainhash.Hash into a big.Int that can be used to 23 // perform math comparisons. 24 func HashToBig(buf []byte) *big.Int { 25 // A Hash is in little-endian, but the big package wants the bytes in 26 // big-endian, so reverse them. 27 blen := len(buf) 28 for i := 0; i < blen/2; i++ { 29 buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i] 30 } 31 return new(big.Int).SetBytes(buf[:]) 32 } 33 34 // CompactToBig converts a compact representation of a whole number N to an 35 // unsigned 32-bit number. The representation is similar to IEEE754 floating 36 // point numbers. 37 // 38 // Like IEEE754 floating point, there are three basic components: the sign, 39 // the exponent, and the mantissa. They are broken out as follows: 40 // 41 // * the most significant 8 bits represent the unsigned base 256 exponent 42 // * bit 23 (the 24th bit) represents the sign bit 43 // * the least significant 23 bits represent the mantissa 44 // 45 // ------------------------------------------------- 46 // | Exponent | Sign | Mantissa | 47 // ------------------------------------------------- 48 // | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | 49 // ------------------------------------------------- 50 // 51 // The formula to calculate N is: 52 // N = (-1^sign) * mantissa * 256^(exponent-3) 53 // 54 // This compact form is only used in bitcoin to encode unsigned 256-bit numbers 55 // which represent difficulty targets, thus there really is not a need for a 56 // sign bit, but it is implemented here to stay consistent with bitcoind. 57 func CompactToBig(compact uint32) *big.Int { 58 // Extract the mantissa, sign bit, and exponent. 59 mantissa := compact & 0x007fffff 60 isNegative := compact&0x00800000 != 0 61 exponent := uint(compact >> 24) 62 63 // Since the base for the exponent is 256, the exponent can be treated 64 // as the number of bytes to represent the full 256-bit number. So, 65 // treat the exponent as the number of bytes and shift the mantissa 66 // right or left accordingly. This is equivalent to: 67 // N = mantissa * 256^(exponent-3) 68 var bn *big.Int 69 if exponent <= 3 { 70 mantissa >>= 8 * (3 - exponent) 71 bn = big.NewInt(int64(mantissa)) 72 } else { 73 bn = big.NewInt(int64(mantissa)) 74 bn.Lsh(bn, 8*(exponent-3)) 75 } 76 77 // Make it negative if the sign bit is set. 78 if isNegative { 79 bn = bn.Neg(bn) 80 } 81 82 return bn 83 } 84 85 // BigToCompact converts a whole number N to a compact representation using 86 // an unsigned 32-bit number. The compact representation only provides 23 bits 87 // of precision, so values larger than (2^23 - 1) only encode the most 88 // significant digits of the number. See CompactToBig for details. 89 func BigToCompact(n *big.Int) uint32 { 90 // No need to do any work if it's zero. 91 if n.Sign() == 0 { 92 return 0 93 } 94 95 // Since the base for the exponent is 256, the exponent can be treated 96 // as the number of bytes. So, shift the number right or left 97 // accordingly. This is equivalent to: 98 // mantissa = mantissa / 256^(exponent-3) 99 var mantissa uint32 100 exponent := uint(len(n.Bytes())) 101 if exponent <= 3 { 102 mantissa = uint32(n.Bits()[0]) 103 mantissa <<= 8 * (3 - exponent) 104 } else { 105 // Use a copy to avoid modifying the caller's original number. 106 tn := new(big.Int).Set(n) 107 mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0]) 108 } 109 110 // When the mantissa already has the sign bit set, the number is too 111 // large to fit into the available 23-bits, so divide the number by 256 112 // and increment the exponent accordingly. 113 if mantissa&0x00800000 != 0 { 114 mantissa >>= 8 115 exponent++ 116 } 117 118 // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit 119 // int and return it. 120 compact := uint32(exponent<<24) | mantissa 121 if n.Sign() < 0 { 122 compact |= 0x00800000 123 } 124 return compact 125 } 126 127 // CalcWork calculates a work value from difficulty bits. Bitcoin increases 128 // the difficulty for generating a block by decreasing the value which the 129 // generated hash must be less than. This difficulty target is stored in each 130 // block header using a compact representation as described in the documentation 131 // for CompactToBig. The main chain is selected by choosing the chain that has 132 // the most proof of work (highest difficulty). Since a lower target difficulty 133 // value equates to higher actual difficulty, the work value which will be 134 // accumulated must be the inverse of the difficulty. Also, in order to avoid 135 // potential division by zero and really small floating point numbers, the 136 // result adds 1 to the denominator and multiplies the numerator by 2^256. 137 func CalcWork(bits uint32) *big.Int { 138 // Return a work value of zero if the passed difficulty bits represent 139 // a negative number. Note this should not happen in practice with valid 140 // blocks, but an invalid block could trigger it. 141 difficultyNum := CompactToBig(bits) 142 if difficultyNum.Sign() <= 0 { 143 return big.NewInt(0) 144 } 145 146 // (1 << 256) / (difficultyNum + 1) 147 denominator := new(big.Int).Add(difficultyNum, bigOne) 148 return new(big.Int).Div(oneLsh256, denominator) 149 }