cash/closest: return 404 when no oracle price within 2h of timestamp
Prevents returning stale v1 data as if it were the price for a gap-period timestamp (Apr 23–May 4 2026). If the closest indexed entry is more than MAX_ORACLE_STALENESS_SECS (7200s) away, respond with PriceNotFound 404 instead of silently returning wrong data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
62c5b2ff4a
commit
7c196faf87
1 changed files with 17 additions and 9 deletions
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use crate::db::oracle::{get_closest, get_range, get_range_with_step};
|
||||
use crate::db::DB;
|
||||
use crate::rpc::err::{bad_request, db_error, ApiErrorCode, CachedApiResult};
|
||||
use crate::rpc::err::{bad_request, db_error, not_found, ApiErrorCode, CachedApiResult};
|
||||
use crate::rpc::response::{cached_ok, CACHE_AGGREGATE};
|
||||
use crate::timeutil::time_now;
|
||||
use bitcoin_hashes::hex::FromHex;
|
||||
|
|
@ -193,9 +193,13 @@ pub async fn oracle_get_history(
|
|||
))
|
||||
}
|
||||
|
||||
/// Delphi oracle updates roughly every 5–15 minutes. An entry more than 2 hours
|
||||
/// older than the requested timestamp means there is genuinely no price for that
|
||||
/// period (e.g. the Apr 23–May 4 2026 gap between v1 and v2).
|
||||
const MAX_ORACLE_STALENESS_SECS: i64 = 7200;
|
||||
|
||||
/// Get the closest BCH/USD price for a given timestamp.
|
||||
/// Backed by Delphi v2 (and v1 for historical timestamps).
|
||||
/// Returns `null` if no data is available.
|
||||
/// Returns 404 if no oracle price is available within 2 hours of the timestamp.
|
||||
#[get("/cash/closest?<timestamp>")]
|
||||
pub async fn oracle_cash_closest(
|
||||
timestamp: Option<i64>,
|
||||
|
|
@ -205,12 +209,16 @@ pub async fn oracle_cash_closest(
|
|||
let entry = get_closest(&db.oracle_r, &None, ts)
|
||||
.await
|
||||
.map_err(db_error)?;
|
||||
Ok(cached_ok(
|
||||
entry.map_or(serde_json::Value::Null, |e| {
|
||||
serde_json::to_value(e).unwrap()
|
||||
}),
|
||||
CACHE_AGGREGATE,
|
||||
))
|
||||
|
||||
match entry {
|
||||
Some(e) if ts - e.oracle_timestamp <= MAX_ORACLE_STALENESS_SECS => {
|
||||
Ok(cached_ok(serde_json::to_value(e).unwrap(), CACHE_AGGREGATE))
|
||||
}
|
||||
_ => Err(not_found(
|
||||
ApiErrorCode::PriceNotFound,
|
||||
&format!("No oracle price available for timestamp {ts}"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get historical BCH/USD prices for a time range.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue