3 // HashToBig converts a *bc.Hash into a big.Int that can be used to
7 "github.com/bytom/protocol/bc"
8 "github.com/bytom/protocol/bc/legacy"
11 // perform math comparisons.
12 func HashToBig(hash *bc.Hash) *big.Int {
15 for i := 0; i < blen/2; i++ {
16 buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
19 return new(big.Int).SetBytes(buf[:])
22 // CompactToBig converts a compact representation of a whole number N to an
23 // unsigned 64-bit number. The representation is similar to IEEE754 floating
26 // -------------------------------------------------
27 // | Exponent | Sign | Mantissa |
28 // -------------------------------------------------
29 // | 8 bits [63-56] | 1 bit [55] | 55 bits [54-00] |
30 // -------------------------------------------------
32 // N = (-1^sign) * mantissa * 256^(exponent-3)
33 func CompactToBig(compact uint64) *big.Int {
34 // Extract the mantissa, sign bit, and exponent.
35 mantissa := compact & 0x007fffffffffffff
36 isNegative := compact&0x0080000000000000 != 0
37 exponent := uint(compact >> 56)
41 mantissa >>= 8 * (3 - exponent)
42 bn = big.NewInt(int64(mantissa))
44 bn = big.NewInt(int64(mantissa))
45 bn.Lsh(bn, 8*(exponent-3))
55 // BigToCompact converts a whole number N to a compact representation using
56 // an unsigned 64-bit number
57 func BigToCompact(n *big.Int) uint64 {
63 exponent := uint(len(n.Bytes()))
65 mantissa = uint64(n.Bits()[0])
66 mantissa <<= 8 * (3 - exponent)
68 tn := new(big.Int).Set(n)
69 mantissa = uint64(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])
72 if mantissa&0x0080000000000000 != 0 {
77 compact := uint64(exponent<<56) | mantissa
79 compact |= 0x0080000000000000
84 func CheckProofOfWork(hash *bc.Hash, bits uint64) bool {
85 return HashToBig(hash).Cmp(CompactToBig(bits)) <= 0
88 func CalcNextRequiredDifficulty(lastBH, compareBH *legacy.BlockHeader) uint64 {
91 } else if (lastBH.Height) % BlocksPerRetarget != 0 {
95 targetTimeSpan := int64(BlocksPerRetarget * targetSecondsPerBlock)
96 actualTimespan := int64(lastBH.Time().Sub(compareBH.Time()).Seconds())
98 oldTarget := CompactToBig(lastBH.Bits)
99 newTarget := new(big.Int).Mul(oldTarget, big.NewInt(actualTimespan))
100 newTarget.Div(newTarget, big.NewInt(targetTimeSpan))
101 newTargetBits := BigToCompact(newTarget)