Skip to content

Commit ef522df

Browse files
committed
fix: performance upgrade for merkletree utils methods
1 parent c0cb4f3 commit ef522df

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

transaction/merkletreeparent.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"github.com/bitcoin-sv/go-sdk/util"
99
)
1010

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

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

31-
// concatenate leaves
32-
concat := append(l, r...)
29+
hash := crypto.Sha256d(concatenated)
3330

34-
// hash the concatenation
35-
hash := crypto.Sha256d(concat)
31+
util.ReverseBytesInPlace(hash)
3632

37-
// swap endianness at the end and convert to hex string
38-
return util.ReverseBytes(hash)
33+
return hash
34+
}
35+
36+
// flipTwoArrays reverses two byte arrays individually and returns as one concatenated slice
37+
// example:
38+
// for a=[a, b, c], b=[d, e, f] the result is [c, b, a, f, e, d]
39+
func flipTwoArrays(a, b []byte) []byte {
40+
result := make([]byte, 0, len(a)+len(b))
41+
for i := len(a) - 1; i >= 0; i-- {
42+
result = append(result, a[i])
43+
}
44+
for i := len(b) - 1; i >= 0; i-- {
45+
result = append(result, b[i])
46+
}
47+
return result
3948
}
4049

4150
// MerkleTreeParentBytes returns the Merkle Tree parent of two Merkle Tree children.

util/bytemanipulation.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ func ReverseBytes(a []byte) []byte {
1414
return tmp
1515
}
1616

17+
// ReverseBytesInPlace reverses the bytes (little endian/big endian) in place (no extra memory allocation).
18+
func ReverseBytesInPlace(a []byte) {
19+
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
20+
a[i], a[j] = a[j], a[i]
21+
}
22+
}
23+
1724
// LittleEndianBytes returns a byte array in little endian from an unsigned integer of 32 bytes.
1825
func LittleEndianBytes(v uint32, l uint32) []byte {
1926
buf := make([]byte, 4)

0 commit comments

Comments
 (0)