Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
fix(BUX-252): validate CMPs before decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
arkadiuszos4chain committed Oct 5, 2023
1 parent 7250d53 commit 183693d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 18 deletions.
54 changes: 37 additions & 17 deletions beef_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package bux
import (
"context"
"encoding/hex"
"errors"
"fmt"
)

Expand Down Expand Up @@ -34,7 +35,12 @@ func newBeefTx(ctx context.Context, version uint32, tx *Transaction) (*beefTx, e
return nil, fmt.Errorf("version above 0x%X", maxBeefVer)
}

if err := hydrateTransaction(ctx, tx); err != nil {
var err error
if err = hydrateTransaction(ctx, tx); err != nil {
return nil, err
}

if err = validateCompoundMerklePathes(tx.draftTransaction.CompoundMerklePathes); err != nil {
return nil, err
}

Expand Down Expand Up @@ -63,6 +69,36 @@ func newBeefTx(ctx context.Context, version uint32, tx *Transaction) (*beefTx, e
return beef, nil
}

func hydrateTransaction(ctx context.Context, tx *Transaction) error {
if tx.draftTransaction == nil {
dTx, err := getDraftTransactionID(
ctx, tx.XPubID, tx.DraftID, tx.GetOptions(false)...,
)

if err != nil {
return fmt.Errorf("retrieve DraftTransaction failed: %w", err)
}

tx.draftTransaction = dTx
}

return nil
}

func validateCompoundMerklePathes(compountedPaths CMPSlice) error {
if len(compountedPaths) == 0 {
return errors.New("empty compounted paths slice")
}

for _, c := range compountedPaths {
if len(c) == 0 {
return errors.New("one of compounted merkle paths is empty")
}
}

return nil
}

func getParentTransactionsForInput(ctx context.Context, client ClientInterface, input *TransactionInput) ([]*Transaction, error) {
inputTx, err := client.GetTransactionByID(ctx, input.UtxoPointer.TransactionID)
if err != nil {
Expand All @@ -79,19 +115,3 @@ func getParentTransactionsForInput(ctx context.Context, client ClientInterface,

return nil, fmt.Errorf("transaction is not mined yet (tx.ID: %s)", inputTx.ID) // TODO: handle it in next iterration
}

func hydrateTransaction(ctx context.Context, tx *Transaction) error {
if tx.draftTransaction == nil {
dTx, err := getDraftTransactionID(
ctx, tx.XPubID, tx.DraftID, tx.GetOptions(false)...,
)

if err != nil {
return fmt.Errorf("retrieve DraftTransaction failed: %w", err)
}

tx.draftTransaction = dTx
}

return nil
}
2 changes: 1 addition & 1 deletion beef_tx_bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var hasCmp = byte(0x01)
var hasNoCmp = byte(0x00)

func (beefTx *beefTx) toBeefBytes() ([]byte, error) {
if beefTx.compoundMerklePaths == nil || beefTx.transactions == nil {
if len(beefTx.compoundMerklePaths) == 0 || len(beefTx.transactions) < 2 { // valid BEEF contains atleast two transactions (new transaction and one parent transaction)
return nil, errors.New("beef tx is incomplete")
}

Expand Down

0 comments on commit 183693d

Please sign in to comment.