Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Package Relay (BIP331)

Overview

Package Relay (BIP331) enables nodes to relay and validate groups of transactions together as atomic units. This is particularly useful for fee-bumping (RBF) transactions, CPFP (Child Pays For Parent) scenarios, and atomic transaction sets.

Specification: BIP 331

Architecture

Package Structure

A transaction package contains:

#![allow(unused)]
fn main() {
pub struct TransactionPackage {
    pub transactions: Vec<Transaction>,  // Ordered: parents first
    pub package_id: PackageId,
    pub combined_fee: u64,
    pub combined_weight: usize,
}
}

Code: package_relay.rs

Package ID

Package ID is calculated as double SHA256 of all transaction IDs:

#![allow(unused)]
fn main() {
pub fn from_transactions(transactions: &[Transaction]) -> PackageId {
    let mut hasher = Sha256::new();
    for tx in transactions {
        let txid = calculate_txid(tx);
        hasher.update(txid);
    }
    let first = hasher.finalize();
    let mut hasher2 = Sha256::new();
    hasher2.update(first);
    PackageId(final_hash)
}
}

Code: package_relay.rs

Validation Rules

Size Limits

  • Maximum Transactions: 25 (BIP331 limit)
  • Maximum Weight: 404,000 WU (~101,000 vB)
  • Minimum Fee Rate: Configurable (default: 1 sat/vB)

Code: package_relay.rs

Ordering Requirements

Transactions must be ordered with parents before children:

  • Each transaction’s inputs that reference in-package parents must reference earlier transactions
  • Invalid ordering results in InvalidOrder rejection

Code: package_relay.rs

Fee Calculation

Package fee is calculated as sum of all transaction fees:

#![allow(unused)]
fn main() {
combined_fee = sum(inputs) - sum(outputs) for all transactions
}

Fee rate is calculated as:

#![allow(unused)]
fn main() {
fee_rate = combined_fee / combined_weight
}

Code: package_relay.rs

Use Cases

Fee-Bumping (RBF)

Parent transaction + child transaction that increases fee:

Package:
  - Parent TX (low fee)
  - Child TX (bumps parent fee)

CPFP (Child Pays For Parent)

Child transaction pays for parent’s fees:

Package:
  - Parent TX (insufficient fee)
  - Child TX (pays for parent)

Atomic Transaction Sets

Multiple transactions that must be accepted together:

Package:
  - TX1 (depends on TX2)
  - TX2 (depends on TX1)

Code: package_relay.rs

Package Manager

PackageRelay

The PackageRelay manager handles:

  • Package validation
  • Package state tracking
  • Package acceptance/rejection
  • Package relay to peers

Code: package_relay.rs

Package States

#![allow(unused)]
fn main() {
pub enum PackageStatus {
    Pending,      // Awaiting validation
    Accepted,     // Validated and accepted
    Rejected { reason: PackageRejectReason },
}
}

Code: package_relay.rs

Rejection Reasons

#![allow(unused)]
fn main() {
pub enum PackageRejectReason {
    TooManyTransactions,
    WeightExceedsLimit,
    FeeRateTooLow,
    InvalidOrder,
    DuplicateTransactions,
    InvalidStructure,
}
}

Code: package_relay.rs

Validation Process

  1. Size Check: Verify transaction count ≤ 25
  2. Weight Check: Verify combined weight ≤ 404,000 WU
  3. Ordering Check: Verify parents before children
  4. Duplicate Check: Verify no duplicate transactions
  5. Fee Calculation: Calculate combined fee and fee rate
  6. Fee Rate Check: Verify fee rate ≥ minimum
  7. Structure Check: Verify valid package structure

Code: package_relay.rs

Network Integration

Package Messages

  • PackageRelay: Relay package to peers
  • PackageAccept: Package accepted by peer
  • PackageReject: Package rejected with reason

Code: package_relay_handler.rs

Handler Integration

The PackageRelayHandler processes incoming package messages:

  • Receives package relay requests
  • Validates packages
  • Accepts or rejects packages
  • Relays accepted packages to other peers

Code: package_relay_handler.rs

Configuration

[network.package_relay]
enabled = true
max_package_size = 25
max_package_weight = 404000  # 404k WU
min_fee_rate = 1000  # 1 sat/vB

Code: package_relay.rs

Benefits

  1. Efficient Fee-Bumping: Better fee rate calculation for packages
  2. Reduced Orphans: Reduces orphan transactions in mempool
  3. Atomic Validation: Package validated as unit
  4. DoS Resistance: Size and weight limits prevent abuse
  5. CPFP Support: Enables child-pays-for-parent scenarios

Components

The Package Relay system includes:

  • Package structure and validation
  • Package ID calculation
  • Fee and weight calculation
  • Ordering validation
  • Package manager
  • Network message handling

Location: blvm-node/src/network/package_relay.rs, blvm-node/src/network/package_relay_handler.rs