mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-06 17:47:01 +02:00
shachain: complete shachain implementation
This commit is contained in:
committed by
Olaoluwa Osuntokun
parent
3a647869b6
commit
b40afeaa08
91
shachain/utils.go
Normal file
91
shachain/utils.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package shachain
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
// changeBit function produce all necessary hash bits flips. You should be
|
||||
// aware that the bit flipping in this function a bit strange, example:
|
||||
// hash: [0b00000000, 0b00000000, ... 0b00000000]
|
||||
// 0 1 ... 31
|
||||
//
|
||||
// byte: 0 0 0 0 0 0 0 0
|
||||
// 7 6 5 4 3 2 1 0
|
||||
//
|
||||
// By flipping the bit at 7 position you will flip the first bit in hash and
|
||||
// by flipping the bit at 8 position you will flip the 16 bit in hash.
|
||||
func changeBit(hash []byte, position uint8) []byte {
|
||||
byteNumber := position / 8
|
||||
bitNumber := position % 8
|
||||
|
||||
hash[byteNumber] ^= (1 << bitNumber)
|
||||
return hash
|
||||
}
|
||||
|
||||
// getBit return bit on index at position.
|
||||
func getBit(index index, position uint8) uint8 {
|
||||
return uint8((uint64(index) >> position) & 1)
|
||||
}
|
||||
|
||||
func getPrefix(index index, position uint8) uint64 {
|
||||
// + -------------------------- +
|
||||
// | № | value | mask | return |
|
||||
// + -- + ----- + ---- + ------ +
|
||||
// | 63 | 1 | 0 | 0 |
|
||||
// | 62 | 0 | 0 | 0 |
|
||||
// | 61 | 1 | 0 | 0 |
|
||||
// ....
|
||||
// | 4 | 1 | 0 | 0 |
|
||||
// | 3 | 1 | 0 | 0 |
|
||||
// | 2 | 1 | 1 | 1 | <--- position
|
||||
// | 1 | 0 | 1 | 0 |
|
||||
// | 0 | 1 | 1 | 1 |
|
||||
// + -- + ----- + ---- + ------ +
|
||||
|
||||
var zero uint64 = 0
|
||||
mask := (zero - 1) - uint64((1<<position)-1)
|
||||
return (uint64(index) & mask)
|
||||
}
|
||||
|
||||
// countTrailingZeros count number of of trailing zero bits, this function is
|
||||
// used to determine the number of element bucket.
|
||||
func countTrailingZeros(index index) uint8 {
|
||||
var zeros uint8 = 0
|
||||
for ; zeros < maxHeight; zeros++ {
|
||||
|
||||
if getBit(index, zeros) != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return zeros
|
||||
}
|
||||
|
||||
// hashFromString takes the string as input an create the wire shahash, the
|
||||
// initial wire.ShaHash NewShaHashFromStr function not suitable because it
|
||||
// reverse the given hash.
|
||||
func hashFromString(s string) (*chainhash.Hash, error) {
|
||||
// Return error if hash string is too long.
|
||||
if len(s) > chainhash.MaxHashStringSize {
|
||||
return nil, chainhash.ErrHashStrSize
|
||||
}
|
||||
|
||||
// Hex decoder expects the hash to be a multiple of two.
|
||||
if len(s)%2 != 0 {
|
||||
s = "0" + s
|
||||
}
|
||||
|
||||
// Convert string hash to bytes.
|
||||
buf, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash, err := chainhash.NewHash(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hash, nil
|
||||
}
|
Reference in New Issue
Block a user