Skip to content

Commit

Permalink
fix: performance upgrade for merkletree utils methods
Browse files Browse the repository at this point in the history
  • Loading branch information
wregulski committed Oct 17, 2024
1 parent c0cb4f3 commit ef522df
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
29 changes: 19 additions & 10 deletions transaction/merkletreeparent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/bitcoin-sv/go-sdk/util"
)

// MerkleTreeParentStr returns the Merkle Tree parent of two Merkle Tree children using hex strings instead of just bytes.
// MerkleTreeParentStr returns the Merkle Tree parent of two MerkleTree children using hex strings instead of just bytes.
func MerkleTreeParentStr(leftNode, rightNode string) (string, error) {
l, err := hex.DecodeString(leftNode)
if err != nil {
Expand All @@ -24,18 +24,27 @@ func MerkleTreeParentStr(leftNode, rightNode string) (string, error) {

// MerkleTreeParent returns the Merkle Tree parent of two MerkleTree children.
func MerkleTreeParent(leftNode, rightNode []byte) []byte {
// swap endianness before concatenating
l := util.ReverseBytes(leftNode)
r := util.ReverseBytes(rightNode)
concatenated := flipTwoArrays(leftNode, rightNode)

// concatenate leaves
concat := append(l, r...)
hash := crypto.Sha256d(concatenated)

// hash the concatenation
hash := crypto.Sha256d(concat)
util.ReverseBytesInPlace(hash)

// swap endianness at the end and convert to hex string
return util.ReverseBytes(hash)
return hash
}

// flipTwoArrays reverses two byte arrays individually and returns as one concatenated slice
// example:
// for a=[a, b, c], b=[d, e, f] the result is [c, b, a, f, e, d]
func flipTwoArrays(a, b []byte) []byte {
result := make([]byte, 0, len(a)+len(b))
for i := len(a) - 1; i >= 0; i-- {
result = append(result, a[i])
}
for i := len(b) - 1; i >= 0; i-- {
result = append(result, b[i])
}
return result
}

// MerkleTreeParentBytes returns the Merkle Tree parent of two Merkle Tree children.
Expand Down
7 changes: 7 additions & 0 deletions util/bytemanipulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ func ReverseBytes(a []byte) []byte {
return tmp
}

// ReverseBytesInPlace reverses the bytes (little endian/big endian) in place (no extra memory allocation).
func ReverseBytesInPlace(a []byte) {
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
}

// LittleEndianBytes returns a byte array in little endian from an unsigned integer of 32 bytes.
func LittleEndianBytes(v uint32, l uint32) []byte {
buf := make([]byte, 4)
Expand Down

0 comments on commit ef522df

Please sign in to comment.