mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snap
This commit is contained in:
@@ -88,13 +88,14 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
|
||||
|
||||
let path = build_path_template(&endpoint.path, &endpoint.path_params);
|
||||
|
||||
let fetch_call = if endpoint.returns_json() {
|
||||
"this.getJson(path, { signal, onUpdate })"
|
||||
} else {
|
||||
"this.getText(path, { signal })"
|
||||
};
|
||||
|
||||
if endpoint.query_params.is_empty() {
|
||||
writeln!(
|
||||
output,
|
||||
" return this.getJson(`{}`, {{ signal, onUpdate }});",
|
||||
path
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " const path = `{}`;", path).unwrap();
|
||||
} else {
|
||||
writeln!(output, " const params = new URLSearchParams();").unwrap();
|
||||
for param in &endpoint.query_params {
|
||||
@@ -122,25 +123,13 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
|
||||
path
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if endpoint.supports_csv {
|
||||
writeln!(output, " if (format === 'csv') {{").unwrap();
|
||||
writeln!(output, " return this.getText(path, {{ signal }});").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" return this.getJson(path, {{ signal, onUpdate }});"
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(
|
||||
output,
|
||||
" return this.getJson(path, {{ signal, onUpdate }});"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
if endpoint.supports_csv {
|
||||
writeln!(output, " if (format === 'csv') return this.getText(path, {{ signal }});").unwrap();
|
||||
}
|
||||
writeln!(output, " return {};", fetch_call).unwrap();
|
||||
|
||||
writeln!(output, " }}\n").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4799,7 +4799,6 @@ impl SeriesTree_Indexes_Addr_OpReturn {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Height {
|
||||
pub identity: SeriesPattern18<Height>,
|
||||
pub minute10: SeriesPattern18<Minute10>,
|
||||
pub minute30: SeriesPattern18<Minute30>,
|
||||
pub hour1: SeriesPattern18<Hour1>,
|
||||
@@ -4821,7 +4820,6 @@ pub struct SeriesTree_Indexes_Height {
|
||||
impl SeriesTree_Indexes_Height {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern18::new(client.clone(), "height".to_string()),
|
||||
minute10: SeriesPattern18::new(client.clone(), "minute10".to_string()),
|
||||
minute30: SeriesPattern18::new(client.clone(), "minute30".to_string()),
|
||||
hour1: SeriesPattern18::new(client.clone(), "hour1".to_string()),
|
||||
@@ -4844,31 +4842,25 @@ impl SeriesTree_Indexes_Height {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Epoch {
|
||||
pub identity: SeriesPattern17<Epoch>,
|
||||
pub first_height: SeriesPattern17<Height>,
|
||||
pub height_count: SeriesPattern17<StoredU64>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Epoch {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern17::new(client.clone(), "epoch".to_string()),
|
||||
first_height: SeriesPattern17::new(client.clone(), "first_height".to_string()),
|
||||
height_count: SeriesPattern17::new(client.clone(), "height_count".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Halving {
|
||||
pub identity: SeriesPattern16<Halving>,
|
||||
pub first_height: SeriesPattern16<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Halving {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern16::new(client.clone(), "halving".to_string()),
|
||||
first_height: SeriesPattern16::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4876,14 +4868,12 @@ impl SeriesTree_Indexes_Halving {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Minute10 {
|
||||
pub identity: SeriesPattern3<Minute10>,
|
||||
pub first_height: SeriesPattern3<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Minute10 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern3::new(client.clone(), "minute10_index".to_string()),
|
||||
first_height: SeriesPattern3::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4891,14 +4881,12 @@ impl SeriesTree_Indexes_Minute10 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Minute30 {
|
||||
pub identity: SeriesPattern4<Minute30>,
|
||||
pub first_height: SeriesPattern4<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Minute30 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern4::new(client.clone(), "minute30_index".to_string()),
|
||||
first_height: SeriesPattern4::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4906,14 +4894,12 @@ impl SeriesTree_Indexes_Minute30 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Hour1 {
|
||||
pub identity: SeriesPattern5<Hour1>,
|
||||
pub first_height: SeriesPattern5<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Hour1 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern5::new(client.clone(), "hour1_index".to_string()),
|
||||
first_height: SeriesPattern5::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4921,14 +4907,12 @@ impl SeriesTree_Indexes_Hour1 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Hour4 {
|
||||
pub identity: SeriesPattern6<Hour4>,
|
||||
pub first_height: SeriesPattern6<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Hour4 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern6::new(client.clone(), "hour4_index".to_string()),
|
||||
first_height: SeriesPattern6::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4936,14 +4920,12 @@ impl SeriesTree_Indexes_Hour4 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Hour12 {
|
||||
pub identity: SeriesPattern7<Hour12>,
|
||||
pub first_height: SeriesPattern7<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Hour12 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern7::new(client.clone(), "hour12_index".to_string()),
|
||||
first_height: SeriesPattern7::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4951,33 +4933,29 @@ impl SeriesTree_Indexes_Hour12 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Day1 {
|
||||
pub identity: SeriesPattern8<Day1>,
|
||||
pub date: SeriesPattern8<Date>,
|
||||
pub first_height: SeriesPattern8<Height>,
|
||||
pub height_count: SeriesPattern8<StoredU64>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Day1 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern8::new(client.clone(), "day1_index".to_string()),
|
||||
date: SeriesPattern8::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern8::new(client.clone(), "first_height".to_string()),
|
||||
height_count: SeriesPattern8::new(client.clone(), "height_count".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Day3 {
|
||||
pub identity: SeriesPattern9<Day3>,
|
||||
pub date: SeriesPattern9<Date>,
|
||||
pub first_height: SeriesPattern9<Height>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Indexes_Day3 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern9::new(client.clone(), "day3_index".to_string()),
|
||||
date: SeriesPattern9::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern9::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
}
|
||||
@@ -4985,7 +4963,6 @@ impl SeriesTree_Indexes_Day3 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Week1 {
|
||||
pub identity: SeriesPattern10<Week1>,
|
||||
pub date: SeriesPattern10<Date>,
|
||||
pub first_height: SeriesPattern10<Height>,
|
||||
}
|
||||
@@ -4993,7 +4970,6 @@ pub struct SeriesTree_Indexes_Week1 {
|
||||
impl SeriesTree_Indexes_Week1 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern10::new(client.clone(), "week1_index".to_string()),
|
||||
date: SeriesPattern10::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern10::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
@@ -5002,7 +4978,6 @@ impl SeriesTree_Indexes_Week1 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Month1 {
|
||||
pub identity: SeriesPattern11<Month1>,
|
||||
pub date: SeriesPattern11<Date>,
|
||||
pub first_height: SeriesPattern11<Height>,
|
||||
}
|
||||
@@ -5010,7 +4985,6 @@ pub struct SeriesTree_Indexes_Month1 {
|
||||
impl SeriesTree_Indexes_Month1 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern11::new(client.clone(), "month1_index".to_string()),
|
||||
date: SeriesPattern11::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern11::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
@@ -5019,7 +4993,6 @@ impl SeriesTree_Indexes_Month1 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Month3 {
|
||||
pub identity: SeriesPattern12<Month3>,
|
||||
pub date: SeriesPattern12<Date>,
|
||||
pub first_height: SeriesPattern12<Height>,
|
||||
}
|
||||
@@ -5027,7 +5000,6 @@ pub struct SeriesTree_Indexes_Month3 {
|
||||
impl SeriesTree_Indexes_Month3 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern12::new(client.clone(), "month3_index".to_string()),
|
||||
date: SeriesPattern12::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern12::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
@@ -5036,7 +5008,6 @@ impl SeriesTree_Indexes_Month3 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Month6 {
|
||||
pub identity: SeriesPattern13<Month6>,
|
||||
pub date: SeriesPattern13<Date>,
|
||||
pub first_height: SeriesPattern13<Height>,
|
||||
}
|
||||
@@ -5044,7 +5015,6 @@ pub struct SeriesTree_Indexes_Month6 {
|
||||
impl SeriesTree_Indexes_Month6 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern13::new(client.clone(), "month6_index".to_string()),
|
||||
date: SeriesPattern13::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern13::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
@@ -5053,7 +5023,6 @@ impl SeriesTree_Indexes_Month6 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Year1 {
|
||||
pub identity: SeriesPattern14<Year1>,
|
||||
pub date: SeriesPattern14<Date>,
|
||||
pub first_height: SeriesPattern14<Height>,
|
||||
}
|
||||
@@ -5061,7 +5030,6 @@ pub struct SeriesTree_Indexes_Year1 {
|
||||
impl SeriesTree_Indexes_Year1 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern14::new(client.clone(), "year1_index".to_string()),
|
||||
date: SeriesPattern14::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern14::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
@@ -5070,7 +5038,6 @@ impl SeriesTree_Indexes_Year1 {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Indexes_Year10 {
|
||||
pub identity: SeriesPattern15<Year10>,
|
||||
pub date: SeriesPattern15<Date>,
|
||||
pub first_height: SeriesPattern15<Height>,
|
||||
}
|
||||
@@ -5078,7 +5045,6 @@ pub struct SeriesTree_Indexes_Year10 {
|
||||
impl SeriesTree_Indexes_Year10 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
identity: SeriesPattern15::new(client.clone(), "year10_index".to_string()),
|
||||
date: SeriesPattern15::new(client.clone(), "date".to_string()),
|
||||
first_height: SeriesPattern15::new(client.clone(), "first_height".to_string()),
|
||||
}
|
||||
@@ -8712,6 +8678,15 @@ impl BrkClient {
|
||||
self.base.get_json(&format!("/api/server/sync"))
|
||||
}
|
||||
|
||||
/// Txid by index
|
||||
///
|
||||
/// Retrieve the transaction ID (txid) at a given global transaction index. Returns the txid as plain text.
|
||||
///
|
||||
/// Endpoint: `GET /api/tx-index/{index}`
|
||||
pub fn get_tx_by_index(&self, index: TxIndex) -> Result<String> {
|
||||
self.base.get_text(&format!("/api/tx-index/{index}"))
|
||||
}
|
||||
|
||||
/// Transaction information
|
||||
///
|
||||
/// Retrieve complete transaction data by transaction ID (txid). Returns inputs, outputs, fee, size, and confirmation status.
|
||||
|
||||
@@ -417,7 +417,11 @@ impl Query {
|
||||
first_seen: None,
|
||||
};
|
||||
|
||||
blocks.push(BlockInfoV1 { info, extras });
|
||||
blocks.push(BlockInfoV1 {
|
||||
info,
|
||||
stale: false,
|
||||
extras,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(blocks)
|
||||
|
||||
@@ -3,10 +3,10 @@ use std::{collections::BTreeMap, sync::LazyLock};
|
||||
use brk_error::{Error, Result};
|
||||
use brk_traversable::TreeNode;
|
||||
use brk_types::{
|
||||
Date, DetailedSeriesCount, Epoch, Etag, Format, Halving, Height, Index, IndexInfo, LegacyValue,
|
||||
Limit, Output, OutputLegacy, PaginatedSeries, Pagination, PaginationIndex, RangeIndex,
|
||||
RangeMap, SearchQuery, SeriesData, SeriesInfo, SeriesName, SeriesOutput, SeriesOutputLegacy,
|
||||
SeriesSelection, Timestamp, Version,
|
||||
BlockHashPrefix, Date, DetailedSeriesCount, Epoch, Etag, Format, Halving, Height, Index,
|
||||
IndexInfo, LegacyValue, Limit, Output, OutputLegacy, PaginatedSeries, Pagination,
|
||||
PaginationIndex, RangeIndex, RangeMap, SearchQuery, SeriesData, SeriesInfo, SeriesName,
|
||||
SeriesOutput, SeriesOutputLegacy, SeriesSelection, Timestamp, Version,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use vecdb::{AnyExportableVec, ReadableVec};
|
||||
@@ -204,7 +204,7 @@ impl Query {
|
||||
total,
|
||||
start,
|
||||
end,
|
||||
height: *self.height(),
|
||||
hash_prefix: self.tip_hash_prefix(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -458,12 +458,12 @@ pub struct ResolvedQuery {
|
||||
pub total: usize,
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
pub height: u32,
|
||||
pub hash_prefix: BlockHashPrefix,
|
||||
}
|
||||
|
||||
impl ResolvedQuery {
|
||||
pub fn etag(&self) -> Etag {
|
||||
Etag::from_series(self.version, self.total, self.start, self.end, self.height)
|
||||
Etag::from_series(self.version, self.total, self.end, self.hash_prefix)
|
||||
}
|
||||
|
||||
pub fn format(&self) -> Format {
|
||||
|
||||
@@ -4,7 +4,7 @@ use brk_types::{
|
||||
BlockHash, Height, MerkleProof, Timestamp, Transaction, TxInIndex, TxIndex, TxOutIndex,
|
||||
TxOutspend, TxStatus, Txid, TxidPrefix, Vin, Vout,
|
||||
};
|
||||
use vecdb::{ReadableVec, VecIndex};
|
||||
use vecdb::{AnyVec, ReadableVec, VecIndex};
|
||||
|
||||
use crate::Query;
|
||||
|
||||
@@ -23,6 +23,19 @@ impl Query {
|
||||
.ok_or(Error::UnknownTxid)
|
||||
}
|
||||
|
||||
pub fn txid_by_index(&self, index: TxIndex) -> Result<Txid> {
|
||||
let len = self.indexer().vecs.transactions.txid.len();
|
||||
if index.to_usize() >= len {
|
||||
return Err(Error::OutOfRange("Transaction index out of range".into()));
|
||||
}
|
||||
self.indexer()
|
||||
.vecs
|
||||
.transactions
|
||||
.txid
|
||||
.collect_one(index)
|
||||
.ok_or_else(|| Error::OutOfRange("Transaction index out of range".into()))
|
||||
}
|
||||
|
||||
/// Resolve a txid to (TxIndex, Height).
|
||||
pub fn resolve_tx(&self, txid: &Txid) -> Result<(TxIndex, Height)> {
|
||||
let tx_index = self.resolve_tx_index(txid)?;
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
AppState, CacheStrategy,
|
||||
cache::CacheParams,
|
||||
extended::{ResponseExtended, TransformResponseExtended},
|
||||
params::{TxidParam, TxidVout, TxidsParam},
|
||||
params::{TxIndexParam, TxidParam, TxidVout, TxidsParam},
|
||||
};
|
||||
|
||||
pub trait TxRoutes {
|
||||
@@ -23,6 +23,24 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
fn add_tx_routes(self) -> Self {
|
||||
self
|
||||
.api_route(
|
||||
"/api/tx-index/{index}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxIndexParam>, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, CacheStrategy::Immutable(Version::ONE), &uri, move |q| q.txid_by_index(param.index).map(|t| t.to_string())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_by_index")
|
||||
.transactions_tag()
|
||||
.summary("Txid by index")
|
||||
.description("Retrieve the transaction ID (txid) at a given global transaction index. Returns the txid as plain text.")
|
||||
.text_response()
|
||||
.not_modified()
|
||||
.bad_request()
|
||||
.not_found()
|
||||
.server_error(),
|
||||
),
|
||||
)
|
||||
.api_route(
|
||||
"/api/v1/cpfp/{txid}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, State(state): State<AppState>| {
|
||||
|
||||
@@ -197,7 +197,6 @@ impl Server {
|
||||
let router = router
|
||||
.with_state(state)
|
||||
.merge(website_router)
|
||||
.layer(compression_layer)
|
||||
.layer(response_time_layer)
|
||||
.layer(trace_layer)
|
||||
.layer(CatchPanicLayer::custom(|panic: Box<dyn Any + Send>| {
|
||||
@@ -213,6 +212,7 @@ impl Server {
|
||||
Duration::from_secs(5),
|
||||
))
|
||||
.layer(json_error_layer)
|
||||
.layer(compression_layer)
|
||||
.layer(CorsLayer::permissive())
|
||||
.layer(axum::middleware::from_fn(
|
||||
async |request: Request<Body>, next: Next| -> Response<Body> {
|
||||
|
||||
@@ -11,6 +11,7 @@ mod pool_slug_param;
|
||||
mod series_param;
|
||||
mod time_period_param;
|
||||
mod timestamp_param;
|
||||
mod tx_index_param;
|
||||
mod txid_param;
|
||||
mod txid_vout;
|
||||
mod txids_param;
|
||||
@@ -29,6 +30,7 @@ pub use pool_slug_param::*;
|
||||
pub use series_param::*;
|
||||
pub use time_period_param::*;
|
||||
pub use timestamp_param::*;
|
||||
pub use tx_index_param::*;
|
||||
pub use txid_param::*;
|
||||
pub use txid_vout::*;
|
||||
pub use txids_param::*;
|
||||
|
||||
10
crates/brk_server/src/params/tx_index_param.rs
Normal file
10
crates/brk_server/src/params/tx_index_param.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use brk_types::TxIndex;
|
||||
|
||||
/// Transaction index path parameter
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
pub struct TxIndexParam {
|
||||
pub index: TxIndex,
|
||||
}
|
||||
@@ -72,7 +72,7 @@ impl AddrValidation {
|
||||
let output_type = OutputType::from(&script);
|
||||
let script_hex = script.as_bytes().to_lower_hex_string();
|
||||
|
||||
let is_script = matches!(output_type, OutputType::P2SH);
|
||||
let is_script = matches!(output_type, OutputType::P2SH | OutputType::P2TR);
|
||||
let is_witness = matches!(
|
||||
output_type,
|
||||
OutputType::P2WPKH | OutputType::P2WSH | OutputType::P2TR | OutputType::P2A
|
||||
|
||||
@@ -10,6 +10,10 @@ pub struct BlockInfoV1 {
|
||||
#[serde(flatten)]
|
||||
pub info: BlockInfo,
|
||||
|
||||
/// Whether this block has been replaced by a longer chain
|
||||
#[serde(default)]
|
||||
pub stale: bool,
|
||||
|
||||
/// Extended block data
|
||||
pub extras: BlockExtras,
|
||||
}
|
||||
|
||||
@@ -52,4 +52,5 @@ impl DataRange {
|
||||
pub fn limit(&self) -> Option<Limit> {
|
||||
self.limit
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use super::{BlockHashPrefix, Version};
|
||||
|
||||
/// HTTP ETag value.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Etag(String);
|
||||
@@ -40,27 +42,20 @@ impl From<&str> for Etag {
|
||||
}
|
||||
|
||||
impl Etag {
|
||||
/// Create ETag from series data response info.
|
||||
///
|
||||
/// Format varies based on whether the slice touches the end:
|
||||
/// - Slice ends before total: `{version:x}-{start}-{end}` (len irrelevant, data won't change if series grows)
|
||||
/// - Slice reaches the end: `{version:x}-{start}-{total}-{height}` (includes height since last value may be recomputed each block)
|
||||
///
|
||||
/// `version` is the series version for single queries, or the sum of versions for bulk queries.
|
||||
/// Tail uses hash prefix (changes per-block and on reorgs),
|
||||
/// non-tail uses total (changes per-block).
|
||||
pub fn from_series(
|
||||
version: super::Version,
|
||||
version: Version,
|
||||
total: usize,
|
||||
start: usize,
|
||||
end: usize,
|
||||
height: u32,
|
||||
hash_prefix: BlockHashPrefix,
|
||||
) -> Self {
|
||||
let v = u32::from(version);
|
||||
if end < total {
|
||||
// Fixed window not at the end - len doesn't matter
|
||||
Self(format!("{v:x}-{start}-{end}"))
|
||||
if end >= total {
|
||||
let h = *hash_prefix;
|
||||
Self(format!("v{v}-{h:x}"))
|
||||
} else {
|
||||
// Fetching up to current end - include height since last value may change each block
|
||||
Self(format!("{v:x}-{start}-{total}-{height}"))
|
||||
Self(format!("v{v}-{total}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user