mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-05 21:56:50 +00:00
Stop using big.Int to compare hashes (#912)
* Add a benchmark for Hash.Cmp() * Compare hashes directly without going through big.Int * Add a more thorough test for Hash.Cmp()
This commit is contained in:
parent
8fb30a5895
commit
1743dc694a
@ -224,7 +224,16 @@ func HashToBig(hash *Hash) *big.Int {
|
|||||||
// +1 if hash > target
|
// +1 if hash > target
|
||||||
//
|
//
|
||||||
func (hash *Hash) Cmp(target *Hash) int {
|
func (hash *Hash) Cmp(target *Hash) int {
|
||||||
return HashToBig(hash).Cmp(HashToBig(target))
|
// We compare the hashes backwards because Hash is stored as a little endian byte array.
|
||||||
|
for i := HashSize - 1; i >= 0; i-- {
|
||||||
|
switch {
|
||||||
|
case hash[i] < target[i]:
|
||||||
|
return -1
|
||||||
|
case hash[i] > target[i]:
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Less returns true iff hash a is less than hash b
|
// Less returns true iff hash a is less than hash b
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -425,3 +426,43 @@ func TestSort(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hashFlipBit(hash Hash, bit int) Hash {
|
||||||
|
word := bit / 8
|
||||||
|
bit = bit % 8
|
||||||
|
hash[word] ^= 1 << bit
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHash_Cmp(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
hash := Hash{}
|
||||||
|
n, err := r.Read(hash[:])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed generating a random hash '%s'", err)
|
||||||
|
} else if n != len(hash) {
|
||||||
|
t.Fatalf("Failed generating a random hash, expected reading: %d. instead read: %d.", len(hash), n)
|
||||||
|
|
||||||
|
}
|
||||||
|
hashBig := HashToBig(&hash)
|
||||||
|
// Iterate bit by bit, flip it and compare.
|
||||||
|
for bit := 0; bit < HashSize*8; bit++ {
|
||||||
|
newHash := hashFlipBit(hash, bit)
|
||||||
|
if hash.Cmp(&newHash) != hashBig.Cmp(HashToBig(&newHash)) {
|
||||||
|
t.Errorf("Hash.Cmp disagrees with big.Int.Cmp newHash: %s, hash: %s", newHash, hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHash_Cmp(b *testing.B) {
|
||||||
|
hash0, err := NewHashFromStr("3333333333333333333333333333333333333333333333333333333333333333")
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
hash0.Cmp(hash0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user