github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/consensus/difficulty/difficulty_test.go (about)

     1  package difficulty
     2  
     3  import (
     4  	"math/big"
     5  	"reflect"
     6  	"strconv"
     7  	"testing"
     8  
     9  	"github.com/bytom/bytom/consensus"
    10  	"github.com/bytom/bytom/protocol/bc"
    11  	"github.com/bytom/bytom/protocol/bc/types"
    12  )
    13  
    14  // A lower difficulty Int actually reflects a more difficult mining progress.
    15  func TestCalcNextRequiredDifficulty(t *testing.T) {
    16  	targetTimeSpan := uint64(consensus.BlocksPerRetarget * consensus.TargetSecondsPerBlock)
    17  	cases := []struct {
    18  		lastBH    *types.BlockHeader
    19  		compareBH *types.BlockHeader
    20  		want      uint64
    21  	}{
    22  		{
    23  			&types.BlockHeader{
    24  				Height:    consensus.BlocksPerRetarget,
    25  				Timestamp: targetTimeSpan,
    26  				Bits:      BigToCompact(big.NewInt(1000)),
    27  			},
    28  			&types.BlockHeader{
    29  				Height:    0,
    30  				Timestamp: 0,
    31  			},
    32  			BigToCompact(big.NewInt(1000)),
    33  		},
    34  		{
    35  			&types.BlockHeader{
    36  				Height:    consensus.BlocksPerRetarget,
    37  				Timestamp: targetTimeSpan * 2,
    38  				Bits:      BigToCompact(big.NewInt(1000)),
    39  			},
    40  			&types.BlockHeader{
    41  				Height:    0,
    42  				Timestamp: 0,
    43  			},
    44  			BigToCompact(big.NewInt(2000)),
    45  		},
    46  		{
    47  			&types.BlockHeader{
    48  				Height:    consensus.BlocksPerRetarget - 1,
    49  				Timestamp: targetTimeSpan*2 - consensus.TargetSecondsPerBlock,
    50  				Bits:      BigToCompact(big.NewInt(1000)),
    51  			},
    52  			&types.BlockHeader{
    53  				Height:    0,
    54  				Timestamp: 0,
    55  			},
    56  			BigToCompact(big.NewInt(1000)),
    57  		},
    58  		{
    59  			&types.BlockHeader{
    60  				Height:    consensus.BlocksPerRetarget,
    61  				Timestamp: targetTimeSpan / 2,
    62  				Bits:      BigToCompact(big.NewInt(1000)),
    63  			},
    64  			&types.BlockHeader{
    65  				Height:    0,
    66  				Timestamp: 0,
    67  			},
    68  			BigToCompact(big.NewInt(500)),
    69  		},
    70  		{
    71  			&types.BlockHeader{
    72  				Height:    consensus.BlocksPerRetarget * 2,
    73  				Timestamp: targetTimeSpan + targetTimeSpan*2,
    74  				Bits:      BigToCompact(big.NewInt(1000)),
    75  			},
    76  			&types.BlockHeader{
    77  				Height:    consensus.BlocksPerRetarget,
    78  				Timestamp: targetTimeSpan,
    79  			},
    80  			BigToCompact(big.NewInt(2000)),
    81  		},
    82  		{
    83  			&types.BlockHeader{
    84  				Height:    consensus.BlocksPerRetarget * 2,
    85  				Timestamp: targetTimeSpan + targetTimeSpan/2,
    86  				Bits:      BigToCompact(big.NewInt(1000)),
    87  			},
    88  			&types.BlockHeader{
    89  				Height:    consensus.BlocksPerRetarget,
    90  				Timestamp: targetTimeSpan,
    91  			},
    92  			BigToCompact(big.NewInt(500)),
    93  		},
    94  		{
    95  			&types.BlockHeader{
    96  				Height:    consensus.BlocksPerRetarget*2 - 1,
    97  				Timestamp: targetTimeSpan + targetTimeSpan*2 - consensus.TargetSecondsPerBlock,
    98  				Bits:      BigToCompact(big.NewInt(1000)),
    99  			},
   100  			&types.BlockHeader{
   101  				Height:    consensus.BlocksPerRetarget,
   102  				Timestamp: targetTimeSpan,
   103  			},
   104  			BigToCompact(big.NewInt(1000)),
   105  		},
   106  		{
   107  			&types.BlockHeader{
   108  				Height:    consensus.BlocksPerRetarget*2 - 1,
   109  				Timestamp: targetTimeSpan + targetTimeSpan/2 - consensus.TargetSecondsPerBlock,
   110  				Bits:      BigToCompact(big.NewInt(1000)),
   111  			},
   112  			&types.BlockHeader{
   113  				Height:    consensus.BlocksPerRetarget,
   114  				Timestamp: targetTimeSpan,
   115  			},
   116  			BigToCompact(big.NewInt(1000)),
   117  		},
   118  		// lastBH.Height: 0, lastBH.Timestamp - compareBH.Timestamp: 0, lastBH.Bits: 0
   119  		{
   120  			&types.BlockHeader{
   121  				Height:    0,
   122  				Timestamp: 0,
   123  				Bits:      0,
   124  			},
   125  			&types.BlockHeader{
   126  				Height:    0,
   127  				Timestamp: 0,
   128  			},
   129  			0,
   130  		},
   131  		// lastBH.Height: 0, lastBH.Timestamp - compareBH.Timestamp: 0, lastBH.Bits: 18446744073709551615
   132  		{
   133  			&types.BlockHeader{
   134  				Height:    0,
   135  				Timestamp: 0,
   136  				Bits:      18446744073709551615,
   137  			},
   138  			&types.BlockHeader{
   139  				Height:    0,
   140  				Timestamp: 0,
   141  			},
   142  			18446744073709551615,
   143  		},
   144  		// lastBH.Height: 0, lastBH.Timestamp - compareBH.Timestamp: 0, lastBH.Bits: bigInt(1000)
   145  		{
   146  			&types.BlockHeader{
   147  				Height:    0,
   148  				Timestamp: 0,
   149  				Bits:      BigToCompact(big.NewInt(1000)),
   150  			},
   151  			&types.BlockHeader{
   152  				Height:    0,
   153  				Timestamp: 0,
   154  			},
   155  			BigToCompact(big.NewInt(1000)),
   156  		},
   157  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 0, lastBH.Bits: bigInt(1000)
   158  		{
   159  			&types.BlockHeader{
   160  				Height:    consensus.BlocksPerRetarget,
   161  				Timestamp: targetTimeSpan,
   162  				Bits:      BigToCompact(big.NewInt(1000)),
   163  			},
   164  			&types.BlockHeader{
   165  				Height:    consensus.BlocksPerRetarget - 1,
   166  				Timestamp: targetTimeSpan,
   167  			},
   168  			0,
   169  		},
   170  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: -9223372036854775808, lastBH.Bits: bigInt(1000)
   171  		{
   172  			&types.BlockHeader{
   173  				Height:    consensus.BlocksPerRetarget,
   174  				Timestamp: targetTimeSpan,
   175  				Bits:      BigToCompact(big.NewInt(1000)),
   176  			},
   177  			&types.BlockHeader{
   178  				Height:    consensus.BlocksPerRetarget - 1,
   179  				Timestamp: targetTimeSpan + 9223372036854775808,
   180  			},
   181  			540431955291560988,
   182  		},
   183  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 9223372036854775807, lastBH.Bits: bigInt(1000)
   184  		{
   185  			&types.BlockHeader{
   186  				Height:    consensus.BlocksPerRetarget,
   187  				Timestamp: targetTimeSpan + 9223372036854775807,
   188  				Bits:      BigToCompact(big.NewInt(1000)),
   189  			},
   190  			&types.BlockHeader{
   191  				Height:    consensus.BlocksPerRetarget - 1,
   192  				Timestamp: targetTimeSpan,
   193  			},
   194  			504403158272597019,
   195  		},
   196  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 18446744073709551615, lastBH.Bits: bigInt(1000)
   197  		{
   198  			&types.BlockHeader{
   199  				Height:    consensus.BlocksPerRetarget,
   200  				Timestamp: 18446744073709551615,
   201  				Bits:      BigToCompact(big.NewInt(1000)),
   202  			},
   203  			&types.BlockHeader{
   204  				Height:    consensus.BlocksPerRetarget - 1,
   205  				Timestamp: 0,
   206  			},
   207  			108086391056957440,
   208  		},
   209  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: bigInt(1000)
   210  		{
   211  			&types.BlockHeader{
   212  				Height:    consensus.BlocksPerRetarget,
   213  				Timestamp: targetTimeSpan * 2,
   214  				Bits:      BigToCompact(big.NewInt(1000)),
   215  			},
   216  			&types.BlockHeader{
   217  				Height:    consensus.BlocksPerRetarget - 1,
   218  				Timestamp: targetTimeSpan,
   219  			},
   220  			BigToCompact(big.NewInt(1000)),
   221  		},
   222  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 604800, lastBH.Bits: bigInt(1000)
   223  		{
   224  			&types.BlockHeader{
   225  				Height:    consensus.BlocksPerRetarget,
   226  				Timestamp: targetTimeSpan * 3,
   227  				Bits:      BigToCompact(big.NewInt(1000)),
   228  			},
   229  			&types.BlockHeader{
   230  				Height:    consensus.BlocksPerRetarget - 1,
   231  				Timestamp: targetTimeSpan,
   232  			},
   233  			144115188076367872,
   234  		},
   235  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 151200, lastBH.Bits: bigInt(1000)
   236  		{
   237  			&types.BlockHeader{
   238  				Height:    consensus.BlocksPerRetarget,
   239  				Timestamp: targetTimeSpan + 9223372036854775807,
   240  				Bits:      BigToCompact(big.NewInt(1000)),
   241  			},
   242  			&types.BlockHeader{
   243  				Height:    consensus.BlocksPerRetarget - 1,
   244  				Timestamp: targetTimeSpan,
   245  			},
   246  			504403158272597019,
   247  		},
   248  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: 0
   249  		{
   250  			&types.BlockHeader{
   251  				Height:    consensus.BlocksPerRetarget,
   252  				Timestamp: targetTimeSpan * 2,
   253  				Bits:      0,
   254  			},
   255  			&types.BlockHeader{
   256  				Height:    consensus.BlocksPerRetarget - 1,
   257  				Timestamp: targetTimeSpan,
   258  			},
   259  			0,
   260  		},
   261  		// lastBH.Height: consensus.BlocksPerRetarget, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: 18446744073709551615
   262  		{
   263  			&types.BlockHeader{
   264  				Height:    consensus.BlocksPerRetarget,
   265  				Timestamp: targetTimeSpan * 2,
   266  				Bits:      18446744073709551615,
   267  			},
   268  			&types.BlockHeader{
   269  				Height:    consensus.BlocksPerRetarget - 1,
   270  				Timestamp: targetTimeSpan,
   271  			},
   272  			252201579141136384,
   273  		},
   274  		// lastBH.Height: consensus.BlocksPerRetarget + 1, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: bigInt(1000)
   275  		{
   276  			&types.BlockHeader{
   277  				Height:    consensus.BlocksPerRetarget + 1,
   278  				Timestamp: targetTimeSpan * 2,
   279  				Bits:      BigToCompact(big.NewInt(1000)),
   280  			},
   281  			&types.BlockHeader{
   282  				Height:    consensus.BlocksPerRetarget,
   283  				Timestamp: targetTimeSpan,
   284  			},
   285  			BigToCompact(big.NewInt(1000)),
   286  		},
   287  		// lastBH.Height: consensus.BlocksPerRetarget - 1, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: bigInt(1000)
   288  		{
   289  			&types.BlockHeader{
   290  				Height:    consensus.BlocksPerRetarget - 1,
   291  				Timestamp: targetTimeSpan * 2,
   292  				Bits:      BigToCompact(big.NewInt(1000)),
   293  			},
   294  			&types.BlockHeader{
   295  				Height:    consensus.BlocksPerRetarget - 2,
   296  				Timestamp: targetTimeSpan,
   297  			},
   298  			BigToCompact(big.NewInt(1000)),
   299  		},
   300  		// lastBH.Height: consensus.BlocksPerRetarget * 2, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: bigInt(1000)
   301  		{
   302  			&types.BlockHeader{
   303  				Height:    consensus.BlocksPerRetarget * 2,
   304  				Timestamp: targetTimeSpan * 2,
   305  				Bits:      BigToCompact(big.NewInt(1000)),
   306  			},
   307  			&types.BlockHeader{
   308  				Height:    consensus.BlocksPerRetarget*2 - 1,
   309  				Timestamp: targetTimeSpan,
   310  			},
   311  			BigToCompact(big.NewInt(1000)),
   312  		},
   313  		// lastBH.Height: consensus.BlocksPerRetarget / 2, lastBH.Timestamp - compareBH.Timestamp: 302400, lastBH.Bits: bigInt(1000)
   314  		{
   315  			&types.BlockHeader{
   316  				Height:    consensus.BlocksPerRetarget / 2,
   317  				Timestamp: targetTimeSpan * 2,
   318  				Bits:      BigToCompact(big.NewInt(1000)),
   319  			},
   320  			&types.BlockHeader{
   321  				Height:    consensus.BlocksPerRetarget/2 - 1,
   322  				Timestamp: targetTimeSpan,
   323  			},
   324  			BigToCompact(big.NewInt(1000)),
   325  		},
   326  	}
   327  
   328  	for i, c := range cases {
   329  		if got := CalcNextRequiredDifficulty(c.lastBH, c.compareBH); got != c.want {
   330  			t.Errorf("Compile(%d) = %d want %d\n", i, got, c.want)
   331  			return
   332  		}
   333  	}
   334  }
   335  
   336  func TestHashToBig(t *testing.T) {
   337  	cases := []struct {
   338  		in  [32]byte
   339  		out [32]byte
   340  	}{
   341  		{
   342  			in: [32]byte{
   343  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   344  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   345  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   346  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   347  			},
   348  			out: [32]byte{
   349  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   350  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   351  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   352  				0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
   353  			},
   354  		},
   355  		{
   356  			in: [32]byte{
   357  				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   358  				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   359  				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   360  				0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   361  			},
   362  			out: [32]byte{
   363  				0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
   364  				0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
   365  				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   366  				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   367  			},
   368  		},
   369  		{
   370  			in: [32]byte{
   371  				0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
   372  				0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
   373  				0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
   374  				0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
   375  			},
   376  			out: [32]byte{
   377  				0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
   378  				0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
   379  				0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
   380  				0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
   381  			},
   382  		},
   383  	}
   384  
   385  	for i, c := range cases {
   386  		bhash := bc.NewHash(c.in)
   387  		result := HashToBig(&bhash).Bytes()
   388  
   389  		var resArr [32]byte
   390  		copy(resArr[:], result)
   391  
   392  		if !reflect.DeepEqual(resArr, c.out) {
   393  			t.Errorf("TestHashToBig test #%d failed:\n\tgot\t%x\n\twant\t%x\n", i, resArr, c.out)
   394  			return
   395  		}
   396  	}
   397  }
   398  
   399  func TestCompactToBig(t *testing.T) {
   400  	cases := []struct {
   401  		in  string
   402  		out *big.Int
   403  	}{
   404  		{
   405  			in: `00000000` + //Exponent
   406  				`0` + //Sign
   407  				`0000000000000000000000000000000000000000000000000000000`, //Mantissa
   408  			out: big.NewInt(0),
   409  		},
   410  		{
   411  			in: `00000000` + //Exponent
   412  				`1` + //Sign
   413  				`0000000000000000000000000000000000000000000000000000000`, //Mantissa
   414  			out: big.NewInt(0),
   415  		},
   416  		{
   417  			in: `00000001` + //Exponent
   418  				`0` + //Sign
   419  				`0000000000000000000000000000000000000010000000000000000`, //Mantissa
   420  			out: big.NewInt(1),
   421  		},
   422  		{
   423  			in: `00000001` + //Exponent
   424  				`1` + //Sign
   425  				`0000000000000000000000000000000000000010000000000000000`, //Mantissa
   426  			out: big.NewInt(-1),
   427  		},
   428  		{
   429  			in: `00000011` + //Exponent
   430  				`0` + //Sign
   431  				`0000000000000000000000000000000000000010000000000000000`, //Mantissa
   432  			out: big.NewInt(65536),
   433  		},
   434  		{
   435  			in: `00000011` + //Exponent
   436  				`1` + //Sign
   437  				`0000000000000000000000000000000000000010000000000000000`, //Mantissa
   438  			out: big.NewInt(-65536),
   439  		},
   440  		{
   441  			in: `00000100` + //Exponent
   442  				`0` + //Sign
   443  				`0000000000000000000000000000000000000010000000000000000`, //Mantissa
   444  			out: big.NewInt(16777216),
   445  		},
   446  		{
   447  			in: `00000100` + //Exponent
   448  				`1` + //Sign
   449  				`0000000000000000000000000000000000000010000000000000000`, //Mantissa
   450  			out: big.NewInt(-16777216),
   451  		},
   452  		{
   453  			//btm PowMin test
   454  			// PowMinBits = 2161727821138738707, i.e 0x1e000000000dbe13, as defined
   455  			// in /consensus/general.go
   456  			in: `00011110` + //Exponent
   457  				`0` + //Sign
   458  				`0000000000000000000000000000000000011011011111000010011`, //Mantissa
   459  			out: big.NewInt(0).Lsh(big.NewInt(0x0dbe13), 27*8), //2161727821138738707
   460  		},
   461  	}
   462  
   463  	for i, c := range cases {
   464  		compact, _ := strconv.ParseUint(c.in, 2, 64)
   465  		r := CompactToBig(compact)
   466  		if r.Cmp(c.out) != 0 {
   467  			t.Error("TestCompactToBig test #", i, "failed: got", r, "want", c.out)
   468  			return
   469  		}
   470  	}
   471  }
   472  
   473  func TestBigToCompact(t *testing.T) {
   474  	// basic tests
   475  	tests := []struct {
   476  		in  int64
   477  		out uint64
   478  	}{
   479  		{0, 0x0000000000000000},
   480  		{-0, 0x0000000000000000},
   481  		{1, 0x0100000000010000},
   482  		{-1, 0x0180000000010000},
   483  		{65536, 0x0300000000010000},
   484  		{-65536, 0x0380000000010000},
   485  		{16777216, 0x0400000000010000},
   486  		{-16777216, 0x0480000000010000},
   487  	}
   488  
   489  	for x, test := range tests {
   490  		n := big.NewInt(test.in)
   491  		r := BigToCompact(n)
   492  		if r != test.out {
   493  			t.Errorf("TestBigToCompact test #%d failed: got 0x%016x want 0x%016x\n",
   494  				x, r, test.out)
   495  			return
   496  		}
   497  	}
   498  
   499  	// btm PowMin test
   500  	// PowMinBits = 2161727821138738707, i.e 0x1e000000000dbe13, as defined
   501  	// in /consensus/general.go
   502  	n := big.NewInt(0).Lsh(big.NewInt(0x0dbe13), 27*8)
   503  	out := uint64(0x1e000000000dbe13)
   504  	r := BigToCompact(n)
   505  	if r != out {
   506  		t.Errorf("TestBigToCompact test #%d failed: got 0x%016x want 0x%016x\n",
   507  			len(tests), r, out)
   508  		return
   509  	}
   510  }
   511  
   512  func TestCalcWorkWithIntStr(t *testing.T) {
   513  	cases := []struct {
   514  		strBits string
   515  		want    *big.Int
   516  	}{
   517  		// Exponent: 0, Sign: 0, Mantissa: 0
   518  		{
   519  			`00000000` + //Exponent
   520  				`0` + //Sign
   521  				`0000000000000000000000000000000000000000000000000000000`, //Mantissa
   522  			big.NewInt(0),
   523  		},
   524  		// Exponent: 0, Sign: 0, Mantissa: 1 (difficultyNum = 0 and difficultyNum.Sign() = 0)
   525  		{
   526  			`00000000` +
   527  				`0` +
   528  				`0000000000000000000000000000000000000000000000000000001`,
   529  			big.NewInt(0),
   530  		},
   531  		// Exponent: 0, Sign: 0, Mantissa: 65536 (difficultyNum = 0 and difficultyNum.Sign() = 0)
   532  		{
   533  			`00000000` +
   534  				`0` +
   535  				`0000000000000000000000000000000000000010000000000000000`,
   536  			big.NewInt(0),
   537  		},
   538  		// Exponent: 0, Sign: 0, Mantissa: 16777216 (difficultyNum = 1 and difficultyNum.Sign() = 1)
   539  		{
   540  			`00000000` +
   541  				`0` +
   542  				`0000000000000000000000000000001000000000000000000000000`,
   543  			new(big.Int).Div(oneLsh256, big.NewInt(2)),
   544  		},
   545  		// Exponent: 0, Sign: 0, Mantissa: 0x007fffffffffffff
   546  		{
   547  			`00000000` +
   548  				`0` +
   549  				`1111111111111111111111111111111111111111111111111111111`,
   550  			big.NewInt(0).Lsh(big.NewInt(0x020000), 208),
   551  		},
   552  		// Exponent: 0, Sign: 1, Mantissa: 0
   553  		{
   554  			`00000000` +
   555  				`1` +
   556  				`0000000000000000000000000000000000000000000000000000000`,
   557  			big.NewInt(0),
   558  		},
   559  		// Exponent: 0, Sign: 1, Mantissa: 1 (difficultyNum = 0 and difficultyNum.Sign() = 0)
   560  		{
   561  			`00000000` +
   562  				`1` +
   563  				`0000000000000000000000000000000000000000000000000000001`,
   564  			big.NewInt(0),
   565  		},
   566  		// Exponent: 0, Sign: 1, Mantissa: 65536 (difficultyNum = 0 and difficultyNum.Sign() = 0)
   567  		{
   568  			`00000000` +
   569  				`1` +
   570  				`0000000000000000000000000000000000000010000000000000000`,
   571  			big.NewInt(0),
   572  		},
   573  		// Exponent: 0, Sign: 0, Mantissa: 16777216 (difficultyNum = -1 and difficultyNum.Sign() = -1)
   574  		{
   575  			`00000000` +
   576  				`1` +
   577  				`0000000000000000000000000000001000000000000000000000000`,
   578  			big.NewInt(0),
   579  		},
   580  		// Exponent: 0, Sign: 1, Mantissa: 0x007fffffffffffff
   581  		{
   582  			`00000000` +
   583  				`1` +
   584  				`1111111111111111111111111111111111111111111111111111111`,
   585  			big.NewInt(0),
   586  		},
   587  		// Exponent: 3, Sign: 0, Mantissa: 0
   588  		{
   589  			`00000011` +
   590  				`0` +
   591  				`0000000000000000000000000000000000000000000000000000000`,
   592  			big.NewInt(0),
   593  		},
   594  		// Exponent: 3, Sign: 0, Mantissa: 1 (difficultyNum = 1 and difficultyNum.Sign() = 1)
   595  		{
   596  			`00000011` +
   597  				`0` +
   598  				`0000000000000000000000000000000000000000000000000000001`,
   599  			new(big.Int).Div(oneLsh256, big.NewInt(2)),
   600  		},
   601  		// Exponent: 3, Sign: 0, Mantissa: 65536 (difficultyNum = 65536 and difficultyNum.Sign() = 1)
   602  		{
   603  			`00000011` +
   604  				`0` +
   605  				`0000000000000000000000000000000000000010000000000000000`,
   606  			new(big.Int).Div(oneLsh256, big.NewInt(65537)),
   607  		},
   608  		// Exponent: 0, Sign: 0, Mantissa: 16777216 (difficultyNum = 16777216 and difficultyNum.Sign() = 1)
   609  		{
   610  			`00000011` +
   611  				`0` +
   612  				`0000000000000000000000000000001000000000000000000000000`,
   613  			new(big.Int).Div(oneLsh256, big.NewInt(16777217)),
   614  		},
   615  		// Exponent: 3, Sign: 0, Mantissa: 0x007fffffffffffff
   616  		{
   617  			`00000011` +
   618  				`0` +
   619  				`1111111111111111111111111111111111111111111111111111111`,
   620  			new(big.Int).Div(oneLsh256, big.NewInt(36028797018963968)),
   621  		},
   622  		// Exponent: 3, Sign: 1, Mantissa: 0
   623  		{
   624  			`00000011` +
   625  				`1` +
   626  				`0000000000000000000000000000000000000000000000000000000`,
   627  			big.NewInt(0),
   628  		},
   629  		//Exponent: 3, Sign: 1, Mantissa: 1 (difficultyNum = -1 and difficultyNum.Sign() = -1)
   630  		{
   631  			`00000011` +
   632  				`1` +
   633  				`0000000000000000000000000000000000000000000000000000001`,
   634  			big.NewInt(0),
   635  		},
   636  		// Exponent: 3, Sign: 1, Mantissa: 65536 (difficultyNum = -65536 and difficultyNum.Sign() = -1)
   637  		{
   638  			`00000011` +
   639  				`1` +
   640  				`0000000000000000000000000000000000000010000000000000000`,
   641  			big.NewInt(0),
   642  		},
   643  		// Exponent: 3, Sign: 1, Mantissa: 16777216 (difficultyNum = -16777216 and difficultyNum.Sign() = -1)
   644  		{
   645  			`00000011` +
   646  				`1` +
   647  				`0000000000000000000000000000001000000000000000000000000`,
   648  			big.NewInt(0),
   649  		},
   650  		// Exponent: 3, Sign: 1, Mantissa: 0x007fffffffffffff
   651  		{
   652  			`00000011` +
   653  				`1` +
   654  				`1111111111111111111111111111111111111111111111111111111`,
   655  			big.NewInt(0),
   656  		},
   657  		// Exponent: 7, Sign: 0, Mantissa: 0
   658  		{
   659  			`00000111` +
   660  				`0` +
   661  				`0000000000000000000000000000000000000000000000000000000`,
   662  			big.NewInt(0),
   663  		},
   664  		//Exponent: 7, Sign: 1, Mantissa: 1 (difficultyNum = 4294967296 and difficultyNum.Sign() = 1)
   665  		{
   666  			`00000111` +
   667  				`0` +
   668  				`0000000000000000000000000000000000000000000000000000001`,
   669  			new(big.Int).Div(oneLsh256, big.NewInt(4294967297)),
   670  		},
   671  		// Exponent: 7, Sign: 0, Mantissa: 65536 (difficultyNum = 4294967296 and difficultyNum.Sign() = 1)
   672  		{
   673  			`00000111` +
   674  				`0` +
   675  				`0000000000000000000000000000000000000010000000000000000`,
   676  			new(big.Int).Div(oneLsh256, big.NewInt(281474976710657)),
   677  		},
   678  		// Exponent: 7, Sign: 0, Mantissa: 16777216 (difficultyNum = 72057594037927936 and difficultyNum.Sign() = 1)
   679  		{
   680  			`00000111` +
   681  				`0` +
   682  				`0000000000000000000000000000001000000000000000000000000`,
   683  			new(big.Int).Div(oneLsh256, big.NewInt(72057594037927937)),
   684  		},
   685  		// Exponent: 7, Sign: 0, Mantissa: 0x007fffffffffffff
   686  		{
   687  			`00000111` +
   688  				`0` +
   689  				`1111111111111111111111111111111111111111111111111111111`,
   690  			new(big.Int).Div(oneLsh256, new(big.Int).Add(big.NewInt(0).Lsh(big.NewInt(36028797018963967), 32), bigOne)),
   691  		},
   692  		// Exponent: 7, Sign: 1, Mantissa: 0
   693  		{
   694  			`00000111` +
   695  				`1` +
   696  				`0000000000000000000000000000000000000000000000000000000`,
   697  			big.NewInt(0),
   698  		},
   699  		// Exponent: 7, Sign: 1, Mantissa: 1 (difficultyNum = -4294967296 and difficultyNum.Sign() = -1)
   700  		{
   701  			`00000111` +
   702  				`1` +
   703  				`0000000000000000000000000000000000000000000000000000001`,
   704  			big.NewInt(0),
   705  		},
   706  		// Exponent: 7, Sign: 1, Mantissa: 65536 (difficultyNum = -72057594037927936 and difficultyNum.Sign() = -1)
   707  		{
   708  			`00000111` +
   709  				`1` +
   710  				`0000000000000000000000000000000000000010000000000000000`,
   711  			big.NewInt(0),
   712  		},
   713  		// Exponent: 7, Sign: 1, Mantissa: 16777216 (difficultyNum = -154742504910672530067423232 and difficultyNum.Sign() = -1)
   714  		{
   715  			`00000111` +
   716  				`1` +
   717  				`0000000000000000000000000000001000000000000000000000000`,
   718  			big.NewInt(0),
   719  		},
   720  		// Exponent: 7, Sign: 1, Mantissa: 0x007fffffffffffff
   721  		{
   722  			`00000111` +
   723  				`1` +
   724  				`1111111111111111111111111111111111111111111111111111111`,
   725  			big.NewInt(0),
   726  		},
   727  		// Exponent: 255, Sign: 0, Mantissa: 1 (difficultyNum.Sign() = 1)
   728  		{
   729  			`11111111` +
   730  				`0` +
   731  				`0000000000000000000000000000000000000000000000000000001`,
   732  			big.NewInt(0),
   733  		},
   734  		// Exponent: 255, Sign: 0, Mantissa: 65536 (difficultyNum.Sign() = 1)
   735  		{
   736  			`11111111` +
   737  				`0` +
   738  				`0000000000000000000000000000000000000010000000000000000`,
   739  			big.NewInt(0),
   740  		},
   741  		// Exponent: 255, Sign: 0, Mantissa: 16777216 (difficultyNum.Sign() = 1)
   742  		{
   743  			`11111111` +
   744  				`0` +
   745  				`0000000000000000000000000000001000000000000000000000000`,
   746  			big.NewInt(0),
   747  		},
   748  		// Exponent: 255, Sign: 0, Mantissa: 0x007fffffffffffff
   749  		{
   750  			`11111111` +
   751  				`0` +
   752  				`1111111111111111111111111111111111111111111111111111111`,
   753  			big.NewInt(0),
   754  		},
   755  		// Exponent: 255, Sign: 1, Mantissa: 1
   756  		{
   757  			`11111111` +
   758  				`1` +
   759  				`0000000000000000000000000000000000000000000000000000001`,
   760  			big.NewInt(0),
   761  		},
   762  		// Exponent: 255, Sign: 1, Mantissa: 65536
   763  		{
   764  			`11111111` +
   765  				`1` +
   766  				`0000000000000000000000000000000000000010000000000000000`,
   767  			big.NewInt(0),
   768  		},
   769  		// Exponent: 255, Sign: 1, Mantissa: 16777216
   770  		{
   771  			`11111111` +
   772  				`1` +
   773  				`0000000000000000000000000000001000000000000000000000000`,
   774  			big.NewInt(0),
   775  		},
   776  		// Exponent: 255, Sign: 1, Mantissa: 0x007fffffffffffff
   777  		{
   778  			`11111111` +
   779  				`1` +
   780  				`1111111111111111111111111111111111111111111111111111111`,
   781  			big.NewInt(0),
   782  		},
   783  	}
   784  
   785  	for i, c := range cases {
   786  		bits, err := strconv.ParseUint(c.strBits, 2, 64)
   787  		if err != nil {
   788  			t.Errorf("convert string into uint error: %s\n", err)
   789  			return
   790  		}
   791  
   792  		if got := CalcWork(bits); got.Cmp(c.want) != 0 {
   793  			t.Errorf("CalcWork(%d) = %s, want %s\n", i, got, c.want)
   794  			return
   795  		}
   796  	}
   797  }
   798  
   799  func TestCalcWork(t *testing.T) {
   800  	testCases := []struct {
   801  		bits uint64
   802  		want *big.Int
   803  	}{
   804  		{
   805  			0,
   806  			big.NewInt(0),
   807  		},
   808  		{
   809  			1,
   810  			big.NewInt(0),
   811  		},
   812  		{
   813  			65535,
   814  			big.NewInt(0),
   815  		},
   816  		{
   817  			16777215,
   818  			big.NewInt(0),
   819  		},
   820  		{
   821  			16777216,
   822  			new(big.Int).Div(oneLsh256, big.NewInt(2)),
   823  		},
   824  		{
   825  			4294967295,
   826  			new(big.Int).Div(oneLsh256, big.NewInt(256)),
   827  		},
   828  		{
   829  			36028797018963967,
   830  			new(big.Int).Div(oneLsh256, big.NewInt(2147483648)),
   831  		},
   832  		{
   833  			36028797018963968,
   834  			big.NewInt(0),
   835  		},
   836  		{
   837  			216172782113783808,
   838  			big.NewInt(0),
   839  		},
   840  		{
   841  			216172782113783809,
   842  			new(big.Int).Div(oneLsh256, big.NewInt(2)),
   843  		},
   844  		{
   845  			216172782130561024,
   846  			new(big.Int).Div(oneLsh256, big.NewInt(16777217)),
   847  		},
   848  		{
   849  			252201579132747775,
   850  			new(big.Int).Div(oneLsh256, big.NewInt(36028797018963968)),
   851  		},
   852  		{
   853  			252201579132747776,
   854  			big.NewInt(0),
   855  		},
   856  		{
   857  			288230376151711744,
   858  			big.NewInt(0),
   859  		},
   860  		{
   861  			288230376151711745,
   862  			new(big.Int).Div(oneLsh256, big.NewInt(257)),
   863  		},
   864  		{
   865  			540431955284459519,
   866  			new(big.Int).Div(oneLsh256, new(big.Int).Add(big.NewInt(0).Lsh(big.NewInt(36028797018963967), 32), bigOne)),
   867  		},
   868  		{
   869  			540431955284459520,
   870  			big.NewInt(0),
   871  		},
   872  		{
   873  			9223372036854775807,
   874  			big.NewInt(0),
   875  		},
   876  		{
   877  			18446744073709551615,
   878  			big.NewInt(0),
   879  		},
   880  	}
   881  
   882  	for i, c := range testCases {
   883  		if got := CalcWork(c.bits); got.Cmp(c.want) != 0 {
   884  			t.Errorf("test case with uint64 for CalcWork(%d) = %s, want %s\n", i, got, c.want)
   885  			return
   886  		}
   887  	}
   888  }