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  }