59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
package anubis
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestSolveProducesLeadingZeros(t *testing.T) {
|
|
cases := []struct {
|
|
randomData string
|
|
difficulty int
|
|
}{
|
|
{"abc123", 1},
|
|
{"deadbeefcafebabe", 2},
|
|
{"root-me-scoreboard", 3},
|
|
{"odd-difficulty-check", 5},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
hash, nonce := Solve(tc.randomData, tc.difficulty)
|
|
|
|
// The hash must have exactly `difficulty` leading '0' hex digits.
|
|
if got := leadingZeroDigits(hash); got < tc.difficulty {
|
|
t.Errorf("Solve(%q, %d): hash %s has %d leading zeros, want >= %d",
|
|
tc.randomData, tc.difficulty, hash, got, tc.difficulty)
|
|
}
|
|
|
|
// And it must be reproducible: SHA-256(randomData + nonce) == hash.
|
|
want := sha256.Sum256([]byte(tc.randomData + strconv.FormatUint(nonce, 10)))
|
|
if hex.EncodeToString(want[:]) != hash {
|
|
t.Errorf("Solve(%q, %d): hash not reproducible from nonce %d",
|
|
tc.randomData, tc.difficulty, nonce)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSolveFindsSmallestNonce(t *testing.T) {
|
|
// Brute the expected smallest nonce independently and compare.
|
|
const data, diff = "smallest", 2 // difficulty 2 == first byte zero
|
|
var want uint64
|
|
for {
|
|
sum := sha256.Sum256([]byte(data + strconv.FormatUint(want, 10)))
|
|
if sum[0] == 0 {
|
|
break
|
|
}
|
|
want++
|
|
}
|
|
if _, nonce := Solve(data, diff); nonce != want {
|
|
t.Errorf("Solve smallest nonce = %d, want %d", nonce, want)
|
|
}
|
|
}
|
|
|
|
func leadingZeroDigits(hexHash string) int {
|
|
return len(hexHash) - len(strings.TrimLeft(hexHash, "0"))
|
|
}
|