Skip to content

Commit

Permalink
chore(BUX-296): update calculate merkle proof method
Browse files Browse the repository at this point in the history
  • Loading branch information
pawellewandowski98 committed Oct 24, 2023
1 parent b23bb66 commit 864ffb3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 71 deletions.
10 changes: 7 additions & 3 deletions bump.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package paymail

// BUMPTx is a struct that represents a single BUMP transaction
type BUMPTx struct {
hash string
txId bool
duplicate bool
}

type BUMPMap []map[string]BUMPTx
// BUMPMap is a map of BUMPTx where offset is the key
type BUMPMap []map[uint64]BUMPTx

// BUMPSlice is a slice of BUMPMap which contain transactions required to calculate merkle roots
type BUMPSlice []BUMPMap

// BUMP is a struct that represents a whole BUMP format
type BUMP struct {
blockHeight uint64
path BUMPSlice
Expand All @@ -18,8 +22,8 @@ type BUMP struct {
func (b BUMPMap) calculateMerkleRoots() ([]string, error) {
merkleRoots := make([]string, 0)

for tx, offset := range cmp[len(cmp)-1] {
merkleRoot, err := calculateMerkleRoot(tx, offset, cmp)
for offset, bumpTx := range b[0] {
merkleRoot, err := calculateMerkleRoot(bumpTx, offset, b)
if err != nil {
return nil, err
}
Expand Down
18 changes: 0 additions & 18 deletions compound_merkle_path.go

This file was deleted.

90 changes: 40 additions & 50 deletions p2p_beef_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"strconv"

"github.com/libsv/go-bc"
"github.com/libsv/go-bt/v2"
)
Expand Down Expand Up @@ -39,8 +37,8 @@ type DecodedBEEF struct {

func (dBeef *DecodedBEEF) GetMerkleRoots() ([]string, error) {
var merkleRoots []string
for _, cmp := range dBeef.CMPSlice {
partialMerkleRoots, err := cmp.calculateMerkleRoots()
for _, bump := range dBeef.BUMP.path {
partialMerkleRoots, err := bump.calculateMerkleRoots()
if err != nil {
return nil, err
}
Expand All @@ -49,39 +47,56 @@ func (dBeef *DecodedBEEF) GetMerkleRoots() ([]string, error) {
return merkleRoots, nil
}

func calculateMerkleRoot(baseTx string, offset uint64, cmp []map[string]uint64) (string, error) {
for i := 0; i < len(cmp); i++ {
var leftNode, rightNode string
func calculateMerkleRoot(baseTx BUMPTx, offset uint64, bumpMap []map[uint64]BUMPTx) (string, error) {
calculatedHash := baseTx.hash

for i := 0; i < len(bumpMap); i++ {
newOffset := offset - 1
if offset%2 == 0 {
newOffset = offset + 1
}
tx2 := keyByValue(cmp[i], newOffset)
if tx2 == nil {
fmt.Println("could not find pair")
tx2 := bumpMap[i][newOffset]
if &tx2 == nil {
return "", errors.New("could not find pair")
}

if newOffset > offset {
leftNode = baseTx
rightNode = *tx2
} else {
leftNode = *tx2
rightNode = baseTx
}
leftNode, rightNode := prepareNodes(baseTx, offset, tx2, newOffset)

// Calculate new merkle tree parent
str, err := bc.MerkleTreeParentStr(leftNode, rightNode)
if err != nil {
return "", err
}
baseTx = str
calculatedHash = str

// Reduce offset
offset = offset / 2

if i+1 < len(bumpMap) {
baseTx = bumpMap[i+1][newOffset]
}
}

return baseTx, nil
return calculatedHash, nil
}

func prepareNodes(baseTx BUMPTx, offset uint64, tx2 BUMPTx, newOffset uint64) (string, string) {
var txHash, tx2Hash string

if baseTx.duplicate {
txHash = tx2.hash
} else {
txHash = baseTx.hash
}

if tx2.duplicate {
tx2Hash = baseTx.hash
} else {
tx2Hash = tx2.hash
}

if newOffset > offset {
return txHash, tx2Hash
}
return tx2Hash, txHash
}

func keyByValue(m map[string]uint64, value uint64) *string {
Expand Down Expand Up @@ -133,30 +148,6 @@ func DecodeBEEF(beefHex string) (*DecodedBEEF, error) {
}, nil
}

func DecodeBUMP(beefHex string) (*DecodedBEEF, error) {
beefBytes, err := hex.DecodeString(beefHex)
if err != nil {
return nil, err
}

blockHeight, bytesUsed := bt.NewVarIntFromBytes(beefBytes)
beefBytes = beefBytes[bytesUsed:]

bumpSlice, _, err := decodeBUMPSliceFromStream(beefBytes)
if err != nil {
return nil, err
}

bump := BUMP{
blockHeight: uint64(blockHeight),
path: bumpSlice,
}

fmt.Println(bump)

return nil, nil
}

func decodeBUMPSliceFromStream(hexBytes []byte) (BUMPSlice, []byte, error) {
if len(hexBytes) == 0 {
return nil, nil, errors.New("cannot decode cmp slice from stream - no bytes provided")
Expand All @@ -179,7 +170,7 @@ func decodeBUMPSliceFromStream(hexBytes []byte) (BUMPSlice, []byte, error) {
}

func decodeBUMPLeaves(nLeaves bt.VarInt, hexBytes []byte) (BUMPMap, []byte) {
bumpMap := make(map[string]BUMPTx)
bumpMap := make(map[uint64]BUMPTx)
for i := 0; i < int(nLeaves); i++ {
if len(hexBytes) < 1 {
panic(fmt.Errorf("insufficient bytes to extract offset for %d leaf of %d leaves", i, int(nLeaves)))
Expand All @@ -196,8 +187,7 @@ func decodeBUMPLeaves(nLeaves bt.VarInt, hexBytes []byte) (BUMPMap, []byte) {
hexBytes = hexBytes[bytesUsed:]

if flag == 1 {
key := strconv.FormatUint(uint64(offset), 10)
bumpMap[key] = BUMPTx{
bumpMap[uint64(offset)] = BUMPTx{
duplicate: true,
}
continue
Expand All @@ -213,11 +203,11 @@ func decodeBUMPLeaves(nLeaves bt.VarInt, hexBytes []byte) (BUMPMap, []byte) {
hash = reverse(hash)

if flag == 0 {
bumpMap[strconv.FormatUint(uint64(offset), 10)] = BUMPTx{
bumpMap[uint64(offset)] = BUMPTx{
hash: hash,
}
} else {
bumpMap[strconv.FormatUint(uint64(offset), 10)] = BUMPTx{
bumpMap[uint64(offset)] = BUMPTx{
hash: hash,
txId: true,
}
Expand Down

0 comments on commit 864ffb3

Please sign in to comment.