diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index 96f5c73e9..e53fa81a3 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -9865,40 +9865,40 @@ impl BrkClient { self.base.get_json(&format!("/api/oracle/price")) } - /// Live EMA histogram + /// Live payment output histogram /// - /// Smoothed round-dollar payment histogram at the live tip: the committed EMA with the forming mempool block blended in. A flat array of log-scale bins. + /// Live smoothed histogram of oracle-eligible payment outputs, binned by output value on the oracle log scale. It combines the committed oracle window with the forming mempool block. A flat array of log-scale bins. /// - /// Endpoint: `GET /api/oracle/histogram/ema/live` - pub fn get_oracle_histogram_ema_live(&self) -> Result> { - self.base.get_json(&format!("/api/oracle/histogram/ema/live")) + /// Endpoint: `GET /api/oracle/histogram/payments/live` + pub fn get_oracle_histogram_payments_live(&self) -> Result> { + self.base.get_json(&format!("/api/oracle/histogram/payments/live")) } - /// EMA histogram at height or day + /// Payment output histogram at height or day /// - /// Smoothed round-dollar payment histogram for a confirmed point: a block height (`840000`) gives that block's EMA, a calendar date (`YYYY-MM-DD`) gives the average of that day's per-block EMAs. A flat array of log-scale bins. + /// Smoothed histogram of oracle-eligible payment outputs for a confirmed point. A block height (`840000`) gives that block's oracle payment histogram; a calendar date (`YYYY-MM-DD`) gives the average of that day's per-block payment histograms. A flat array of log-scale bins. /// - /// Endpoint: `GET /api/oracle/histogram/ema/{point}` - pub fn get_oracle_histogram_ema(&self, point: &str) -> Result> { - self.base.get_json(&format!("/api/oracle/histogram/ema/{point}")) + /// Endpoint: `GET /api/oracle/histogram/payments/{point}` + pub fn get_oracle_histogram_payments(&self, point: &str) -> Result> { + self.base.get_json(&format!("/api/oracle/histogram/payments/{point}")) } - /// Live raw histogram + /// Live output value histogram /// - /// Unfiltered output histogram for the forming mempool block: every live output binned by value, with none of the round-dollar payment filters applied. A flat array of log-scale bins, all zero when no mempool is configured. + /// Live unfiltered output value histogram for the forming mempool block. Every live output is binned by value on the oracle log scale; no oracle payment filters are applied. A flat array of log-scale bins, all zero when no mempool is configured. /// - /// Endpoint: `GET /api/oracle/histogram/raw/live` - pub fn get_oracle_histogram_raw_live(&self) -> Result> { - self.base.get_json(&format!("/api/oracle/histogram/raw/live")) + /// Endpoint: `GET /api/oracle/histogram/outputs/live` + pub fn get_oracle_histogram_outputs_live(&self) -> Result> { + self.base.get_json(&format!("/api/oracle/histogram/outputs/live")) } - /// Raw histogram at height or day + /// Output value histogram at height or day /// - /// Unfiltered output histogram for a confirmed point: a block height (`840000`) gives that block's outputs, coinbase included, binned by value with no payment filtering; a calendar date (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale bins. + /// Unfiltered output value histogram for a confirmed point. A block height (`840000`) gives every output in that block, coinbase included, binned by value on the oracle log scale; a calendar date (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale bins. /// - /// Endpoint: `GET /api/oracle/histogram/raw/{point}` - pub fn get_oracle_histogram_raw(&self, point: &str) -> Result> { - self.base.get_json(&format!("/api/oracle/histogram/raw/{point}")) + /// Endpoint: `GET /api/oracle/histogram/outputs/{point}` + pub fn get_oracle_histogram_outputs(&self, point: &str) -> Result> { + self.base.get_json(&format!("/api/oracle/histogram/outputs/{point}")) } /// Txid by index diff --git a/crates/brk_computer/src/prices/compute.rs b/crates/brk_computer/src/prices/compute.rs index 7d61b328c..3f3c25314 100644 --- a/crates/brk_computer/src/prices/compute.rs +++ b/crates/brk_computer/src/prices/compute.rs @@ -3,8 +3,8 @@ use std::ops::Range; use brk_error::Result; use brk_indexer::{Indexer, Lengths}; use brk_oracle::{ - Config, HistogramRaw, Oracle, START_HEIGHT_FAST, START_HEIGHT_SLOW, bin_to_cents, cents_to_bin, - for_each_round_dollar_bin, + bin_to_cents, cents_to_bin, for_each_round_dollar_bin, Config, HistogramRaw, Oracle, + START_HEIGHT_FAST, START_HEIGHT_SLOW, }; use brk_types::{Cents, OutputType, Sats, TxIndex, TxOutIndex}; use tracing::info; @@ -115,13 +115,7 @@ impl Vecs { let seed_bin = cents_to_bin(prev_cents.inner() as f64); let warmup = config.window_size.min(committed - START_HEIGHT_SLOW); let mut oracle = Oracle::from_checkpoint(seed_bin, config, |o| { - Self::feed_blocks_with( - o, - indexer, - (committed - warmup)..committed, - None, - |_, _, _| {}, - ); + Self::feed_blocks_for_warmup(o, indexer, (committed - warmup)..committed, None); }); let num_new = total_heights - committed; @@ -136,7 +130,12 @@ impl Vecs { let mut ref_bins = Vec::with_capacity(num_new); if committed < START_HEIGHT_FAST { let slow_end = START_HEIGHT_FAST.min(total_heights); - ref_bins.extend(Self::feed_blocks(&mut oracle, indexer, committed..slow_end, None)); + ref_bins.extend(Self::feed_blocks( + &mut oracle, + indexer, + committed..slow_end, + None, + )); if slow_end == START_HEIGHT_FAST { oracle.reconfigure(Config::default()); } @@ -197,6 +196,16 @@ impl Vecs { ref_bins } + /// Feed blocks into an Oracle when callers only need the warmed EMA/window state. + pub fn feed_blocks_for_warmup( + oracle: &mut Oracle, + indexer: &Indexer, + range: Range, + cap: Option<&Lengths>, + ) { + Self::feed_blocks_with(oracle, indexer, range, cap, |_, _, _| {}); + } + /// Feed a range of blocks into an Oracle and call `on_block` after each /// processed block. This lets callers observe derived state such as EMA /// without duplicating the histogram extraction path. diff --git a/crates/brk_oracle/src/config.rs b/crates/brk_oracle/src/config.rs index cb2c286e9..9cd5705f7 100644 --- a/crates/brk_oracle/src/config.rs +++ b/crates/brk_oracle/src/config.rs @@ -66,7 +66,7 @@ impl Config { /// Split a block range into sub-ranges with a single EMA configuration. pub fn segments_for_range(range: Range) -> impl Iterator> { - let split = START_HEIGHT_FAST.clamp(range.start, range.end); + let split = START_HEIGHT_FAST.max(range.start).min(range.end); [range.start..split, split..range.end] .into_iter() .filter(|range| !range.is_empty()) diff --git a/crates/brk_query/src/impl/oracle.rs b/crates/brk_query/src/impl/oracle.rs index 120a59f52..13840333c 100644 --- a/crates/brk_query/src/impl/oracle.rs +++ b/crates/brk_query/src/impl/oracle.rs @@ -18,30 +18,32 @@ impl Query { Ok(self.live_oracle()?.price_dollars()) } - /// Smoothed EMA histogram at the live tip, quantized for the wire. - pub fn live_histogram_ema(&self) -> Result { + /// Smoothed payment output histogram at the live tip, quantized for the wire. + pub fn live_payment_histogram(&self) -> Result { Ok(self.live_oracle()?.ema().to_compact()) } - /// Smoothed EMA histogram for a confirmed `height`, deterministically + /// Smoothed payment output histogram for a confirmed `height`, deterministically /// reconstructed by replaying the window ending at `height`. EMA values are /// seed-independent, so the result is exact. - pub fn confirmed_histogram_ema(&self, height: usize) -> Result { + pub fn confirmed_payment_histogram(&self, height: usize) -> Result { let safe = self.check_histogram_height(height)?; Ok(self.ema_oracle_at(height, &safe)?.ema().to_compact()) } - /// Smoothed EMA histogram for a calendar `day`: the bin-by-bin average of + /// Smoothed payment output histogram for a calendar `day`: the bin-by-bin average of /// every confirmed block's per-block EMA. Each block's EMA is reconstructed /// independently (seed-independent, so exact); averaging keeps the result an /// intensive per-block rate rather than letting a busy day dominate. - pub fn confirmed_histogram_ema_day(&self, day: Day1) -> Result { + pub fn confirmed_payment_histogram_day(&self, day: Day1) -> Result { let safe = self.safe_lengths(); let range = self.day_block_range(day, &safe)?; - Ok(self.average_histogram_ema_range(range, &safe)?.to_compact()) + Ok(self + .average_payment_histogram_range(range, &safe)? + .to_compact()) } - fn average_histogram_ema_range( + fn average_payment_histogram_range( &self, range: Range, safe: &Lengths, @@ -72,7 +74,7 @@ impl Query { /// Unfiltered per-bin output counts at the live tip: every forming-block /// mempool output binned by value, with none of the round-dollar payment /// filters applied. Zeros when no mempool is configured. - pub fn live_histogram_raw(&self) -> Result { + pub fn live_output_histogram(&self) -> Result { Ok(match self.mempool() { Some(mempool) => mempool.live_raw_histogram(), None => HistogramRaw::zeros(), @@ -81,18 +83,18 @@ impl Query { /// Unfiltered per-bin output counts for a confirmed `height`: every output /// in the block binned by value, with no payment filtering. - pub fn confirmed_histogram_raw(&self, height: usize) -> Result { + pub fn confirmed_output_histogram(&self, height: usize) -> Result { let safe = self.check_histogram_height(height)?; - Ok(self.raw_histogram_for_blocks(height..height + 1, &safe)) + Ok(self.output_histogram_for_blocks(height..height + 1, &safe)) } - /// Unfiltered per-bin output counts for a calendar `day`: every block's raw + /// Unfiltered per-bin output counts for a calendar `day`: every block's output /// histogram summed bin-by-bin. Raw counts are additive, so the day total is /// just the sum across its confirmed blocks. - pub fn confirmed_histogram_raw_day(&self, day: Day1) -> Result { + pub fn confirmed_output_histogram_day(&self, day: Day1) -> Result { let safe = self.safe_lengths(); let range = self.day_block_range(day, &safe)?; - Ok(self.raw_histogram_for_blocks(range, &safe)) + Ok(self.output_histogram_for_blocks(range, &safe)) } /// The live tip oracle: the cached committed base, with the forming block's @@ -124,7 +126,14 @@ impl Query { return Ok(oracle); } - let last = self.computer().prices.spot.cents.height.len().saturating_sub(1); + let last = self + .computer() + .prices + .spot + .cents + .height + .len() + .saturating_sub(1); let seed_bin = self.seed_bin_at(last)?; let oracle = Arc::new(self.warm_oracle(seed_bin, height.to_usize(), &safe)); @@ -150,7 +159,7 @@ impl Query { let config = Config::for_height(end.saturating_sub(1)); let start = end.saturating_sub(config.window_size); Oracle::from_checkpoint(seed_bin, config, |o| { - PricesVecs::feed_blocks_with(o, self.indexer(), start..end, Some(safe), |_, _, _| {}); + PricesVecs::feed_blocks_for_warmup(o, self.indexer(), start..end, Some(safe)); }) } @@ -222,7 +231,7 @@ impl Query { /// coinbase included, binned by value via `sats_to_bin` with no payment /// filtering. Raw counts are additive, so a day can be read as one output /// range instead of one block at a time. - fn raw_histogram_for_blocks(&self, range: Range, safe: &Lengths) -> HistogramRaw { + fn output_histogram_for_blocks(&self, range: Range, safe: &Lengths) -> HistogramRaw { let indexer = self.indexer(); let total_outputs = safe.txout_index.to_usize(); let collect_end = (range.end + 1).min(safe.height.to_usize()); diff --git a/crates/brk_server/src/api/oracle.rs b/crates/brk_server/src/api/oracle.rs index 3294946de..06c173ae8 100644 --- a/crates/brk_server/src/api/oracle.rs +++ b/crates/brk_server/src/api/oracle.rs @@ -43,23 +43,24 @@ impl OracleRoutes for ApiRouter { ), ) .api_route( - "/api/oracle/histogram/ema/live", + "/api/oracle/histogram/payments/live", get_with( async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State| { state .respond_json(&headers, state.mempool_strategy(), &uri, |q| { - q.live_histogram_ema() + q.live_payment_histogram() }) .await }, |op| { - op.id("get_oracle_histogram_ema_live") + op.id("get_oracle_histogram_payments_live") .oracle_tag() - .summary("Live EMA histogram") + .summary("Live payment output histogram") .description( - "Smoothed round-dollar payment histogram at the live tip: the \ - committed EMA with the forming mempool block blended in. \ - A flat array of log-scale bins.", + "Live smoothed histogram of oracle-eligible payment outputs, binned \ + by output value on the oracle log scale. It combines the committed \ + oracle window with the forming mempool block. A flat array of \ + log-scale bins.", ) .json_response::() .not_modified() @@ -68,7 +69,7 @@ impl OracleRoutes for ApiRouter { ), ) .api_route( - "/api/oracle/histogram/ema/{point}", + "/api/oracle/histogram/payments/{point}", get_with( async |uri: Uri, headers: HeaderMap, @@ -81,7 +82,7 @@ impl OracleRoutes for ApiRouter { let strategy = state.date_strategy(version, date); state .respond_json(&headers, strategy, &uri, move |q| { - q.confirmed_histogram_ema_day(Day1::try_from(date)?) + q.confirmed_payment_histogram_day(Day1::try_from(date)?) }) .await } @@ -89,7 +90,7 @@ impl OracleRoutes for ApiRouter { let strategy = state.height_strategy(version, height); state .respond_json(&headers, strategy, &uri, move |q| { - q.confirmed_histogram_ema(usize::from(height)) + q.confirmed_payment_histogram(usize::from(height)) }) .await } @@ -97,14 +98,15 @@ impl OracleRoutes for ApiRouter { } }, |op| { - op.id("get_oracle_histogram_ema") + op.id("get_oracle_histogram_payments") .oracle_tag() - .summary("EMA histogram at height or day") + .summary("Payment output histogram at height or day") .description( - "Smoothed round-dollar payment histogram for a confirmed point: a \ - block height (`840000`) gives that block's EMA, a calendar date \ - (`YYYY-MM-DD`) gives the average of that day's per-block EMAs. \ - A flat array of log-scale bins.", + "Smoothed histogram of oracle-eligible payment outputs for a \ + confirmed point. A block height (`840000`) gives that block's oracle \ + payment histogram; a calendar date (`YYYY-MM-DD`) gives the average \ + of that day's per-block payment histograms. A flat array of log-scale \ + bins.", ) .json_response::() .not_modified() @@ -115,24 +117,24 @@ impl OracleRoutes for ApiRouter { ), ) .api_route( - "/api/oracle/histogram/raw/live", + "/api/oracle/histogram/outputs/live", get_with( async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State| { state .respond_json(&headers, state.mempool_strategy(), &uri, |q| { - q.live_histogram_raw() + q.live_output_histogram() }) .await }, |op| { - op.id("get_oracle_histogram_raw_live") + op.id("get_oracle_histogram_outputs_live") .oracle_tag() - .summary("Live raw histogram") + .summary("Live output value histogram") .description( - "Unfiltered output histogram for the forming mempool block: every \ - live output binned by value, with none of the round-dollar payment \ - filters applied. A flat array of log-scale bins, all zero when no \ - mempool is configured.", + "Live unfiltered output value histogram for the forming mempool \ + block. Every live output is binned by value on the oracle log scale; \ + no oracle payment filters are applied. A flat array of log-scale \ + bins, all zero when no mempool is configured.", ) .json_response::() .not_modified() @@ -141,7 +143,7 @@ impl OracleRoutes for ApiRouter { ), ) .api_route( - "/api/oracle/histogram/raw/{point}", + "/api/oracle/histogram/outputs/{point}", get_with( async |uri: Uri, headers: HeaderMap, @@ -155,7 +157,7 @@ impl OracleRoutes for ApiRouter { let strategy = state.date_strategy(version, date); state .respond_json(&headers, strategy, &uri, move |q| { - q.confirmed_histogram_raw_day(Day1::try_from(date)?) + q.confirmed_output_histogram_day(Day1::try_from(date)?) }) .await } @@ -163,7 +165,7 @@ impl OracleRoutes for ApiRouter { let strategy = state.height_strategy(version, height); state .respond_json(&headers, strategy, &uri, move |q| { - q.confirmed_histogram_raw(usize::from(height)) + q.confirmed_output_histogram(usize::from(height)) }) .await } @@ -171,14 +173,15 @@ impl OracleRoutes for ApiRouter { } }, |op| { - op.id("get_oracle_histogram_raw") + op.id("get_oracle_histogram_outputs") .oracle_tag() - .summary("Raw histogram at height or day") + .summary("Output value histogram at height or day") .description( - "Unfiltered output histogram for a confirmed point: a block height \ - (`840000`) gives that block's outputs, coinbase included, binned by \ - value with no payment filtering; a calendar date (`YYYY-MM-DD`) sums \ - every block that day. A flat array of log-scale bins.", + "Unfiltered output value histogram for a confirmed point. A block \ + height (`840000`) gives every output in that block, coinbase \ + included, binned by value on the oracle log scale; a calendar date \ + (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale \ + bins.", ) .json_response::() .not_modified() diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 394933769..3919790a5 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -11888,62 +11888,62 @@ class BrkClient extends BrkClientBase { } /** - * Live EMA histogram + * Live payment output histogram * - * Smoothed round-dollar payment histogram at the live tip: the committed EMA with the forming mempool block blended in. A flat array of log-scale bins. + * Live smoothed histogram of oracle-eligible payment outputs, binned by output value on the oracle log scale. It combines the committed oracle window with the forming mempool block. A flat array of log-scale bins. * - * Endpoint: `GET /api/oracle/histogram/ema/live` + * Endpoint: `GET /api/oracle/histogram/payments/live` * @param {{ signal?: AbortSignal, onValue?: (value: number[]) => void }} [options] * @returns {Promise} */ - async getOracleHistogramEmaLive({ signal, onValue } = {}) { - const path = `/api/oracle/histogram/ema/live`; + async getOracleHistogramPaymentsLive({ signal, onValue } = {}) { + const path = `/api/oracle/histogram/payments/live`; return this.getJson(path, { signal, onValue }); } /** - * EMA histogram at height or day + * Payment output histogram at height or day * - * Smoothed round-dollar payment histogram for a confirmed point: a block height (`840000`) gives that block's EMA, a calendar date (`YYYY-MM-DD`) gives the average of that day's per-block EMAs. A flat array of log-scale bins. + * Smoothed histogram of oracle-eligible payment outputs for a confirmed point. A block height (`840000`) gives that block's oracle payment histogram; a calendar date (`YYYY-MM-DD`) gives the average of that day's per-block payment histograms. A flat array of log-scale bins. * - * Endpoint: `GET /api/oracle/histogram/ema/{point}` + * Endpoint: `GET /api/oracle/histogram/payments/{point}` * * @param {string} point * @param {{ signal?: AbortSignal, onValue?: (value: number[]) => void }} [options] * @returns {Promise} */ - async getOracleHistogramEma(point, { signal, onValue } = {}) { - const path = `/api/oracle/histogram/ema/${point}`; + async getOracleHistogramPayments(point, { signal, onValue } = {}) { + const path = `/api/oracle/histogram/payments/${point}`; return this.getJson(path, { signal, onValue }); } /** - * Live raw histogram + * Live output value histogram * - * Unfiltered output histogram for the forming mempool block: every live output binned by value, with none of the round-dollar payment filters applied. A flat array of log-scale bins, all zero when no mempool is configured. + * Live unfiltered output value histogram for the forming mempool block. Every live output is binned by value on the oracle log scale; no oracle payment filters are applied. A flat array of log-scale bins, all zero when no mempool is configured. * - * Endpoint: `GET /api/oracle/histogram/raw/live` + * Endpoint: `GET /api/oracle/histogram/outputs/live` * @param {{ signal?: AbortSignal, onValue?: (value: number[]) => void }} [options] * @returns {Promise} */ - async getOracleHistogramRawLive({ signal, onValue } = {}) { - const path = `/api/oracle/histogram/raw/live`; + async getOracleHistogramOutputsLive({ signal, onValue } = {}) { + const path = `/api/oracle/histogram/outputs/live`; return this.getJson(path, { signal, onValue }); } /** - * Raw histogram at height or day + * Output value histogram at height or day * - * Unfiltered output histogram for a confirmed point: a block height (`840000`) gives that block's outputs, coinbase included, binned by value with no payment filtering; a calendar date (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale bins. + * Unfiltered output value histogram for a confirmed point. A block height (`840000`) gives every output in that block, coinbase included, binned by value on the oracle log scale; a calendar date (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale bins. * - * Endpoint: `GET /api/oracle/histogram/raw/{point}` + * Endpoint: `GET /api/oracle/histogram/outputs/{point}` * * @param {string} point * @param {{ signal?: AbortSignal, onValue?: (value: number[]) => void }} [options] * @returns {Promise} */ - async getOracleHistogramRaw(point, { signal, onValue } = {}) { - const path = `/api/oracle/histogram/raw/${point}`; + async getOracleHistogramOutputs(point, { signal, onValue } = {}) { + const path = `/api/oracle/histogram/outputs/${point}`; return this.getJson(path, { signal, onValue }); } diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index 7a0e0c102..cfe584f38 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -8674,37 +8674,37 @@ class BrkClient(BrkClientBase): Endpoint: `GET /api/oracle/price`""" return self.get_json('/api/oracle/price') - def get_oracle_histogram_ema_live(self) -> List[int]: - """Live EMA histogram. + def get_oracle_histogram_payments_live(self) -> List[int]: + """Live payment output histogram. - Smoothed round-dollar payment histogram at the live tip: the committed EMA with the forming mempool block blended in. A flat array of log-scale bins. + Live smoothed histogram of oracle-eligible payment outputs, binned by output value on the oracle log scale. It combines the committed oracle window with the forming mempool block. A flat array of log-scale bins. - Endpoint: `GET /api/oracle/histogram/ema/live`""" - return self.get_json('/api/oracle/histogram/ema/live') + Endpoint: `GET /api/oracle/histogram/payments/live`""" + return self.get_json('/api/oracle/histogram/payments/live') - def get_oracle_histogram_ema(self, point: str) -> List[int]: - """EMA histogram at height or day. + def get_oracle_histogram_payments(self, point: str) -> List[int]: + """Payment output histogram at height or day. - Smoothed round-dollar payment histogram for a confirmed point: a block height (`840000`) gives that block's EMA, a calendar date (`YYYY-MM-DD`) gives the average of that day's per-block EMAs. A flat array of log-scale bins. + Smoothed histogram of oracle-eligible payment outputs for a confirmed point. A block height (`840000`) gives that block's oracle payment histogram; a calendar date (`YYYY-MM-DD`) gives the average of that day's per-block payment histograms. A flat array of log-scale bins. - Endpoint: `GET /api/oracle/histogram/ema/{point}`""" - return self.get_json(f'/api/oracle/histogram/ema/{point}') + Endpoint: `GET /api/oracle/histogram/payments/{point}`""" + return self.get_json(f'/api/oracle/histogram/payments/{point}') - def get_oracle_histogram_raw_live(self) -> List[int]: - """Live raw histogram. + def get_oracle_histogram_outputs_live(self) -> List[int]: + """Live output value histogram. - Unfiltered output histogram for the forming mempool block: every live output binned by value, with none of the round-dollar payment filters applied. A flat array of log-scale bins, all zero when no mempool is configured. + Live unfiltered output value histogram for the forming mempool block. Every live output is binned by value on the oracle log scale; no oracle payment filters are applied. A flat array of log-scale bins, all zero when no mempool is configured. - Endpoint: `GET /api/oracle/histogram/raw/live`""" - return self.get_json('/api/oracle/histogram/raw/live') + Endpoint: `GET /api/oracle/histogram/outputs/live`""" + return self.get_json('/api/oracle/histogram/outputs/live') - def get_oracle_histogram_raw(self, point: str) -> List[int]: - """Raw histogram at height or day. + def get_oracle_histogram_outputs(self, point: str) -> List[int]: + """Output value histogram at height or day. - Unfiltered output histogram for a confirmed point: a block height (`840000`) gives that block's outputs, coinbase included, binned by value with no payment filtering; a calendar date (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale bins. + Unfiltered output value histogram for a confirmed point. A block height (`840000`) gives every output in that block, coinbase included, binned by value on the oracle log scale; a calendar date (`YYYY-MM-DD`) sums every block that day. A flat array of log-scale bins. - Endpoint: `GET /api/oracle/histogram/raw/{point}`""" - return self.get_json(f'/api/oracle/histogram/raw/{point}') + Endpoint: `GET /api/oracle/histogram/outputs/{point}`""" + return self.get_json(f'/api/oracle/histogram/outputs/{point}') def get_tx_by_index(self, index: TxIndex) -> Txid: """Txid by index. diff --git a/website/scripts/options/partial.js b/website/scripts/options/partial.js index c30e574c9..c41f41883 100644 --- a/website/scripts/options/partial.js +++ b/website/scripts/options/partial.js @@ -27,8 +27,8 @@ import { createCointimeSection } from "./cointime.js"; import { createInvestingSection } from "./investing.js"; import { demoHeatmapOption } from "../../src/heatmap/demo.js"; import { - oracleEmaHeatmapOption, - oracleRawHeatmapOption, + oracleOutputsHeatmapOption, + oraclePaymentsHeatmapOption, } from "../../src/heatmap/oracle.js"; // Re-export types for external consumers @@ -306,8 +306,8 @@ export function createPartialOptions() { tree: [ demoHeatmapOption, { - name: "output values", - tree: [oracleRawHeatmapOption, oracleEmaHeatmapOption], + name: "oracle histograms", + tree: [oracleOutputsHeatmapOption, oraclePaymentsHeatmapOption], }, ], }, diff --git a/website/src/heatmap/index.js b/website/src/heatmap/index.js index 32b2b0e7d..69b4f4949 100644 --- a/website/src/heatmap/index.js +++ b/website/src/heatmap/index.js @@ -486,7 +486,7 @@ function updateYControls(option) { const maxSelect = createSelect({ id: "heatmap-y-max", label: "to", - choices, + choices: Array.from(choices).reverse(), initialValue: maxChoice, onChange(choice) { maxChoice = choice; diff --git a/website/src/heatmap/oracle.js b/website/src/heatmap/oracle.js index e1bce9265..6aec9c93e 100644 --- a/website/src/heatmap/oracle.js +++ b/website/src/heatmap/oracle.js @@ -25,14 +25,17 @@ const AMOUNT_CHOICES = [ { label: "10k BTC", value: 4 }, ]; -export const oracleRawHeatmapOption = createOracleHeatmapOption("raw", "raw"); -export const oracleEmaHeatmapOption = createOracleHeatmapOption( - "ema", - "smoothed", +export const oracleOutputsHeatmapOption = createOracleHeatmapOption( + "outputs", + "outputs", +); +export const oraclePaymentsHeatmapOption = createOracleHeatmapOption( + "payments", + "payments", ); /** - * @param {"raw" | "ema"} mode + * @param {"outputs" | "payments"} mode * @param {string} name * @returns {PartialHeatmapOption} */ @@ -40,7 +43,8 @@ function createOracleHeatmapOption(mode, name) { return { kind: "heatmap", name, - title: `${capitalize(name)} Output Value Distribution`, + title: + mode === "outputs" ? "Output Value Histogram" : "Payment Output Histogram", points: { fetch: (date, signal, onPoints) => fetchOraclePoints(mode, date, signal, onPoints), @@ -64,7 +68,7 @@ function createOracleHeatmapOption(mode, name) { } /** - * @param {"raw" | "ema"} mode + * @param {"outputs" | "payments"} mode * @param {string} date * @param {AbortSignal} signal * @param {(points: HeatmapPoints) => void} [onPoints] @@ -82,7 +86,7 @@ async function fetchOraclePoints(mode, date, signal, onPoints) { } /** - * @param {"raw" | "ema"} mode + * @param {"outputs" | "payments"} mode * @param {string} date * @param {AbortSignal} signal * @param {(values: number[]) => void} [onValue] @@ -90,9 +94,9 @@ async function fetchOraclePoints(mode, date, signal, onPoints) { */ function fetchOracleValues(mode, date, signal, onValue) { return ( - mode === "raw" - ? brk.getOracleHistogramRaw(date, { signal, onValue }) - : brk.getOracleHistogramEma(date, { signal, onValue }) + mode === "outputs" + ? brk.getOracleHistogramOutputs(date, { signal, onValue }) + : brk.getOracleHistogramPayments(date, { signal, onValue }) ); } @@ -138,8 +142,3 @@ function formatNumber(value) { function trimNumber(value) { return value.replace(/\.?0+$/, ""); } - -/** @param {string} value */ -function capitalize(value) { - return value.charAt(0).toUpperCase() + value.slice(1); -}