OSDN Git Service

test (#52)
[bytom/vapor.git] / consensus / difficulty / difficulty_test.go
1 package difficulty
2
3 import (
4         "math/big"
5         "reflect"
6         "strconv"
7         "testing"
8
9         "github.com/vapor/consensus"
10         "github.com/vapor/protocol/bc"
11         "github.com/vapor/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 }