Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(BUX-250): fix decode;add spv and decode tests for corrupted/invalid beef #45

Merged
merged 5 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func ExampleNewClient() {
return
}
fmt.Printf("loaded client: %s", client.GetOptions().userAgent)
// Output:loaded client: go-paymail: v0.9.3
// Output:loaded client: go-paymail: v0.7.2
}

// BenchmarkNewClient benchmarks the method NewClient()
Expand Down
2 changes: 1 addition & 1 deletion definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const (
defaultSSLTimeout = 10 * time.Second // Default timeout in seconds
defaultUserAgent = "go-paymail: " + version // Default user agent
defaultNetwork = byte(Mainnet) // Default network
version = "v0.9.3" // Go-Paymail version
version = "v0.7.2" // Go-Paymail version
)

// Public defaults for paymail specs
Expand Down
36 changes: 22 additions & 14 deletions p2p_beef_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
hashBytesCount = 32
markerBytesCount = 2
versionBytesCount = 2
maxTreeHeight = 64
)

type TxData struct {
Expand Down Expand Up @@ -71,10 +72,6 @@ func DecodeBEEF(beefHex string) (*DecodedBEEF, error) {
return nil, err
}

if len(transactions) < 2 {
return nil, errors.New("not enough transactions provided to decode BEEF")
}

// get the last transaction as the processed transaction - it should be the last one because of khan's ordering
processedTx := transactions[len(transactions)-1]
transactions = transactions[:len(transactions)-1]
Expand All @@ -91,17 +88,29 @@ func decodeBUMPs(beefBytes []byte) ([]BUMP, []byte, error) {
return nil, nil, errors.New("cannot decode BUMP - no bytes provided")
}

bumps := make([]BUMP, 0)
nBump, bytesUsed := bt.NewVarIntFromBytes(beefBytes)

if nBump == 0 {
return nil, nil, errors.New("invalid BEEF- lack of BUMPs")
}

beefBytes = beefBytes[bytesUsed:]

bumps := make([]BUMP, 0, int(nBump))
for i := 0; i < int(nBump); i++ {
if len(beefBytes) == 0 {
return nil, nil, errors.New("insufficient bytes to extract BUMP blockHeight")
}
blockHeight, bytesUsed := bt.NewVarIntFromBytes(beefBytes)
beefBytes = beefBytes[bytesUsed:]
bumpPaths, remainingBytes, err := decodeBUMPPathsFromStream(beefBytes)

treeHeight := beefBytes[0]
if int(treeHeight) > maxTreeHeight {
wregulski marked this conversation as resolved.
Show resolved Hide resolved
return nil, nil, fmt.Errorf("invalid BEEF - treeHeight cannot be grater than %d", maxTreeHeight)
}
beefBytes = beefBytes[1:]

bumpPaths, remainingBytes, err := decodeBUMPPathsFromStream(int(treeHeight), beefBytes)
if err != nil {
return nil, nil, err
}
Expand All @@ -118,16 +127,10 @@ func decodeBUMPs(beefBytes []byte) ([]BUMP, []byte, error) {
return bumps, beefBytes, nil
}

func decodeBUMPPathsFromStream(hexBytes []byte) ([][]BUMPLeaf, []byte, error) {
if len(hexBytes) == 0 {
return nil, nil, errors.New("cannot decode BUMP paths from stream - no bytes provided")
}

treeHeight := hexBytes[0]
hexBytes = hexBytes[1:]
func decodeBUMPPathsFromStream(treeHeight int, hexBytes []byte) ([][]BUMPLeaf, []byte, error) {
bumpPaths := make([][]BUMPLeaf, 0)

for i := 0; i < int(treeHeight); i++ {
for i := 0; i < treeHeight; i++ {
if len(hexBytes) == 0 {
return nil, nil, errors.New("cannot decode BUMP paths number of leaves from stream - no bytes provided")
}
Expand Down Expand Up @@ -196,6 +199,11 @@ func decodeBUMPLevel(nLeaves bt.VarInt, hexBytes []byte) ([]BUMPLeaf, []byte, er

func decodeTransactionsWithPathIndexes(bytes []byte) ([]*TxData, error) {
nTransactions, offset := bt.NewVarIntFromBytes(bytes)

if nTransactions < 2 {
return nil, errors.New("invalid BEEF- not enough transactions provided to decode BEEF")
}

bytes = bytes[offset:]

transactions := make([]*TxData, 0, int(nTransactions))
Expand Down
Loading
Loading