Expand description
§brk_cohort
UTXO and address cohort filtering for on-chain analytics.
§What It Enables
Slice the UTXO set and address population by age, amount, output type, halving epoch, or holder classification (STH/LTH). Build complex cohorts by combining filters for metrics like “realized cap of 1+ BTC UTXOs older than 150 days.”
§Key Features
- Age-based:
TimeFilter::GreaterOrEqual(hours),TimeFilter::Range(hours..hours),TimeFilter::LowerThan(hours) - Amount-based:
AmountFilter::GreaterOrEqual(Sats::_1BTC),AmountFilter::Range(Sats::_100K..Sats::_1M) - Term classification:
Term::Sth(short-term holders, <150 days),Term::Lth(long-term holders) - Epoch filters: Group by halving epoch
- Type filters: Segment by output type (P2PKH, P2TR, etc.)
- Context-aware naming: Automatic prefix generation (
utxos_,addrs_) based on cohort context - Inclusion logic: Filter hierarchy for aggregation (
Filter::includes)
§Filter Types
ⓘ
pub enum Filter {
All,
Term(Term), // STH/LTH
Time(TimeFilter), // Age-based
Amount(AmountFilter), // Value-based
Epoch(Halving), // Halving epoch
Year(Year), // Calendar year
Type(OutputType), // P2PKH, P2TR, etc.
}§Core API
ⓘ
// TimeFilter values are in hours (e.g., 3600 hours = 150 days)
let filter = Filter::Time(TimeFilter::GreaterOrEqual(3600));
// Check membership
filter.contains_time(4000); // true (4000 hours > 3600 hours)
filter.contains_amount(sats);
// Generate metric names (via CohortContext)
let ctx = CohortContext::Utxo;
ctx.full_name(&filter, "min_age_150d"); // "utxos_min_age_150d"§Built On
brk_errorfor error handlingbrk_typesforSats,Halving,OutputTypebrk_traversablefor data structure traversal
Structs§
- Addr
Groups - Age
- Represents the age of a UTXO or address balance. Encapsulates all age-related calculations in one type-safe struct.
- AgeRange
- Amount
Bucket - Bucket index for amount ranges. Use for cheap comparisons and direct lookups.
- Amount
Range - ByAddr
Type - ByAny
Addr - ByEpoch
- ByTerm
- ByType
- Class
- Cohort
Name - Display names for a cohort with id (for storage/API), short (for charts), and long (for tooltips/labels)
- Loss
- 9 “at least X% loss” aggregate thresholds.
- OverAge
- Over
Amount - Profit
- 14 “at least X% profit” aggregate thresholds.
- Profitability
Range - 25 profitability range buckets ordered from most profitable to most in loss.
- Spendable
Type - UTXO
Groups - Under
Age - Under
Amount - Unspendable
Type
Enums§
- Amount
Filter - Cohort
Context - Context for cohort naming - determines whether a prefix is needed.
- Filter
- State
Level - Controls the level of state tracking for a cohort.
- Term
- Classification for short-term vs long-term holders. The threshold is 150 days (approximately 5 months) = 3600 hours.
- Time
Filter
Constants§
- AGE_
BOUNDARIES - Age boundaries in hours. Defines the cohort ranges: [0, 1h), [1h, 1d), [1d, 1w), [1w, 1m), …, [15y, ∞)
- AGE_
RANGE_ BOUNDS - Age range bounds (end = usize::MAX means unbounded)
- AGE_
RANGE_ FILTERS - Age range filters
- AGE_
RANGE_ NAMES - Age range names
- AMOUNT_
RANGE_ BOUNDS - Amount range bounds
- AMOUNT_
RANGE_ FILTERS - Amount range filters
- AMOUNT_
RANGE_ NAMES - Amount range names
- CLASS_
FILTERS - Class filters
- CLASS_
NAMES - Class names
- CLASS_
VALUES - Class values
- EPOCH_
FILTERS - Epoch filters
- EPOCH_
NAMES - Epoch names
- EPOCH_
VALUES - Epoch values
- HOURS_
1D - HOURS_
1H - HOURS_
1M - HOURS_
1W - HOURS_
1Y - HOURS_
2M - HOURS_
2Y - HOURS_
3M - HOURS_
3Y - HOURS_
4M - HOURS_
4Y - HOURS_
5M - HOURS_
5Y - HOURS_
6M - HOURS_
6Y - HOURS_
7Y - HOURS_
8Y - HOURS_
10Y - HOURS_
12Y - HOURS_
15Y - LOSS_
COUNT - Number of loss thresholds.
- LOSS_
NAMES - “At least X% loss” threshold names (9 thresholds).
- OVER_
AGE_ FILTERS - Over-age filters (GreaterOrEqual threshold in hours)
- OVER_
AGE_ HOURS - Over-age thresholds in hours
- OVER_
AGE_ NAMES - Over-age names
- OVER_
AMOUNT_ FILTERS - Over-amount filters
- OVER_
AMOUNT_ NAMES - Over-amount names
- OVER_
AMOUNT_ THRESHOLDS - Over-amount thresholds
- P2A
- P2PK33
- P2PK65
- P2PKH
- P2SH
- P2TR
- P2WPKH
- P2WSH
- PROFITABILITY_
BOUNDARY_ COUNT - Number of profitability range boundaries (24 boundaries → 25 buckets).
- PROFITABILITY_
RANGE_ COUNT - Number of profitability range buckets.
- PROFITABILITY_
RANGE_ NAMES - Profitability range names (25 ranges, from most profitable to most in loss)
- PROFIT_
COUNT - Number of profit thresholds.
- PROFIT_
NAMES - “At least X% profit” threshold names (14 thresholds).
- SPENDABLE_
TYPE_ FILTERS - Spendable type filters
- SPENDABLE_
TYPE_ NAMES - Spendable type names
- SPENDABLE_
TYPE_ VALUES - Spendable type values
- TERM_
FILTERS - Term filters
- TERM_
NAMES - Term names
- TERM_
VALUES - Term values
- UNDER_
AGE_ FILTERS - Under-age filters (LowerThan threshold in hours)
- UNDER_
AGE_ HOURS - Under-age thresholds in hours
- UNDER_
AGE_ NAMES - Under-age names
- UNDER_
AMOUNT_ FILTERS - Under-amount filters
- UNDER_
AMOUNT_ NAMES - Under-amount names
- UNDER_
AMOUNT_ THRESHOLDS - Under-amount thresholds
Traits§
Functions§
- amounts_
in_ different_ buckets - Check if two amounts are in different buckets. O(1).
- compute_
profitability_ boundaries - Compute 24 boundary prices from spot price for profitability bucketing.
- zip2_
by_ addr_ type - Zip two ByAddrTypes with a function, producing a new ByAddrType.
- zip_
by_ addr_ type - Zip one ByAddrType with a function, producing a new ByAddrType.