oracle: snapshot + start at 508k

This commit is contained in:
nym21
2026-05-23 00:45:37 +02:00
parent bf8de73541
commit 9c74881c5d
28 changed files with 1712 additions and 17546 deletions
+3
View File
@@ -25,6 +25,7 @@ mod mempool;
mod metrics;
mod mining;
mod openapi;
mod oracle;
mod series;
mod series_legacy;
mod server;
@@ -38,6 +39,7 @@ use general::GeneralRoutes;
use mempool::MempoolRoutes;
use mining::MiningRoutes;
pub use openapi::*;
use oracle::OracleRoutes;
use transactions::TxRoutes;
pub trait ApiRoutes {
@@ -57,6 +59,7 @@ impl ApiRoutes for ApiRouter<AppState> {
.add_mining_routes()
.add_fees_routes()
.add_mempool_routes()
.add_oracle_routes()
.add_tx_routes()
.api_route(
"/openapi.json",
+163
View File
@@ -0,0 +1,163 @@
use aide::axum::{ApiRouter, routing::get_with};
use axum::{
extract::{Path, State},
http::{HeaderMap, Uri},
};
use brk_oracle::{HistogramEmaCompact, HistogramRaw};
use brk_types::{Dollars, Version};
use crate::{
AppState,
extended::TransformResponseExtended,
params::{Empty, HeightParam},
};
pub trait OracleRoutes {
fn add_oracle_routes(self) -> Self;
}
impl OracleRoutes for ApiRouter<AppState> {
fn add_oracle_routes(self) -> Self {
self.api_route(
"/api/oracle/price",
get_with(
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
state
.respond_json(&headers, state.mempool_strategy(), &uri, |q| q.live_price())
.await
},
|op| {
op.id("get_oracle_price")
.oracle_tag()
.summary("Live BTC/USD price")
.description(
"Current BTC/USD price in dollars, derived purely from on-chain \
round-dollar output patterns over the last 12 blocks plus the \
forming mempool block. Same value as `/api/mempool/price`. \
Confirmed per-height history is available at `/api/vecs/height-to-price`.",
)
.json_response::<Dollars>()
.not_modified()
.server_error()
},
),
)
.api_route(
"/api/oracle/histogram/ema/live",
get_with(
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
state
.respond_json(&headers, state.mempool_strategy(), &uri, |q| {
q.live_histogram_ema()
})
.await
},
|op| {
op.id("get_oracle_histogram_ema_live")
.oracle_tag()
.summary("Live EMA histogram")
.description(
"Smoothed round-dollar payment histogram at the live tip: the \
committed 12-block EMA with the forming mempool block blended in \
as a final slot. A flat array of 2400 log-scale bins, quantized \
to `u16` for the wire. This is the heatmap column you render.",
)
.json_response::<HistogramEmaCompact>()
.not_modified()
.server_error()
},
),
)
.api_route(
"/api/oracle/histogram/ema/{height}",
get_with(
async |uri: Uri,
headers: HeaderMap,
Path(path): Path<HeightParam>,
_: Empty,
State(state): State<AppState>| {
let strategy = state.height_strategy(Version::new(brk_oracle::VERSION), path.height);
state
.respond_json(&headers, strategy, &uri, move |q| {
q.confirmed_histogram_ema(usize::from(path.height))
})
.await
},
|op| {
op.id("get_oracle_histogram_ema")
.oracle_tag()
.summary("EMA histogram at height")
.description(
"Smoothed round-dollar payment histogram for a confirmed height, \
deterministically reconstructed by replaying the 12-block window \
ending at that height. Immutable once buried, so repeated requests \
return byte-identical results. A flat array of 2400 log-scale bins, \
quantized to `u16`.",
)
.json_response::<HistogramEmaCompact>()
.not_modified()
.bad_request()
.not_found()
.server_error()
},
),
)
.api_route(
"/api/oracle/histogram/raw/live",
get_with(
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
state
.respond_json(&headers, state.mempool_strategy(), &uri, |q| {
q.live_histogram_raw()
})
.await
},
|op| {
op.id("get_oracle_histogram_raw_live")
.oracle_tag()
.summary("Live raw histogram")
.description(
"Un-smoothed per-block round-dollar counts for the forming mempool \
block: the spiky primitive the EMA smooths over. A flat array of \
2400 log-scale bins (`u32` counts), all zero when no mempool is \
configured.",
)
.json_response::<HistogramRaw>()
.not_modified()
.server_error()
},
),
)
.api_route(
"/api/oracle/histogram/raw/{height}",
get_with(
async |uri: Uri,
headers: HeaderMap,
Path(path): Path<HeightParam>,
_: Empty,
State(state): State<AppState>| {
let strategy = state.height_strategy(Version::new(brk_oracle::VERSION), path.height);
state
.respond_json(&headers, strategy, &uri, move |q| {
q.confirmed_histogram_raw(usize::from(path.height))
})
.await
},
|op| {
op.id("get_oracle_histogram_raw")
.oracle_tag()
.summary("Raw histogram at height")
.description(
"Un-smoothed round-dollar counts for a single confirmed block. A \
flat array of 2400 log-scale bins (`u32` counts).",
)
.json_response::<HistogramRaw>()
.not_modified()
.bad_request()
.not_found()
.server_error()
},
),
)
}
}