guard

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package guard checks a BRC-74 BUMP someone else supplied before the SDK is allowed to allocate for it.

A BUMP reader that sizes a slice from a wire count can be asked, by a handful of bytes, for an allocation that ends the process with an out-of-memory no recover() sees. go-sdk v1.5.2 bounds its leaf count itself, which is why that version is the floor, but whoever serves a proof is one more party choosing the bytes, and the rule for length-prefixed data from any other party is that a declared length is a claim, checked against the bytes present before it sizes memory.

There is no BEEF counterpart: go-sdk v1.5.2's BEEF parser bounds every count against the bytes remaining.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseBUMP

func ParseBUMP(b []byte, bound int) (mp *transaction.MerklePath, err error)

ParseBUMP guards and parses one BRC-74 BUMP of at most bound bytes. The bound is the caller's, since only the caller knows how large an answer it was prepared to read; a bound of zero or less admits nothing.

The parse runs under a recover, so a malformed proof is an error and never a crash.

Example

ParseBUMP walks a BRC-74 BUMP someone else supplied, allocating nothing, and hands it to the SDK only once every count it declares fits the bytes present. The bound is the caller's: how large an answer it was prepared to read.

package main

import (
	"crypto/sha256"
	"fmt"

	"github.com/bsv-blockchain/go-sdk/chainhash"
	"github.com/bsv-blockchain/go-sdk/transaction"

	"github.com/lightwebinc/bcommon/guard"
)

func main() {
	// A well-formed proof: a transaction at offset 1 of a two-transaction
	// block at height 90.
	txid := chainhash.Hash(sha256.Sum256([]byte("a transaction")))
	sibling := chainhash.Hash(sha256.Sum256([]byte("its neighbour")))
	isTxid := true
	good := transaction.NewMerklePath(90, [][]*transaction.PathElement{{
		{Offset: 0, Hash: &sibling},
		{Offset: 1, Hash: &txid, Txid: &isTxid},
	}}).Bytes()

	mp, err := guard.ParseBUMP(good, 1<<20)
	fmt.Println("good:", len(good), "bytes, height", mp.BlockHeight, err)

	// Seven bytes that declare four billion leaves: the SDK is never asked
	// to size a slice for them.
	hostile := []byte{0x5a, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff}
	_, err = guard.ParseBUMP(hostile, 1<<20)
	fmt.Println("hostile:", err)

	_, err = guard.ParseBUMP(append(good, 0x00), 1<<20)
	fmt.Println("trailing:", err)

	_, err = guard.ParseBUMP(good, 16)
	fmt.Println("over the bound:", err)
}
Output:
good: 71 bytes, height 90 <nil>
hostile: bump level 0 declares 4294967295 leaves, 0 bytes remain
trailing: bump has 1 trailing bytes
over the bound: bump is 71 bytes, max 16

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL