mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-22 04:18:50 -07:00
global: snapshot
This commit is contained in:
+275
-275
@@ -1268,56 +1268,6 @@ impl Price111dSmaPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActivePriceRatioPattern {
|
||||
pub ratio: MetricPattern4<StoredF32>,
|
||||
pub ratio_1m_sma: MetricPattern4<StoredF32>,
|
||||
pub ratio_1w_sma: MetricPattern4<StoredF32>,
|
||||
pub ratio_1y_sd: Ratio1ySdPattern,
|
||||
pub ratio_2y_sd: Ratio1ySdPattern,
|
||||
pub ratio_4y_sd: Ratio1ySdPattern,
|
||||
pub ratio_pct1: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct1_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct2: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct2_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct5: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct5_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct95: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct95_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct98: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct98_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct99: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct99_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_sd: Ratio1ySdPattern,
|
||||
}
|
||||
|
||||
impl ActivePriceRatioPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ratio: MetricPattern4::new(client.clone(), acc.clone()),
|
||||
ratio_1m_sma: MetricPattern4::new(client.clone(), _m(&acc, "1m_sma")),
|
||||
ratio_1w_sma: MetricPattern4::new(client.clone(), _m(&acc, "1w_sma")),
|
||||
ratio_1y_sd: Ratio1ySdPattern::new(client.clone(), _m(&acc, "1y")),
|
||||
ratio_2y_sd: Ratio1ySdPattern::new(client.clone(), _m(&acc, "2y")),
|
||||
ratio_4y_sd: Ratio1ySdPattern::new(client.clone(), _m(&acc, "4y")),
|
||||
ratio_pct1: MetricPattern4::new(client.clone(), _m(&acc, "pct1")),
|
||||
ratio_pct1_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct1_usd")),
|
||||
ratio_pct2: MetricPattern4::new(client.clone(), _m(&acc, "pct2")),
|
||||
ratio_pct2_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct2_usd")),
|
||||
ratio_pct5: MetricPattern4::new(client.clone(), _m(&acc, "pct5")),
|
||||
ratio_pct5_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct5_usd")),
|
||||
ratio_pct95: MetricPattern4::new(client.clone(), _m(&acc, "pct95")),
|
||||
ratio_pct95_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct95_usd")),
|
||||
ratio_pct98: MetricPattern4::new(client.clone(), _m(&acc, "pct98")),
|
||||
ratio_pct98_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct98_usd")),
|
||||
ratio_pct99: MetricPattern4::new(client.clone(), _m(&acc, "pct99")),
|
||||
ratio_pct99_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct99_usd")),
|
||||
ratio_sd: Ratio1ySdPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct PercentilesPattern {
|
||||
pub pct05: MetricPattern4<Dollars>,
|
||||
@@ -1368,6 +1318,56 @@ impl PercentilesPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActivePriceRatioPattern {
|
||||
pub ratio: MetricPattern4<StoredF32>,
|
||||
pub ratio_1m_sma: MetricPattern4<StoredF32>,
|
||||
pub ratio_1w_sma: MetricPattern4<StoredF32>,
|
||||
pub ratio_1y_sd: Ratio1ySdPattern,
|
||||
pub ratio_2y_sd: Ratio1ySdPattern,
|
||||
pub ratio_4y_sd: Ratio1ySdPattern,
|
||||
pub ratio_pct1: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct1_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct2: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct2_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct5: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct5_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct95: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct95_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct98: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct98_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_pct99: MetricPattern4<StoredF32>,
|
||||
pub ratio_pct99_usd: MetricPattern4<Dollars>,
|
||||
pub ratio_sd: Ratio1ySdPattern,
|
||||
}
|
||||
|
||||
impl ActivePriceRatioPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ratio: MetricPattern4::new(client.clone(), acc.clone()),
|
||||
ratio_1m_sma: MetricPattern4::new(client.clone(), _m(&acc, "1m_sma")),
|
||||
ratio_1w_sma: MetricPattern4::new(client.clone(), _m(&acc, "1w_sma")),
|
||||
ratio_1y_sd: Ratio1ySdPattern::new(client.clone(), _m(&acc, "1y")),
|
||||
ratio_2y_sd: Ratio1ySdPattern::new(client.clone(), _m(&acc, "2y")),
|
||||
ratio_4y_sd: Ratio1ySdPattern::new(client.clone(), _m(&acc, "4y")),
|
||||
ratio_pct1: MetricPattern4::new(client.clone(), _m(&acc, "pct1")),
|
||||
ratio_pct1_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct1_usd")),
|
||||
ratio_pct2: MetricPattern4::new(client.clone(), _m(&acc, "pct2")),
|
||||
ratio_pct2_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct2_usd")),
|
||||
ratio_pct5: MetricPattern4::new(client.clone(), _m(&acc, "pct5")),
|
||||
ratio_pct5_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct5_usd")),
|
||||
ratio_pct95: MetricPattern4::new(client.clone(), _m(&acc, "pct95")),
|
||||
ratio_pct95_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct95_usd")),
|
||||
ratio_pct98: MetricPattern4::new(client.clone(), _m(&acc, "pct98")),
|
||||
ratio_pct98_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct98_usd")),
|
||||
ratio_pct99: MetricPattern4::new(client.clone(), _m(&acc, "pct99")),
|
||||
ratio_pct99_usd: MetricPattern4::new(client.clone(), _m(&acc, "pct99_usd")),
|
||||
ratio_sd: Ratio1ySdPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct RelativePattern5 {
|
||||
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
@@ -1600,40 +1600,6 @@ impl BitcoinPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct DollarsPattern<T> {
|
||||
pub average: MetricPattern2<T>,
|
||||
pub base: MetricPattern11<T>,
|
||||
pub cumulative: MetricPattern1<T>,
|
||||
pub max: MetricPattern2<T>,
|
||||
pub median: MetricPattern6<T>,
|
||||
pub min: MetricPattern2<T>,
|
||||
pub pct10: MetricPattern6<T>,
|
||||
pub pct25: MetricPattern6<T>,
|
||||
pub pct75: MetricPattern6<T>,
|
||||
pub pct90: MetricPattern6<T>,
|
||||
pub sum: MetricPattern2<T>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> DollarsPattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
average: MetricPattern2::new(client.clone(), _m(&acc, "average")),
|
||||
base: MetricPattern11::new(client.clone(), acc.clone()),
|
||||
cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")),
|
||||
max: MetricPattern2::new(client.clone(), _m(&acc, "max")),
|
||||
median: MetricPattern6::new(client.clone(), _m(&acc, "median")),
|
||||
min: MetricPattern2::new(client.clone(), _m(&acc, "min")),
|
||||
pct10: MetricPattern6::new(client.clone(), _m(&acc, "pct10")),
|
||||
pct25: MetricPattern6::new(client.clone(), _m(&acc, "pct25")),
|
||||
pct75: MetricPattern6::new(client.clone(), _m(&acc, "pct75")),
|
||||
pct90: MetricPattern6::new(client.clone(), _m(&acc, "pct90")),
|
||||
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ClassAveragePricePattern<T> {
|
||||
pub _2015: MetricPattern4<T>,
|
||||
@@ -1669,33 +1635,35 @@ impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct RelativePattern {
|
||||
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub net_unrealized_pnl_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub nupl: MetricPattern1<StoredF32>,
|
||||
pub supply_in_loss_rel_to_circulating_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_in_profit_rel_to_circulating_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_rel_to_circulating_supply: MetricPattern4<StoredF64>,
|
||||
pub unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub unrealized_profit_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub struct DollarsPattern<T> {
|
||||
pub average: MetricPattern2<T>,
|
||||
pub base: MetricPattern11<T>,
|
||||
pub cumulative: MetricPattern1<T>,
|
||||
pub max: MetricPattern2<T>,
|
||||
pub median: MetricPattern6<T>,
|
||||
pub min: MetricPattern2<T>,
|
||||
pub pct10: MetricPattern6<T>,
|
||||
pub pct25: MetricPattern6<T>,
|
||||
pub pct75: MetricPattern6<T>,
|
||||
pub pct90: MetricPattern6<T>,
|
||||
pub sum: MetricPattern2<T>,
|
||||
}
|
||||
|
||||
impl RelativePattern {
|
||||
impl<T: DeserializeOwned> DollarsPattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_market_cap")),
|
||||
net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_market_cap")),
|
||||
nupl: MetricPattern1::new(client.clone(), _m(&acc, "nupl")),
|
||||
supply_in_loss_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_circulating_supply")),
|
||||
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")),
|
||||
supply_in_profit_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_circulating_supply")),
|
||||
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")),
|
||||
supply_rel_to_circulating_supply: MetricPattern4::new(client.clone(), _m(&acc, "supply_rel_to_circulating_supply")),
|
||||
unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_market_cap")),
|
||||
unrealized_profit_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_market_cap")),
|
||||
average: MetricPattern2::new(client.clone(), _m(&acc, "average")),
|
||||
base: MetricPattern11::new(client.clone(), acc.clone()),
|
||||
cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")),
|
||||
max: MetricPattern2::new(client.clone(), _m(&acc, "max")),
|
||||
median: MetricPattern6::new(client.clone(), _m(&acc, "median")),
|
||||
min: MetricPattern2::new(client.clone(), _m(&acc, "min")),
|
||||
pct10: MetricPattern6::new(client.clone(), _m(&acc, "pct10")),
|
||||
pct25: MetricPattern6::new(client.clone(), _m(&acc, "pct25")),
|
||||
pct75: MetricPattern6::new(client.clone(), _m(&acc, "pct75")),
|
||||
pct90: MetricPattern6::new(client.clone(), _m(&acc, "pct90")),
|
||||
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1732,6 +1700,38 @@ impl RelativePattern2 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct RelativePattern {
|
||||
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub net_unrealized_pnl_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub nupl: MetricPattern1<StoredF32>,
|
||||
pub supply_in_loss_rel_to_circulating_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_in_profit_rel_to_circulating_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
|
||||
pub supply_rel_to_circulating_supply: MetricPattern4<StoredF64>,
|
||||
pub unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
pub unrealized_profit_rel_to_market_cap: MetricPattern1<StoredF32>,
|
||||
}
|
||||
|
||||
impl RelativePattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_market_cap")),
|
||||
net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_market_cap")),
|
||||
nupl: MetricPattern1::new(client.clone(), _m(&acc, "nupl")),
|
||||
supply_in_loss_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_circulating_supply")),
|
||||
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")),
|
||||
supply_in_profit_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_circulating_supply")),
|
||||
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")),
|
||||
supply_rel_to_circulating_supply: MetricPattern4::new(client.clone(), _m(&acc, "supply_rel_to_circulating_supply")),
|
||||
unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_market_cap")),
|
||||
unrealized_profit_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_market_cap")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CountPattern2<T> {
|
||||
pub average: MetricPattern1<T>,
|
||||
@@ -1794,36 +1794,6 @@ impl AddrCountPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct FeeRatePattern<T> {
|
||||
pub average: MetricPattern1<T>,
|
||||
pub max: MetricPattern1<T>,
|
||||
pub median: MetricPattern11<T>,
|
||||
pub min: MetricPattern1<T>,
|
||||
pub pct10: MetricPattern11<T>,
|
||||
pub pct25: MetricPattern11<T>,
|
||||
pub pct75: MetricPattern11<T>,
|
||||
pub pct90: MetricPattern11<T>,
|
||||
pub txindex: MetricPattern27<T>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> FeeRatePattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
average: MetricPattern1::new(client.clone(), _m(&acc, "average")),
|
||||
max: MetricPattern1::new(client.clone(), _m(&acc, "max")),
|
||||
median: MetricPattern11::new(client.clone(), _m(&acc, "median")),
|
||||
min: MetricPattern1::new(client.clone(), _m(&acc, "min")),
|
||||
pct10: MetricPattern11::new(client.clone(), _m(&acc, "pct10")),
|
||||
pct25: MetricPattern11::new(client.clone(), _m(&acc, "pct25")),
|
||||
pct75: MetricPattern11::new(client.clone(), _m(&acc, "pct75")),
|
||||
pct90: MetricPattern11::new(client.clone(), _m(&acc, "pct90")),
|
||||
txindex: MetricPattern27::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct FullnessPattern<T> {
|
||||
pub average: MetricPattern2<T>,
|
||||
@@ -1854,6 +1824,36 @@ impl<T: DeserializeOwned> FullnessPattern<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct FeeRatePattern<T> {
|
||||
pub average: MetricPattern1<T>,
|
||||
pub max: MetricPattern1<T>,
|
||||
pub median: MetricPattern11<T>,
|
||||
pub min: MetricPattern1<T>,
|
||||
pub pct10: MetricPattern11<T>,
|
||||
pub pct25: MetricPattern11<T>,
|
||||
pub pct75: MetricPattern11<T>,
|
||||
pub pct90: MetricPattern11<T>,
|
||||
pub txindex: MetricPattern27<T>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> FeeRatePattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
average: MetricPattern1::new(client.clone(), _m(&acc, "average")),
|
||||
max: MetricPattern1::new(client.clone(), _m(&acc, "max")),
|
||||
median: MetricPattern11::new(client.clone(), _m(&acc, "median")),
|
||||
min: MetricPattern1::new(client.clone(), _m(&acc, "min")),
|
||||
pct10: MetricPattern11::new(client.clone(), _m(&acc, "pct10")),
|
||||
pct25: MetricPattern11::new(client.clone(), _m(&acc, "pct25")),
|
||||
pct75: MetricPattern11::new(client.clone(), _m(&acc, "pct75")),
|
||||
pct90: MetricPattern11::new(client.clone(), _m(&acc, "pct90")),
|
||||
txindex: MetricPattern27::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _0satsPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
@@ -1910,32 +1910,6 @@ impl<T: DeserializeOwned> PhaseDailyCentsPattern<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _10yPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern4,
|
||||
pub relative: RelativePattern,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _10yPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: RealizedPattern4::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct UnrealizedPattern {
|
||||
pub neg_unrealized_loss: MetricPattern1<Dollars>,
|
||||
@@ -1963,25 +1937,25 @@ impl UnrealizedPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _0satsPattern2 {
|
||||
pub struct _10yTo12yPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub cost_basis: CostBasisPattern2,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern4,
|
||||
pub realized: RealizedPattern2,
|
||||
pub relative: RelativePattern2,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _0satsPattern2 {
|
||||
impl _10yTo12yPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
|
||||
realized: RealizedPattern2::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern2::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
@@ -2014,6 +1988,32 @@ impl PeriodCagrPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _10yPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern4,
|
||||
pub relative: RelativePattern,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _10yPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: RealizedPattern4::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _100btcPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
@@ -2041,25 +2041,25 @@ impl _100btcPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _10yTo12yPattern {
|
||||
pub struct _0satsPattern2 {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern2,
|
||||
pub relative: RelativePattern2,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern4,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _10yTo12yPattern {
|
||||
impl _0satsPattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: RealizedPattern2::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern2::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
@@ -2108,6 +2108,42 @@ impl<T: DeserializeOwned> SplitPattern2<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _2015Pattern {
|
||||
pub bitcoin: MetricPattern4<Bitcoin>,
|
||||
pub dollars: MetricPattern4<Dollars>,
|
||||
pub sats: MetricPattern4<Sats>,
|
||||
}
|
||||
|
||||
impl _2015Pattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: MetricPattern4::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: MetricPattern4::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: MetricPattern4::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActiveSupplyPattern {
|
||||
pub bitcoin: MetricPattern1<Bitcoin>,
|
||||
pub dollars: MetricPattern1<Dollars>,
|
||||
pub sats: MetricPattern1<Sats>,
|
||||
}
|
||||
|
||||
impl ActiveSupplyPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CostBasisPattern2 {
|
||||
pub max: MetricPattern1<Dollars>,
|
||||
@@ -2126,6 +2162,24 @@ impl CostBasisPattern2 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CoinbasePattern2 {
|
||||
pub bitcoin: BlockCountPattern<Bitcoin>,
|
||||
pub dollars: BlockCountPattern<Dollars>,
|
||||
pub sats: BlockCountPattern<Sats>,
|
||||
}
|
||||
|
||||
impl CoinbasePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: BlockCountPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SegwitAdoptionPattern {
|
||||
pub base: MetricPattern11<StoredF32>,
|
||||
@@ -2162,60 +2216,6 @@ impl CoinbasePattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _2015Pattern {
|
||||
pub bitcoin: MetricPattern4<Bitcoin>,
|
||||
pub dollars: MetricPattern4<Dollars>,
|
||||
pub sats: MetricPattern4<Sats>,
|
||||
}
|
||||
|
||||
impl _2015Pattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: MetricPattern4::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: MetricPattern4::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: MetricPattern4::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CoinbasePattern2 {
|
||||
pub bitcoin: BlockCountPattern<Bitcoin>,
|
||||
pub dollars: BlockCountPattern<Dollars>,
|
||||
pub sats: BlockCountPattern<Sats>,
|
||||
}
|
||||
|
||||
impl CoinbasePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: BlockCountPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActiveSupplyPattern {
|
||||
pub bitcoin: MetricPattern1<Bitcoin>,
|
||||
pub dollars: MetricPattern1<Dollars>,
|
||||
pub sats: MetricPattern1<Sats>,
|
||||
}
|
||||
|
||||
impl ActiveSupplyPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct UnclaimedRewardsPattern {
|
||||
pub bitcoin: BitcoinPattern2<Bitcoin>,
|
||||
@@ -2234,22 +2234,6 @@ impl UnclaimedRewardsPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1dReturns1mSdPattern {
|
||||
pub sd: MetricPattern4<StoredF32>,
|
||||
pub sma: MetricPattern4<StoredF32>,
|
||||
}
|
||||
|
||||
impl _1dReturns1mSdPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
sd: MetricPattern4::new(client.clone(), _m(&acc, "sd")),
|
||||
sma: MetricPattern4::new(client.clone(), _m(&acc, "sma")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SupplyPattern2 {
|
||||
pub halved: ActiveSupplyPattern,
|
||||
@@ -2298,6 +2282,22 @@ impl CostBasisPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1dReturns1mSdPattern {
|
||||
pub sd: MetricPattern4<StoredF32>,
|
||||
pub sma: MetricPattern4<StoredF32>,
|
||||
}
|
||||
|
||||
impl _1dReturns1mSdPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
sd: MetricPattern4::new(client.clone(), _m(&acc, "sd")),
|
||||
sma: MetricPattern4::new(client.clone(), _m(&acc, "sma")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct BitcoinPattern2<T> {
|
||||
pub cumulative: MetricPattern2<T>,
|
||||
@@ -2340,22 +2340,8 @@ impl<T: DeserializeOwned> SatsPattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc_sats")),
|
||||
split: SplitPattern2::new(client.clone(), _m(&acc, "sats")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct OutputsPattern {
|
||||
pub utxo_count: MetricPattern1<StoredU64>,
|
||||
}
|
||||
|
||||
impl OutputsPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc")),
|
||||
split: SplitPattern2::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2374,6 +2360,20 @@ impl RealizedPriceExtraPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct OutputsPattern {
|
||||
pub utxo_count: MetricPattern1<StoredU64>,
|
||||
}
|
||||
|
||||
impl OutputsPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics tree
|
||||
|
||||
/// Metrics tree node.
|
||||
@@ -3932,7 +3932,7 @@ pub struct MetricsTree_Indexes_Height {
|
||||
impl MetricsTree_Indexes_Height {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
dateindex: MetricPattern11::new(client.clone(), "height_dateindex".to_string()),
|
||||
dateindex: MetricPattern11::new(client.clone(), "dateindex".to_string()),
|
||||
difficultyepoch: MetricPattern11::new(client.clone(), "difficultyepoch".to_string()),
|
||||
halvingepoch: MetricPattern11::new(client.clone(), "halvingepoch".to_string()),
|
||||
identity: MetricPattern11::new(client.clone(), "height".to_string()),
|
||||
@@ -4942,8 +4942,8 @@ impl MetricsTree_Positions {
|
||||
pub struct MetricsTree_Price {
|
||||
pub cents: MetricsTree_Price_Cents,
|
||||
pub oracle: MetricsTree_Price_Oracle,
|
||||
pub sats: SatsPattern<OHLCSats>,
|
||||
pub usd: MetricsTree_Price_Usd,
|
||||
pub sats: MetricsTree_Price_Sats,
|
||||
pub usd: SatsPattern<OHLCDollars>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Price {
|
||||
@@ -4951,8 +4951,8 @@ impl MetricsTree_Price {
|
||||
Self {
|
||||
cents: MetricsTree_Price_Cents::new(client.clone(), format!("{base_path}_cents")),
|
||||
oracle: MetricsTree_Price_Oracle::new(client.clone(), format!("{base_path}_oracle")),
|
||||
sats: SatsPattern::new(client.clone(), "price".to_string()),
|
||||
usd: MetricsTree_Price_Usd::new(client.clone(), format!("{base_path}_usd")),
|
||||
sats: MetricsTree_Price_Sats::new(client.clone(), format!("{base_path}_sats")),
|
||||
usd: SatsPattern::new(client.clone(), "price".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5027,16 +5027,16 @@ impl MetricsTree_Price_Oracle {
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Price_Usd {
|
||||
pub ohlc: MetricPattern1<OHLCDollars>,
|
||||
pub split: SplitPattern2<Dollars>,
|
||||
pub struct MetricsTree_Price_Sats {
|
||||
pub ohlc: MetricPattern1<OHLCSats>,
|
||||
pub split: SplitPattern2<Sats>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Price_Usd {
|
||||
impl MetricsTree_Price_Sats {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
ohlc: MetricPattern1::new(client.clone(), "price_ohlc".to_string()),
|
||||
split: SplitPattern2::new(client.clone(), "price".to_string()),
|
||||
ohlc: MetricPattern1::new(client.clone(), "price_ohlc_sats".to_string()),
|
||||
split: SplitPattern2::new(client.clone(), "price_sats".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
identity: EagerVec::forced_import(db, "height", version)?,
|
||||
dateindex: EagerVec::forced_import(db, "height_dateindex", version)?,
|
||||
dateindex: EagerVec::forced_import(db, "dateindex", version)?,
|
||||
difficultyepoch: EagerVec::forced_import(db, "difficultyepoch", version)?,
|
||||
halvingepoch: EagerVec::forced_import(db, "halvingepoch", version)?,
|
||||
txindex_count: EagerVec::forced_import(db, "txindex_count", version)?,
|
||||
|
||||
@@ -24,8 +24,8 @@ impl Vecs {
|
||||
let phase_histogram = BytesVec::forced_import(db, "phase_histogram", version)?;
|
||||
|
||||
// Layer 5: Phase Oracle prices
|
||||
// v32: Revert to simple anchor-based decade selection (no prev_price tracking)
|
||||
let phase_version = version + Version::new(25);
|
||||
// v45: Back to decades (10x) + anchor only
|
||||
let phase_version = version + Version::new(38);
|
||||
let phase_price_cents = PcoVec::forced_import(db, "phase_price_cents", phase_version)?;
|
||||
let phase_daily_cents = Distribution::forced_import(db, "phase_daily", phase_version)?;
|
||||
let phase_daily_dollars = LazyTransformDistribution::from_distribution::<CentsToDollars>(
|
||||
|
||||
@@ -33,7 +33,7 @@ serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tower-http = { version = "0.6.8", features = ["compression-full", "trace"] }
|
||||
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-full", "cors", "normalize-path", "timeout", "trace"] }
|
||||
|
||||
[build-dependencies]
|
||||
# importmap = { path = "../../../importmap" }
|
||||
|
||||
@@ -14,7 +14,8 @@ fn main() {
|
||||
let map = if is_dev {
|
||||
importmap::ImportMap::empty()
|
||||
} else {
|
||||
importmap::ImportMap::scan(&website_path, "").unwrap_or_else(|_| importmap::ImportMap::empty())
|
||||
importmap::ImportMap::scan(&website_path, "")
|
||||
.unwrap_or_else(|_| importmap::ImportMap::empty())
|
||||
};
|
||||
|
||||
let _ = map.update_html_file(&website_path.join("index.html"));
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::HeaderMap,
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use axum::{extract::State, http::HeaderMap, response::Redirect, routing::get};
|
||||
use brk_types::{MempoolBlock, MempoolInfo, RecommendedFees, Txid};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
|
||||
@@ -6,6 +6,7 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_types::{Format, MetricSelection, Output};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
@@ -24,12 +25,7 @@ pub async fn handler(
|
||||
) -> Response {
|
||||
match req_to_response_res(uri, headers, query, state).await {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
response
|
||||
}
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,19 +34,16 @@ async fn req_to_response_res(
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<MetricSelection>,
|
||||
AppState { query, cache, .. }: AppState,
|
||||
) -> brk_error::Result<Response> {
|
||||
) -> Result<Response> {
|
||||
// Phase 1: Search and resolve metadata (cheap)
|
||||
let resolved = query
|
||||
.run(move |q| q.resolve(params, MAX_WEIGHT))
|
||||
.await?;
|
||||
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
|
||||
|
||||
let format = resolved.format();
|
||||
let etag = resolved.etag();
|
||||
|
||||
// Check if client has fresh cache
|
||||
if headers.has_etag(etag.as_str()) {
|
||||
let mut response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
let response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
@@ -81,7 +74,6 @@ async fn req_to_response_res(
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_etag(etag.as_str());
|
||||
headers.insert_cache_control(CACHE_CONTROL);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_types::{Format, MetricSelection, Output};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
@@ -24,12 +25,7 @@ pub async fn handler(
|
||||
) -> Response {
|
||||
match req_to_response_res(uri, headers, query, state).await {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
response
|
||||
}
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,19 +34,16 @@ async fn req_to_response_res(
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<MetricSelection>,
|
||||
AppState { query, cache, .. }: AppState,
|
||||
) -> brk_error::Result<Response> {
|
||||
) -> Result<Response> {
|
||||
// Phase 1: Search and resolve metadata (cheap)
|
||||
let resolved = query
|
||||
.run(move |q| q.resolve(params, MAX_WEIGHT))
|
||||
.await?;
|
||||
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
|
||||
|
||||
let format = resolved.format();
|
||||
let etag = resolved.etag();
|
||||
|
||||
// Check if client has fresh cache
|
||||
if headers.has_etag(etag.as_str()) {
|
||||
let mut response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
let response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
@@ -81,7 +74,6 @@ async fn req_to_response_res(
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_etag(etag.as_str());
|
||||
headers.insert_cache_control(CACHE_CONTROL);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_types::{Format, MetricSelection, OutputLegacy};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
@@ -24,12 +25,7 @@ pub async fn handler(
|
||||
) -> Response {
|
||||
match req_to_response_res(uri, headers, query, state).await {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
response
|
||||
}
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,19 +34,16 @@ async fn req_to_response_res(
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<MetricSelection>,
|
||||
AppState { query, cache, .. }: AppState,
|
||||
) -> brk_error::Result<Response> {
|
||||
) -> Result<Response> {
|
||||
// Phase 1: Search and resolve metadata (cheap)
|
||||
let resolved = query
|
||||
.run(move |q| q.resolve(params, MAX_WEIGHT))
|
||||
.await?;
|
||||
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
|
||||
|
||||
let format = resolved.format();
|
||||
let etag = resolved.etag();
|
||||
|
||||
// Check if client has fresh cache
|
||||
if headers.has_etag(etag.as_str()) {
|
||||
let mut response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
let response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
@@ -62,9 +55,7 @@ async fn req_to_response_res(
|
||||
Response::new(Body::from(v))
|
||||
} else {
|
||||
// Phase 2: Format (expensive, only on cache miss)
|
||||
let metric_output = query
|
||||
.run(move |q| q.format_legacy(resolved))
|
||||
.await?;
|
||||
let metric_output = query.run(move |q| q.format_legacy(resolved)).await?;
|
||||
|
||||
match metric_output.output {
|
||||
OutputLegacy::CSV(s) => {
|
||||
@@ -84,7 +75,6 @@ async fn req_to_response_res(
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_etag(etag.as_str());
|
||||
headers.insert_cache_control(CACHE_CONTROL);
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ use axum::{
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{
|
||||
BlockCountParam, BlockFeesEntry, BlockRewardsEntry, BlockSizesWeights,
|
||||
DifficultyAdjustment, DifficultyAdjustmentEntry, HashrateSummary, PoolDetail, PoolInfo,
|
||||
PoolSlugParam, PoolsSummary, RewardStats, TimePeriodParam,
|
||||
BlockCountParam, BlockFeesEntry, BlockRewardsEntry, BlockSizesWeights, DifficultyAdjustment,
|
||||
DifficultyAdjustmentEntry, HashrateSummary, PoolDetail, PoolInfo, PoolSlugParam, PoolsSummary,
|
||||
RewardStats, TimePeriodParam,
|
||||
};
|
||||
|
||||
use crate::{CacheStrategy, extended::TransformResponseExtended};
|
||||
|
||||
@@ -377,7 +377,10 @@ mod tests {
|
||||
|
||||
let props = &parsed["components"]["schemas"]["AddressStats"]["properties"];
|
||||
assert_eq!(props["address"], "Address", "address should be simplified");
|
||||
assert_eq!(props["chain_stats"], "AddressChainStats", "chain_stats should be simplified");
|
||||
assert_eq!(
|
||||
props["chain_stats"], "AddressChainStats",
|
||||
"chain_stats should be simplified"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -19,8 +19,6 @@ pub enum ModifiedState {
|
||||
}
|
||||
|
||||
pub trait HeaderMapExtended {
|
||||
fn insert_cors(&mut self);
|
||||
|
||||
fn has_etag(&self, etag: &str) -> bool;
|
||||
|
||||
fn get_if_modified_since(&self) -> Option<DateTime>;
|
||||
@@ -52,11 +50,6 @@ pub trait HeaderMapExtended {
|
||||
}
|
||||
|
||||
impl HeaderMapExtended for HeaderMap {
|
||||
fn insert_cors(&mut self) {
|
||||
self.insert(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*".parse().unwrap());
|
||||
self.insert(header::ACCESS_CONTROL_ALLOW_HEADERS, "*".parse().unwrap());
|
||||
}
|
||||
|
||||
fn insert_cache_control(&mut self, value: &str) {
|
||||
self.insert(header::CACHE_CONTROL, value.parse().unwrap());
|
||||
}
|
||||
|
||||
@@ -36,8 +36,7 @@ where
|
||||
impl ResponseExtended for Response<Body> {
|
||||
fn new_not_modified() -> Response<Body> {
|
||||
let mut response = (StatusCode::NOT_MODIFIED, "").into_response();
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
let _headers = response.headers_mut();
|
||||
response
|
||||
}
|
||||
|
||||
@@ -56,7 +55,6 @@ impl ResponseExtended for Response<Body> {
|
||||
let mut response = Response::builder().body(bytes.into()).unwrap();
|
||||
*response.status_mut() = status;
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type_application_json();
|
||||
headers.insert_cache_control_must_revalidate();
|
||||
headers.insert_etag(etag);
|
||||
@@ -68,12 +66,9 @@ impl ResponseExtended for Response<Body> {
|
||||
}
|
||||
|
||||
fn new_text_with(status: StatusCode, value: &str, etag: &str) -> Self {
|
||||
let mut response = Response::builder()
|
||||
.body(value.to_string().into())
|
||||
.unwrap();
|
||||
let mut response = Response::builder().body(value.to_string().into()).unwrap();
|
||||
*response.status_mut() = status;
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type_text_plain();
|
||||
headers.insert_cache_control_must_revalidate();
|
||||
headers.insert_etag(etag);
|
||||
@@ -88,7 +83,6 @@ impl ResponseExtended for Response<Body> {
|
||||
let mut response = Response::builder().body(value.into()).unwrap();
|
||||
*response.status_mut() = status;
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type_octet_stream();
|
||||
headers.insert_cache_control_must_revalidate();
|
||||
headers.insert_etag(etag);
|
||||
@@ -102,7 +96,6 @@ impl ResponseExtended for Response<Body> {
|
||||
let bytes = serde_json::to_vec(&value).unwrap();
|
||||
let mut response = Response::builder().body(bytes.into()).unwrap();
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type_application_json();
|
||||
headers.insert_cache_control(¶ms.cache_control);
|
||||
if let Some(etag) = ¶ms.etag {
|
||||
@@ -123,11 +116,8 @@ impl ResponseExtended for Response<Body> {
|
||||
}
|
||||
|
||||
fn new_text_cached(value: &str, params: &CacheParams) -> Self {
|
||||
let mut response = Response::builder()
|
||||
.body(value.to_string().into())
|
||||
.unwrap();
|
||||
let mut response = Response::builder().body(value.to_string().into()).unwrap();
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type_text_plain();
|
||||
headers.insert_cache_control(¶ms.cache_control);
|
||||
if let Some(etag) = ¶ms.etag {
|
||||
@@ -139,7 +129,6 @@ impl ResponseExtended for Response<Body> {
|
||||
fn new_bytes_cached(value: Vec<u8>, params: &CacheParams) -> Self {
|
||||
let mut response = Response::builder().body(value.into()).unwrap();
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type_octet_stream();
|
||||
headers.insert_cache_control(¶ms.cache_control);
|
||||
if let Some(etag) = ¶ms.etag {
|
||||
|
||||
@@ -81,7 +81,6 @@ fn build_response(state: &AppState, path: &Path, content: Vec<u8>, cache_key: &s
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type(path);
|
||||
|
||||
if cfg!(debug_assertions) || must_revalidate {
|
||||
@@ -114,9 +113,8 @@ fn embedded_handler(state: &AppState, path: Option<String>) -> Response {
|
||||
});
|
||||
|
||||
let Some(file) = file else {
|
||||
let mut response: Response<Body> =
|
||||
let response: Response<Body> =
|
||||
(StatusCode::NOT_FOUND, "File not found".to_string()).into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
return response;
|
||||
};
|
||||
|
||||
@@ -147,9 +145,8 @@ fn filesystem_handler(
|
||||
let allowed = canonical.starts_with(&canonical_base)
|
||||
|| project_root.is_some_and(|root| canonical.starts_with(root));
|
||||
if !allowed {
|
||||
let mut response: Response<Body> =
|
||||
let response: Response<Body> =
|
||||
(StatusCode::FORBIDDEN, "Access denied".to_string()).into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -165,12 +162,11 @@ fn filesystem_handler(
|
||||
// SPA fallback
|
||||
if !path.exists() || path.is_dir() {
|
||||
if path.extension().is_some() {
|
||||
let mut response: Response<Body> = (
|
||||
let response: Response<Body> = (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"File doesn't exist".to_string(),
|
||||
)
|
||||
.into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
return response;
|
||||
} else {
|
||||
path = files_path.join("index.html");
|
||||
@@ -188,12 +184,7 @@ fn filesystem_handler(
|
||||
fn path_to_response(headers: &HeaderMap, state: &AppState, path: &Path) -> Response {
|
||||
match path_to_response_(headers, state, path) {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
response.headers_mut().insert_cors();
|
||||
response
|
||||
}
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use std::{panic, path::PathBuf, sync::Arc, time::{Duration, Instant}};
|
||||
use std::{
|
||||
panic,
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use aide::axum::ApiRouter;
|
||||
use axum::{
|
||||
@@ -14,10 +19,14 @@ use axum::{
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_query::AsyncQuery;
|
||||
use include_dir::{include_dir, Dir};
|
||||
use include_dir::{Dir, include_dir};
|
||||
use quick_cache::sync::Cache;
|
||||
use tokio::net::TcpListener;
|
||||
use tower_http::{compression::CompressionLayer, trace::TraceLayer};
|
||||
use tower_http::{
|
||||
catch_panic::CatchPanicLayer, classify::ServerErrorsFailureClass,
|
||||
compression::CompressionLayer, cors::CorsLayer, normalize_path::NormalizePathLayer,
|
||||
timeout::TimeoutLayer, trace::TraceLayer,
|
||||
};
|
||||
use tracing::{error, info};
|
||||
|
||||
/// Embedded website assets
|
||||
@@ -86,19 +95,25 @@ impl Server {
|
||||
|
||||
let trace_layer = TraceLayer::new_for_http()
|
||||
.on_request(())
|
||||
.on_response(|response: &Response<Body>, latency: Duration, _: &tracing::Span| {
|
||||
let status = response.status().as_u16();
|
||||
let uri = response.extensions().get::<Uri>().unwrap();
|
||||
match response.status() {
|
||||
StatusCode::OK => info!(status, %uri, ?latency),
|
||||
StatusCode::NOT_MODIFIED
|
||||
| StatusCode::TEMPORARY_REDIRECT
|
||||
| StatusCode::PERMANENT_REDIRECT => info!(status, %uri, ?latency),
|
||||
_ => error!(status, %uri, ?latency),
|
||||
}
|
||||
})
|
||||
.on_response(
|
||||
|response: &Response<Body>, latency: Duration, _: &tracing::Span| {
|
||||
let status = response.status().as_u16();
|
||||
let uri = response.extensions().get::<Uri>().unwrap();
|
||||
match response.status() {
|
||||
StatusCode::OK => info!(status, %uri, ?latency),
|
||||
StatusCode::NOT_MODIFIED
|
||||
| StatusCode::TEMPORARY_REDIRECT
|
||||
| StatusCode::PERMANENT_REDIRECT => info!(status, %uri, ?latency),
|
||||
_ => error!(status, %uri, ?latency),
|
||||
}
|
||||
},
|
||||
)
|
||||
.on_body_chunk(())
|
||||
.on_failure(())
|
||||
.on_failure(
|
||||
|error: ServerErrorsFailureClass, latency: Duration, _: &tracing::Span| {
|
||||
error!(?error, ?latency, "request failed");
|
||||
},
|
||||
)
|
||||
.on_eos(());
|
||||
|
||||
let vecs = state.query.inner().vecs();
|
||||
@@ -126,9 +141,13 @@ impl Server {
|
||||
)
|
||||
.route("/nostr", get(Redirect::temporary("https://primal.net/p/npub1jagmm3x39lmwfnrtvxcs9ac7g300y3dusv9lgzhk2e4x5frpxlrqa73v44")))
|
||||
.with_state(state)
|
||||
.layer(CatchPanicLayer::new())
|
||||
.layer(compression_layer)
|
||||
.layer(response_uri_layer)
|
||||
.layer(trace_layer);
|
||||
.layer(trace_layer)
|
||||
.layer(TimeoutLayer::with_status_code(StatusCode::GATEWAY_TIMEOUT, Duration::from_secs(5)))
|
||||
.layer(CorsLayer::permissive())
|
||||
.layer(NormalizePathLayer::trim_trailing_slash());
|
||||
|
||||
const BASE_PORT: u16 = 3110;
|
||||
const MAX_PORT: u16 = BASE_PORT + 100;
|
||||
|
||||
Reference in New Issue
Block a user