global: opreturn part 5

This commit is contained in:
nym21
2026-07-19 18:19:48 +02:00
parent 0fc61d7932
commit 3af673132a
10 changed files with 523 additions and 454 deletions
+86 -104
View File
@@ -2001,6 +2001,30 @@ impl CentsNegativeToUsdPattern2 {
}
}
/// Pattern struct for repeated tree structure.
pub struct ChainDataOutputTxPattern {
pub chain_share: BpsPercentRatioPattern2,
pub data_bytes: AverageBlockCumulativeSumPattern<StoredU64>,
pub data_share: BpsPercentRatioPattern2,
pub output_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub tx_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub tx_vsize: AverageBlockCumulativeSumPattern<VSize>,
}
impl ChainDataOutputTxPattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
chain_share: BpsPercentRatioPattern2::new(client.clone(), _m(&acc, "chain_share")),
data_bytes: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "data_bytes")),
data_share: BpsPercentRatioPattern2::new(client.clone(), _m(&acc, "data_share")),
output_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "output_count")),
tx_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "tx_count")),
tx_vsize: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "tx_vsize")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct DeltaDominanceHalfInTotalPattern2 {
pub delta: AbsoluteRatePattern3,
@@ -2291,28 +2315,6 @@ impl CapLossMvrvPriceProfitPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct CarrierDataOutputPostPattern {
pub carrier_tx_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub carrier_vsize: AverageBlockCumulativeSumPattern<VSize>,
pub data_share: BpsPercentRatioPattern2,
pub output_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub post_op_return_bytes: AverageBlockCumulativeSumPattern<StoredU64>,
}
impl CarrierDataOutputPostPattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
carrier_tx_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "carrier_tx_count")),
carrier_vsize: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "carrier_vsize")),
data_share: BpsPercentRatioPattern2::new(client.clone(), _m(&acc, "data_share")),
output_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "output_count")),
post_op_return_bytes: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "post_op_return_bytes")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CentsToUsdPattern4 {
pub cents: SeriesPattern1<Cents>,
@@ -2674,26 +2676,6 @@ impl BtcCentsSatsUsdPattern3 {
}
}
/// Pattern struct for repeated tree structure.
pub struct CarrierOutputPostPattern {
pub carrier_tx_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub carrier_vsize: AverageBlockCumulativeSumPattern<VSize>,
pub output_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub post_op_return_bytes: AverageBlockCumulativeSumPattern<StoredU64>,
}
impl CarrierOutputPostPattern {
/// Create a new pattern node with accumulated series name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
carrier_tx_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "carrier_tx_count")),
carrier_vsize: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "carrier_vsize")),
output_count: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "output_count")),
post_op_return_bytes: AverageBlockCumulativeSumPattern::new(client.clone(), _m(&acc, "post_op_return_bytes")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CentsDeltaToUsdPattern {
pub cents: SeriesPattern1<Cents>,
@@ -5407,95 +5389,95 @@ impl SeriesTree_OpReturn_Raw {
/// Series tree node.
pub struct SeriesTree_OpReturn_Total {
pub post_op_return_bytes: AverageBlockCumulativeSumPattern<StoredU64>,
pub carrier_tx_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub carrier_vsize: AverageBlockCumulativeSumPattern<VSize>,
pub data_share: BpsPercentRatioPattern2,
pub data_bytes: AverageBlockCumulativeSumPattern<StoredU64>,
pub tx_count: AverageBlockCumulativeSumPattern<StoredU64>,
pub tx_vsize: AverageBlockCumulativeSumPattern<VSize>,
pub chain_share: BpsPercentRatioPattern2,
}
impl SeriesTree_OpReturn_Total {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
post_op_return_bytes: AverageBlockCumulativeSumPattern::new(client.clone(), "op_return_post_op_return_bytes".to_string()),
carrier_tx_count: AverageBlockCumulativeSumPattern::new(client.clone(), "op_return_carrier_tx_count".to_string()),
carrier_vsize: AverageBlockCumulativeSumPattern::new(client.clone(), "op_return_carrier_vsize".to_string()),
data_share: BpsPercentRatioPattern2::new(client.clone(), "op_return_data_share".to_string()),
data_bytes: AverageBlockCumulativeSumPattern::new(client.clone(), "op_return_data_bytes".to_string()),
tx_count: AverageBlockCumulativeSumPattern::new(client.clone(), "op_return_tx_count".to_string()),
tx_vsize: AverageBlockCumulativeSumPattern::new(client.clone(), "op_return_tx_vsize".to_string()),
chain_share: BpsPercentRatioPattern2::new(client.clone(), "op_return_chain_share".to_string()),
}
}
}
/// Series tree node.
pub struct SeriesTree_OpReturn_ByKind {
pub runes: CarrierOutputPostPattern,
pub veri_block: CarrierOutputPostPattern,
pub omni: CarrierOutputPostPattern,
pub stacks: CarrierOutputPostPattern,
pub blockstack: CarrierOutputPostPattern,
pub colu: CarrierOutputPostPattern,
pub open_assets: CarrierOutputPostPattern,
pub komodo: CarrierOutputPostPattern,
pub coin_spark: CarrierOutputPostPattern,
pub poet: CarrierOutputPostPattern,
pub docproof: CarrierOutputPostPattern,
pub open_timestamps: CarrierOutputPostPattern,
pub factom: CarrierOutputPostPattern,
pub eternity_wall: CarrierOutputPostPattern,
pub memo: CarrierOutputPostPattern,
pub bitproof: CarrierOutputPostPattern,
pub ascribe: CarrierOutputPostPattern,
pub stampery: CarrierOutputPostPattern,
pub epobc: CarrierOutputPostPattern,
pub bare_hash: CarrierOutputPostPattern,
pub text: CarrierOutputPostPattern,
pub empty: CarrierOutputPostPattern,
pub unknown: CarrierOutputPostPattern,
pub runes: ChainDataOutputTxPattern,
pub veri_block: ChainDataOutputTxPattern,
pub omni: ChainDataOutputTxPattern,
pub stacks: ChainDataOutputTxPattern,
pub blockstack: ChainDataOutputTxPattern,
pub colu: ChainDataOutputTxPattern,
pub open_assets: ChainDataOutputTxPattern,
pub komodo: ChainDataOutputTxPattern,
pub coin_spark: ChainDataOutputTxPattern,
pub poet: ChainDataOutputTxPattern,
pub docproof: ChainDataOutputTxPattern,
pub open_timestamps: ChainDataOutputTxPattern,
pub factom: ChainDataOutputTxPattern,
pub eternity_wall: ChainDataOutputTxPattern,
pub memo: ChainDataOutputTxPattern,
pub bitproof: ChainDataOutputTxPattern,
pub ascribe: ChainDataOutputTxPattern,
pub stampery: ChainDataOutputTxPattern,
pub epobc: ChainDataOutputTxPattern,
pub bare_hash: ChainDataOutputTxPattern,
pub text: ChainDataOutputTxPattern,
pub empty: ChainDataOutputTxPattern,
pub unknown: ChainDataOutputTxPattern,
}
impl SeriesTree_OpReturn_ByKind {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
runes: CarrierOutputPostPattern::new(client.clone(), "op_return_runes".to_string()),
veri_block: CarrierOutputPostPattern::new(client.clone(), "op_return_veri_block".to_string()),
omni: CarrierOutputPostPattern::new(client.clone(), "op_return_omni".to_string()),
stacks: CarrierOutputPostPattern::new(client.clone(), "op_return_stacks".to_string()),
blockstack: CarrierOutputPostPattern::new(client.clone(), "op_return_blockstack".to_string()),
colu: CarrierOutputPostPattern::new(client.clone(), "op_return_colu".to_string()),
open_assets: CarrierOutputPostPattern::new(client.clone(), "op_return_open_assets".to_string()),
komodo: CarrierOutputPostPattern::new(client.clone(), "op_return_komodo".to_string()),
coin_spark: CarrierOutputPostPattern::new(client.clone(), "op_return_coin_spark".to_string()),
poet: CarrierOutputPostPattern::new(client.clone(), "op_return_poet".to_string()),
docproof: CarrierOutputPostPattern::new(client.clone(), "op_return_docproof".to_string()),
open_timestamps: CarrierOutputPostPattern::new(client.clone(), "op_return_open_timestamps".to_string()),
factom: CarrierOutputPostPattern::new(client.clone(), "op_return_factom".to_string()),
eternity_wall: CarrierOutputPostPattern::new(client.clone(), "op_return_eternity_wall".to_string()),
memo: CarrierOutputPostPattern::new(client.clone(), "op_return_memo".to_string()),
bitproof: CarrierOutputPostPattern::new(client.clone(), "op_return_bitproof".to_string()),
ascribe: CarrierOutputPostPattern::new(client.clone(), "op_return_ascribe".to_string()),
stampery: CarrierOutputPostPattern::new(client.clone(), "op_return_stampery".to_string()),
epobc: CarrierOutputPostPattern::new(client.clone(), "op_return_epobc".to_string()),
bare_hash: CarrierOutputPostPattern::new(client.clone(), "op_return_bare_hash".to_string()),
text: CarrierOutputPostPattern::new(client.clone(), "op_return_text".to_string()),
empty: CarrierOutputPostPattern::new(client.clone(), "op_return_empty".to_string()),
unknown: CarrierOutputPostPattern::new(client.clone(), "op_return_unknown".to_string()),
runes: ChainDataOutputTxPattern::new(client.clone(), "op_return_runes".to_string()),
veri_block: ChainDataOutputTxPattern::new(client.clone(), "op_return_veri_block".to_string()),
omni: ChainDataOutputTxPattern::new(client.clone(), "op_return_omni".to_string()),
stacks: ChainDataOutputTxPattern::new(client.clone(), "op_return_stacks".to_string()),
blockstack: ChainDataOutputTxPattern::new(client.clone(), "op_return_blockstack".to_string()),
colu: ChainDataOutputTxPattern::new(client.clone(), "op_return_colu".to_string()),
open_assets: ChainDataOutputTxPattern::new(client.clone(), "op_return_open_assets".to_string()),
komodo: ChainDataOutputTxPattern::new(client.clone(), "op_return_komodo".to_string()),
coin_spark: ChainDataOutputTxPattern::new(client.clone(), "op_return_coin_spark".to_string()),
poet: ChainDataOutputTxPattern::new(client.clone(), "op_return_poet".to_string()),
docproof: ChainDataOutputTxPattern::new(client.clone(), "op_return_docproof".to_string()),
open_timestamps: ChainDataOutputTxPattern::new(client.clone(), "op_return_open_timestamps".to_string()),
factom: ChainDataOutputTxPattern::new(client.clone(), "op_return_factom".to_string()),
eternity_wall: ChainDataOutputTxPattern::new(client.clone(), "op_return_eternity_wall".to_string()),
memo: ChainDataOutputTxPattern::new(client.clone(), "op_return_memo".to_string()),
bitproof: ChainDataOutputTxPattern::new(client.clone(), "op_return_bitproof".to_string()),
ascribe: ChainDataOutputTxPattern::new(client.clone(), "op_return_ascribe".to_string()),
stampery: ChainDataOutputTxPattern::new(client.clone(), "op_return_stampery".to_string()),
epobc: ChainDataOutputTxPattern::new(client.clone(), "op_return_epobc".to_string()),
bare_hash: ChainDataOutputTxPattern::new(client.clone(), "op_return_bare_hash".to_string()),
text: ChainDataOutputTxPattern::new(client.clone(), "op_return_text".to_string()),
empty: ChainDataOutputTxPattern::new(client.clone(), "op_return_empty".to_string()),
unknown: ChainDataOutputTxPattern::new(client.clone(), "op_return_unknown".to_string()),
}
}
}
/// Series tree node.
pub struct SeriesTree_OpReturn_Policy {
pub standard: CarrierDataOutputPostPattern,
pub oversized: CarrierDataOutputPostPattern,
pub multiple: CarrierDataOutputPostPattern,
pub pre_v30_nonstandard: CarrierDataOutputPostPattern,
pub pre_v30_standard: ChainDataOutputTxPattern,
pub pre_v30_nonstandard: ChainDataOutputTxPattern,
pub oversized: ChainDataOutputTxPattern,
pub multiple: ChainDataOutputTxPattern,
}
impl SeriesTree_OpReturn_Policy {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
standard: CarrierDataOutputPostPattern::new(client.clone(), "op_return_policy_standard".to_string()),
oversized: CarrierDataOutputPostPattern::new(client.clone(), "op_return_policy_oversized".to_string()),
multiple: CarrierDataOutputPostPattern::new(client.clone(), "op_return_policy_multiple".to_string()),
pre_v30_nonstandard: CarrierDataOutputPostPattern::new(client.clone(), "op_return_policy_pre_v30_nonstandard".to_string()),
pre_v30_standard: ChainDataOutputTxPattern::new(client.clone(), "op_return_policy_pre_v30_standard".to_string()),
pre_v30_nonstandard: ChainDataOutputTxPattern::new(client.clone(), "op_return_policy_pre_v30_nonstandard".to_string()),
oversized: ChainDataOutputTxPattern::new(client.clone(), "op_return_policy_oversized".to_string()),
multiple: ChainDataOutputTxPattern::new(client.clone(), "op_return_policy_multiple".to_string()),
}
}
}
+65 -43
View File
@@ -3,7 +3,7 @@ use brk_indexer::Indexer;
use brk_types::{BasisPoints16, Height, OpReturnKind, StoredU64, VSize};
use vecdb::{AnyVec, Exit, ReadableVec, VecIndex};
use super::{Vecs, vecs::Totals};
use super::{Breakdown, Vecs, vecs::Totals};
use crate::{
blocks,
internal::{PercentPerBlock, RatioU64Bp16},
@@ -15,30 +15,30 @@ const WRITE_INTERVAL: usize = 10_000;
#[derive(Clone, Copy, Default)]
struct PolicyTotals {
standard: Totals,
pre_v30_standard: Totals,
pre_v30_nonstandard: Totals,
oversized: Totals,
multiple: Totals,
pre_v30_nonstandard: Totals,
}
#[derive(Clone, Copy, Default)]
struct Carrier {
kinds: u32,
output_count: u64,
post_op_return_bytes: u64,
data_bytes: u64,
oversized_output_count: u64,
oversized_post_op_return_bytes: u64,
oversized_data_bytes: u64,
vsize: VSize,
}
impl Carrier {
fn add_output(&mut self, kind: OpReturnKind, post_op_return_bytes: u64) {
fn add_output(&mut self, kind: OpReturnKind, data_bytes: u64) {
self.kinds |= kind_bit(kind);
self.output_count += 1;
self.post_op_return_bytes += post_op_return_bytes;
if post_op_return_bytes > OLD_STANDARD_MAX_POST_OP_RETURN_BYTES {
self.data_bytes += data_bytes;
if data_bytes > OLD_STANDARD_MAX_POST_OP_RETURN_BYTES {
self.oversized_output_count += 1;
self.oversized_post_op_return_bytes += post_op_return_bytes;
self.oversized_data_bytes += data_bytes;
}
}
}
@@ -110,9 +110,9 @@ impl Vecs {
carrier.vsize = VSize::from(weight_cursor.next().unwrap());
}
total.post_op_return_bytes += bytes;
total.data_bytes += bytes;
by_kind[kind_index].output_count += 1;
by_kind[kind_index].post_op_return_bytes += bytes;
by_kind[kind_index].data_bytes += bytes;
carrier.add_output(kind, bytes);
}
@@ -122,12 +122,12 @@ impl Vecs {
for (kind, metrics) in self.by_kind.iter_typed_mut() {
metrics.push(by_kind[kind as usize]);
}
self.policy.standard.push(policy.standard);
self.policy.oversized.push(policy.oversized);
self.policy.multiple.push(policy.multiple);
self.policy.pre_v30_standard.push(policy.pre_v30_standard);
self.policy
.pre_v30_nonstandard
.push(policy.pre_v30_nonstandard);
self.policy.oversized.push(policy.oversized);
self.policy.multiple.push(policy.multiple);
if (height + 1).is_multiple_of(WRITE_INTERVAL) {
let _lock = exit.lock();
@@ -144,16 +144,26 @@ impl Vecs {
let block_size = &blocks.size.size.cumulative.height;
compute_data_share(
starting_lengths.height,
&mut self.total.data_share,
&self.total.metrics.post_op_return_bytes.cumulative.height,
&mut self.total.chain_share,
&self.total.metrics.data_bytes.cumulative.height,
block_size,
exit,
)?;
for policy in self.policy.iter_mut() {
compute_data_share(
let total_data = &self.total.metrics.data_bytes.cumulative.height;
for breakdown in self.by_kind.iter_mut() {
compute_breakdown_data_shares(
starting_lengths.height,
&mut policy.data_share,
&policy.metrics.total.post_op_return_bytes.cumulative.height,
breakdown,
total_data,
block_size,
exit,
)?;
}
for policy in self.policy.iter_mut() {
compute_breakdown_data_shares(
starting_lengths.height,
policy,
total_data,
block_size,
exit,
)?;
@@ -168,6 +178,18 @@ impl Vecs {
}
}
fn compute_breakdown_data_shares(
max_from: Height,
breakdown: &mut Breakdown,
total_data: &impl ReadableVec<Height, StoredU64>,
block_size: &impl ReadableVec<Height, StoredU64>,
exit: &Exit,
) -> Result<()> {
let data = &breakdown.metrics.total.data_bytes.cumulative.height;
compute_data_share(max_from, &mut breakdown.chain_share, data, block_size, exit)?;
compute_data_share(max_from, &mut breakdown.data_share, data, total_data, exit)
}
fn compute_data_share(
max_from: Height,
target: &mut PercentPerBlock<BasisPoints16>,
@@ -198,30 +220,30 @@ fn finalize_transaction(
if carrier.oversized_output_count > 0 {
policy.oversized.output_count += carrier.oversized_output_count;
policy.oversized.post_op_return_bytes += carrier.oversized_post_op_return_bytes;
policy.oversized.data_bytes += carrier.oversized_data_bytes;
add_carrier(&mut policy.oversized, carrier.vsize);
}
if carrier.output_count > 1 {
policy.multiple.output_count += carrier.output_count;
policy.multiple.post_op_return_bytes += carrier.post_op_return_bytes;
policy.multiple.data_bytes += carrier.data_bytes;
add_carrier(&mut policy.multiple, carrier.vsize);
}
if carrier.oversized_output_count > 0 || carrier.output_count > 1 {
policy.pre_v30_nonstandard.output_count += carrier.output_count;
policy.pre_v30_nonstandard.post_op_return_bytes += carrier.post_op_return_bytes;
policy.pre_v30_nonstandard.data_bytes += carrier.data_bytes;
add_carrier(&mut policy.pre_v30_nonstandard, carrier.vsize);
} else {
policy.standard.output_count += carrier.output_count;
policy.standard.post_op_return_bytes += carrier.post_op_return_bytes;
add_carrier(&mut policy.standard, carrier.vsize);
policy.pre_v30_standard.output_count += carrier.output_count;
policy.pre_v30_standard.data_bytes += carrier.data_bytes;
add_carrier(&mut policy.pre_v30_standard, carrier.vsize);
}
}
fn add_carrier(metrics: &mut Totals, vsize: VSize) {
metrics.carrier_tx_count += 1;
metrics.carrier_vsize += vsize;
metrics.tx_count += 1;
metrics.tx_vsize += vsize;
}
const fn kind_bit(kind: OpReturnKind) -> u32 {
@@ -246,13 +268,13 @@ mod tests {
finalize_transaction(&mut total, &mut by_kind, &mut policy, carrier);
assert_eq!(total.carrier_tx_count, 1);
assert_eq!(by_kind[OpReturnKind::Runes as usize].carrier_tx_count, 1);
assert_eq!(by_kind[OpReturnKind::Omni as usize].carrier_tx_count, 1);
assert_eq!(total.tx_count, 1);
assert_eq!(by_kind[OpReturnKind::Runes as usize].tx_count, 1);
assert_eq!(by_kind[OpReturnKind::Omni as usize].tx_count, 1);
assert_eq!(policy.multiple.output_count, 2);
assert_eq!(policy.pre_v30_nonstandard.carrier_tx_count, 1);
assert_eq!(policy.oversized.carrier_tx_count, 0);
assert_eq!(policy.standard.carrier_tx_count, 0);
assert_eq!(policy.pre_v30_nonstandard.tx_count, 1);
assert_eq!(policy.oversized.tx_count, 0);
assert_eq!(policy.pre_v30_standard.tx_count, 0);
}
#[test]
@@ -269,10 +291,10 @@ mod tests {
finalize_transaction(&mut total, &mut by_kind, &mut policy, carrier);
assert_eq!(policy.oversized.output_count, 1);
assert_eq!(policy.oversized.carrier_vsize, VSize::new(120));
assert_eq!(policy.pre_v30_nonstandard.carrier_tx_count, 1);
assert_eq!(policy.multiple.carrier_tx_count, 0);
assert_eq!(policy.standard.carrier_tx_count, 0);
assert_eq!(policy.oversized.tx_vsize, VSize::new(120));
assert_eq!(policy.pre_v30_nonstandard.tx_count, 1);
assert_eq!(policy.multiple.tx_count, 0);
assert_eq!(policy.pre_v30_standard.tx_count, 0);
}
#[test]
@@ -288,10 +310,10 @@ mod tests {
finalize_transaction(&mut total, &mut by_kind, &mut policy, carrier);
assert_eq!(policy.standard.output_count, 1);
assert_eq!(policy.standard.post_op_return_bytes, 15);
assert_eq!(policy.standard.carrier_tx_count, 1);
assert_eq!(policy.standard.carrier_vsize, VSize::new(100));
assert_eq!(policy.pre_v30_nonstandard.carrier_tx_count, 0);
assert_eq!(policy.pre_v30_standard.output_count, 1);
assert_eq!(policy.pre_v30_standard.data_bytes, 15);
assert_eq!(policy.pre_v30_standard.tx_count, 1);
assert_eq!(policy.pre_v30_standard.tx_vsize, VSize::new(100));
assert_eq!(policy.pre_v30_nonstandard.tx_count, 0);
}
}
+2 -2
View File
@@ -3,7 +3,7 @@ use std::path::Path;
use brk_error::Result;
use brk_types::Version;
use super::{ByKind, Metrics, Policy, Total, Vecs};
use super::{Breakdown, ByKind, Policy, Total, Vecs};
use crate::{
indexes,
internal::{
@@ -22,7 +22,7 @@ impl Vecs {
let db = open_db(parent_path, super::DB_NAME, 1_000_000)?;
let total = Total::forced_import(&db, "op_return", version, indexes, cached_starts)?;
let by_kind = ByKind::try_new(|_, name| {
Metrics::forced_import(
Breakdown::forced_import(
&db,
&format!("op_return_{name}"),
version,
+1 -1
View File
@@ -4,6 +4,6 @@ mod import;
mod vecs;
pub use by_kind::ByKind;
pub use vecs::{Metrics, Policy, Total, Vecs};
pub use vecs::{Breakdown, Policy, Total, Vecs};
pub const DB_NAME: &str = "op_return";
+58 -59
View File
@@ -15,16 +15,16 @@ pub type Series<T, M = Rw> = PerBlockCumulativeRolling<T, T, M>;
#[derive(Clone, Copy, Default)]
pub(super) struct Totals {
pub output_count: u64,
pub post_op_return_bytes: u64,
pub carrier_tx_count: u64,
pub carrier_vsize: VSize,
pub data_bytes: u64,
pub tx_count: u64,
pub tx_vsize: VSize,
}
#[derive(Traversable)]
pub struct TotalMetrics<M: StorageMode = Rw> {
pub post_op_return_bytes: Series<StoredU64, M>,
pub carrier_tx_count: Series<StoredU64, M>,
pub carrier_vsize: Series<VSize, M>,
pub data_bytes: Series<StoredU64, M>,
pub tx_count: Series<StoredU64, M>,
pub tx_vsize: Series<VSize, M>,
}
impl TotalMetrics {
@@ -36,23 +36,23 @@ impl TotalMetrics {
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
Ok(Self {
post_op_return_bytes: Series::forced_import(
data_bytes: Series::forced_import(
db,
&format!("{prefix}_post_op_return_bytes"),
&format!("{prefix}_data_bytes"),
version,
indexes,
cached_starts,
)?,
carrier_tx_count: Series::forced_import(
tx_count: Series::forced_import(
db,
&format!("{prefix}_carrier_tx_count"),
&format!("{prefix}_tx_count"),
version,
indexes,
cached_starts,
)?,
carrier_vsize: Series::forced_import(
tx_vsize: Series::forced_import(
db,
&format!("{prefix}_carrier_vsize"),
&format!("{prefix}_tx_vsize"),
version,
indexes,
cached_starts,
@@ -61,54 +61,46 @@ impl TotalMetrics {
}
fn len(&self) -> usize {
self.post_op_return_bytes
self.data_bytes
.block
.len()
.min(self.carrier_tx_count.block.len())
.min(self.carrier_vsize.block.len())
.min(self.tx_count.block.len())
.min(self.tx_vsize.block.len())
}
pub(super) fn push(&mut self, block: Totals) {
self.post_op_return_bytes
.block
.push(block.post_op_return_bytes.into());
self.carrier_tx_count
.block
.push(block.carrier_tx_count.into());
self.carrier_vsize.block.push(block.carrier_vsize);
self.data_bytes.block.push(block.data_bytes.into());
self.tx_count.block.push(block.tx_count.into());
self.tx_vsize.block.push(block.tx_vsize);
}
fn validate_and_truncate(&mut self, version: Version, height: Height) -> Result<()> {
self.post_op_return_bytes
.block
.validate_and_truncate(version, height)?;
self.carrier_tx_count
.block
.validate_and_truncate(version, height)?;
self.carrier_vsize
self.data_bytes
.block
.validate_and_truncate(version, height)?;
self.tx_count.block.validate_and_truncate(version, height)?;
self.tx_vsize.block.validate_and_truncate(version, height)?;
Ok(())
}
fn truncate_if_needed_at(&mut self, len: usize) -> Result<()> {
self.post_op_return_bytes.block.truncate_if_needed_at(len)?;
self.carrier_tx_count.block.truncate_if_needed_at(len)?;
self.carrier_vsize.block.truncate_if_needed_at(len)?;
self.data_bytes.block.truncate_if_needed_at(len)?;
self.tx_count.block.truncate_if_needed_at(len)?;
self.tx_vsize.block.truncate_if_needed_at(len)?;
Ok(())
}
fn write(&mut self) -> Result<()> {
self.post_op_return_bytes.block.write()?;
self.carrier_tx_count.block.write()?;
self.carrier_vsize.block.write()?;
self.data_bytes.block.write()?;
self.tx_count.block.write()?;
self.tx_vsize.block.write()?;
Ok(())
}
fn compute_cumulative(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
self.post_op_return_bytes.compute_rest(max_from, exit)?;
self.carrier_tx_count.compute_rest(max_from, exit)?;
self.carrier_vsize.compute_rest(max_from, exit)?;
self.data_bytes.compute_rest(max_from, exit)?;
self.tx_count.compute_rest(max_from, exit)?;
self.tx_vsize.compute_rest(max_from, exit)?;
Ok(())
}
}
@@ -119,7 +111,7 @@ pub struct Total<M: StorageMode = Rw> {
#[deref_mut]
#[traversable(flatten)]
pub metrics: TotalMetrics<M>,
pub data_share: PercentPerBlock<BasisPoints16, M>,
pub chain_share: PercentPerBlock<BasisPoints16, M>,
}
impl Total {
@@ -132,9 +124,9 @@ impl Total {
) -> Result<Self> {
Ok(Self {
metrics: TotalMetrics::forced_import(db, prefix, version, indexes, cached_starts)?,
data_share: PercentPerBlock::forced_import(
chain_share: PercentPerBlock::forced_import(
db,
&format!("{prefix}_data_share"),
&format!("{prefix}_chain_share"),
version,
indexes,
)?,
@@ -206,16 +198,17 @@ impl Metrics {
}
#[derive(Deref, DerefMut, Traversable)]
pub struct PolicyMetrics<M: StorageMode = Rw> {
pub struct Breakdown<M: StorageMode = Rw> {
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub metrics: Metrics<M>,
pub data_share: PercentPerBlock<BasisPoints16, M>,
pub chain_share: PercentPerBlock<BasisPoints16, M>,
}
impl PolicyMetrics {
fn forced_import(
impl Breakdown {
pub(crate) fn forced_import(
db: &Database,
prefix: &str,
version: Version,
@@ -230,16 +223,22 @@ impl PolicyMetrics {
version,
indexes,
)?,
chain_share: PercentPerBlock::forced_import(
db,
&format!("{prefix}_chain_share"),
version,
indexes,
)?,
})
}
}
#[derive(Traversable)]
pub struct Policy<M: StorageMode = Rw> {
pub standard: PolicyMetrics<M>,
pub oversized: PolicyMetrics<M>,
pub multiple: PolicyMetrics<M>,
pub pre_v30_nonstandard: PolicyMetrics<M>,
pub pre_v30_standard: Breakdown<M>,
pub pre_v30_nonstandard: Breakdown<M>,
pub oversized: Breakdown<M>,
pub multiple: Breakdown<M>,
}
impl Policy {
@@ -250,7 +249,7 @@ impl Policy {
cached_starts: &Windows<&WindowStartVec>,
) -> Result<Self> {
let import = |name| {
PolicyMetrics::forced_import(
Breakdown::forced_import(
db,
&format!("op_return_policy_{name}"),
version,
@@ -260,29 +259,29 @@ impl Policy {
};
Ok(Self {
standard: import("standard")?,
pre_v30_standard: import("pre_v30_standard")?,
pre_v30_nonstandard: import("pre_v30_nonstandard")?,
oversized: import("oversized")?,
multiple: import("multiple")?,
pre_v30_nonstandard: import("pre_v30_nonstandard")?,
})
}
fn iter(&self) -> impl Iterator<Item = &PolicyMetrics> {
fn iter(&self) -> impl Iterator<Item = &Breakdown> {
[
&self.standard,
&self.pre_v30_standard,
&self.pre_v30_nonstandard,
&self.oversized,
&self.multiple,
&self.pre_v30_nonstandard,
]
.into_iter()
}
pub(super) fn iter_mut(&mut self) -> impl Iterator<Item = &mut PolicyMetrics> {
pub(super) fn iter_mut(&mut self) -> impl Iterator<Item = &mut Breakdown> {
[
&mut self.standard,
&mut self.pre_v30_standard,
&mut self.pre_v30_nonstandard,
&mut self.oversized,
&mut self.multiple,
&mut self.pre_v30_nonstandard,
]
.into_iter()
}
@@ -293,7 +292,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(skip)]
pub(crate) db: Database,
pub total: Total<M>,
pub by_kind: ByKind<Metrics<M>>,
pub by_kind: ByKind<Breakdown<M>>,
pub policy: Policy<M>,
}
@@ -302,7 +301,7 @@ impl Vecs {
let len = self
.by_kind
.iter()
.map(Metrics::len)
.map(|metrics| metrics.len())
.fold(self.total.len(), usize::min);
self.policy
.iter()
+89 -110
View File
@@ -3491,6 +3491,33 @@ function createCentsNegativeToUsdPattern2(client, acc) {
};
}
/**
* @typedef {Object} ChainDataOutputTxPattern
* @property {BpsPercentRatioPattern2} chainShare
* @property {AverageBlockCumulativeSumPattern<StoredU64>} dataBytes
* @property {BpsPercentRatioPattern2} dataShare
* @property {AverageBlockCumulativeSumPattern<StoredU64>} outputCount
* @property {AverageBlockCumulativeSumPattern<StoredU64>} txCount
* @property {AverageBlockCumulativeSumPattern<VSize>} txVsize
*/
/**
* Create a ChainDataOutputTxPattern pattern node
* @param {BrkClient} client
* @param {string} acc - Accumulated series name
* @returns {ChainDataOutputTxPattern}
*/
function createChainDataOutputTxPattern(client, acc) {
return {
chainShare: createBpsPercentRatioPattern2(client, _m(acc, 'chain_share')),
dataBytes: createAverageBlockCumulativeSumPattern(client, _m(acc, 'data_bytes')),
dataShare: createBpsPercentRatioPattern2(client, _m(acc, 'data_share')),
outputCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'output_count')),
txCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'tx_count')),
txVsize: createAverageBlockCumulativeSumPattern(client, _m(acc, 'tx_vsize')),
};
}
/**
* @typedef {Object} DeltaDominanceHalfInTotalPattern2
* @property {AbsoluteRatePattern3} delta
@@ -3820,31 +3847,6 @@ function createCapLossMvrvPriceProfitPattern(client, acc) {
};
}
/**
* @typedef {Object} CarrierDataOutputPostPattern
* @property {AverageBlockCumulativeSumPattern<StoredU64>} carrierTxCount
* @property {AverageBlockCumulativeSumPattern<VSize>} carrierVsize
* @property {BpsPercentRatioPattern2} dataShare
* @property {AverageBlockCumulativeSumPattern<StoredU64>} outputCount
* @property {AverageBlockCumulativeSumPattern<StoredU64>} postOpReturnBytes
*/
/**
* Create a CarrierDataOutputPostPattern pattern node
* @param {BrkClient} client
* @param {string} acc - Accumulated series name
* @returns {CarrierDataOutputPostPattern}
*/
function createCarrierDataOutputPostPattern(client, acc) {
return {
carrierTxCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_tx_count')),
carrierVsize: createAverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_vsize')),
dataShare: createBpsPercentRatioPattern2(client, _m(acc, 'data_share')),
outputCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'output_count')),
postOpReturnBytes: createAverageBlockCumulativeSumPattern(client, _m(acc, 'post_op_return_bytes')),
};
}
/**
* @typedef {Object} CentsToUsdPattern4
* @property {SeriesPattern1<Cents>} cents
@@ -4257,29 +4259,6 @@ function createBtcCentsSatsUsdPattern3(client, acc) {
};
}
/**
* @typedef {Object} CarrierOutputPostPattern
* @property {AverageBlockCumulativeSumPattern<StoredU64>} carrierTxCount
* @property {AverageBlockCumulativeSumPattern<VSize>} carrierVsize
* @property {AverageBlockCumulativeSumPattern<StoredU64>} outputCount
* @property {AverageBlockCumulativeSumPattern<StoredU64>} postOpReturnBytes
*/
/**
* Create a CarrierOutputPostPattern pattern node
* @param {BrkClient} client
* @param {string} acc - Accumulated series name
* @returns {CarrierOutputPostPattern}
*/
function createCarrierOutputPostPattern(client, acc) {
return {
carrierTxCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_tx_count')),
carrierVsize: createAverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_vsize')),
outputCount: createAverageBlockCumulativeSumPattern(client, _m(acc, 'output_count')),
postOpReturnBytes: createAverageBlockCumulativeSumPattern(client, _m(acc, 'post_op_return_bytes')),
};
}
/**
* @typedef {Object} CentsDeltaToUsdPattern
* @property {SeriesPattern1<Cents>} cents
@@ -6214,45 +6193,45 @@ function createTransferPattern(client, acc) {
/**
* @typedef {Object} SeriesTree_OpReturn_Total
* @property {AverageBlockCumulativeSumPattern<StoredU64>} postOpReturnBytes
* @property {AverageBlockCumulativeSumPattern<StoredU64>} carrierTxCount
* @property {AverageBlockCumulativeSumPattern<VSize>} carrierVsize
* @property {BpsPercentRatioPattern2} dataShare
* @property {AverageBlockCumulativeSumPattern<StoredU64>} dataBytes
* @property {AverageBlockCumulativeSumPattern<StoredU64>} txCount
* @property {AverageBlockCumulativeSumPattern<VSize>} txVsize
* @property {BpsPercentRatioPattern2} chainShare
*/
/**
* @typedef {Object} SeriesTree_OpReturn_ByKind
* @property {CarrierOutputPostPattern} runes
* @property {CarrierOutputPostPattern} veriBlock
* @property {CarrierOutputPostPattern} omni
* @property {CarrierOutputPostPattern} stacks
* @property {CarrierOutputPostPattern} blockstack
* @property {CarrierOutputPostPattern} colu
* @property {CarrierOutputPostPattern} openAssets
* @property {CarrierOutputPostPattern} komodo
* @property {CarrierOutputPostPattern} coinSpark
* @property {CarrierOutputPostPattern} poet
* @property {CarrierOutputPostPattern} docproof
* @property {CarrierOutputPostPattern} openTimestamps
* @property {CarrierOutputPostPattern} factom
* @property {CarrierOutputPostPattern} eternityWall
* @property {CarrierOutputPostPattern} memo
* @property {CarrierOutputPostPattern} bitproof
* @property {CarrierOutputPostPattern} ascribe
* @property {CarrierOutputPostPattern} stampery
* @property {CarrierOutputPostPattern} epobc
* @property {CarrierOutputPostPattern} bareHash
* @property {CarrierOutputPostPattern} text
* @property {CarrierOutputPostPattern} empty
* @property {CarrierOutputPostPattern} unknown
* @property {ChainDataOutputTxPattern} runes
* @property {ChainDataOutputTxPattern} veriBlock
* @property {ChainDataOutputTxPattern} omni
* @property {ChainDataOutputTxPattern} stacks
* @property {ChainDataOutputTxPattern} blockstack
* @property {ChainDataOutputTxPattern} colu
* @property {ChainDataOutputTxPattern} openAssets
* @property {ChainDataOutputTxPattern} komodo
* @property {ChainDataOutputTxPattern} coinSpark
* @property {ChainDataOutputTxPattern} poet
* @property {ChainDataOutputTxPattern} docproof
* @property {ChainDataOutputTxPattern} openTimestamps
* @property {ChainDataOutputTxPattern} factom
* @property {ChainDataOutputTxPattern} eternityWall
* @property {ChainDataOutputTxPattern} memo
* @property {ChainDataOutputTxPattern} bitproof
* @property {ChainDataOutputTxPattern} ascribe
* @property {ChainDataOutputTxPattern} stampery
* @property {ChainDataOutputTxPattern} epobc
* @property {ChainDataOutputTxPattern} bareHash
* @property {ChainDataOutputTxPattern} text
* @property {ChainDataOutputTxPattern} empty
* @property {ChainDataOutputTxPattern} unknown
*/
/**
* @typedef {Object} SeriesTree_OpReturn_Policy
* @property {CarrierDataOutputPostPattern} standard
* @property {CarrierDataOutputPostPattern} oversized
* @property {CarrierDataOutputPostPattern} multiple
* @property {CarrierDataOutputPostPattern} preV30Nonstandard
* @property {ChainDataOutputTxPattern} preV30Standard
* @property {ChainDataOutputTxPattern} preV30Nonstandard
* @property {ChainDataOutputTxPattern} oversized
* @property {ChainDataOutputTxPattern} multiple
*/
/**
@@ -10011,41 +9990,41 @@ class BrkClient extends BrkClientBase {
postOpReturnBytes: createSeriesPattern23(this, 'op_return_post_op_return_bytes'),
},
total: {
postOpReturnBytes: createAverageBlockCumulativeSumPattern(this, 'op_return_post_op_return_bytes'),
carrierTxCount: createAverageBlockCumulativeSumPattern(this, 'op_return_carrier_tx_count'),
carrierVsize: createAverageBlockCumulativeSumPattern(this, 'op_return_carrier_vsize'),
dataShare: createBpsPercentRatioPattern2(this, 'op_return_data_share'),
dataBytes: createAverageBlockCumulativeSumPattern(this, 'op_return_data_bytes'),
txCount: createAverageBlockCumulativeSumPattern(this, 'op_return_tx_count'),
txVsize: createAverageBlockCumulativeSumPattern(this, 'op_return_tx_vsize'),
chainShare: createBpsPercentRatioPattern2(this, 'op_return_chain_share'),
},
byKind: {
runes: createCarrierOutputPostPattern(this, 'op_return_runes'),
veriBlock: createCarrierOutputPostPattern(this, 'op_return_veri_block'),
omni: createCarrierOutputPostPattern(this, 'op_return_omni'),
stacks: createCarrierOutputPostPattern(this, 'op_return_stacks'),
blockstack: createCarrierOutputPostPattern(this, 'op_return_blockstack'),
colu: createCarrierOutputPostPattern(this, 'op_return_colu'),
openAssets: createCarrierOutputPostPattern(this, 'op_return_open_assets'),
komodo: createCarrierOutputPostPattern(this, 'op_return_komodo'),
coinSpark: createCarrierOutputPostPattern(this, 'op_return_coin_spark'),
poet: createCarrierOutputPostPattern(this, 'op_return_poet'),
docproof: createCarrierOutputPostPattern(this, 'op_return_docproof'),
openTimestamps: createCarrierOutputPostPattern(this, 'op_return_open_timestamps'),
factom: createCarrierOutputPostPattern(this, 'op_return_factom'),
eternityWall: createCarrierOutputPostPattern(this, 'op_return_eternity_wall'),
memo: createCarrierOutputPostPattern(this, 'op_return_memo'),
bitproof: createCarrierOutputPostPattern(this, 'op_return_bitproof'),
ascribe: createCarrierOutputPostPattern(this, 'op_return_ascribe'),
stampery: createCarrierOutputPostPattern(this, 'op_return_stampery'),
epobc: createCarrierOutputPostPattern(this, 'op_return_epobc'),
bareHash: createCarrierOutputPostPattern(this, 'op_return_bare_hash'),
text: createCarrierOutputPostPattern(this, 'op_return_text'),
empty: createCarrierOutputPostPattern(this, 'op_return_empty'),
unknown: createCarrierOutputPostPattern(this, 'op_return_unknown'),
runes: createChainDataOutputTxPattern(this, 'op_return_runes'),
veriBlock: createChainDataOutputTxPattern(this, 'op_return_veri_block'),
omni: createChainDataOutputTxPattern(this, 'op_return_omni'),
stacks: createChainDataOutputTxPattern(this, 'op_return_stacks'),
blockstack: createChainDataOutputTxPattern(this, 'op_return_blockstack'),
colu: createChainDataOutputTxPattern(this, 'op_return_colu'),
openAssets: createChainDataOutputTxPattern(this, 'op_return_open_assets'),
komodo: createChainDataOutputTxPattern(this, 'op_return_komodo'),
coinSpark: createChainDataOutputTxPattern(this, 'op_return_coin_spark'),
poet: createChainDataOutputTxPattern(this, 'op_return_poet'),
docproof: createChainDataOutputTxPattern(this, 'op_return_docproof'),
openTimestamps: createChainDataOutputTxPattern(this, 'op_return_open_timestamps'),
factom: createChainDataOutputTxPattern(this, 'op_return_factom'),
eternityWall: createChainDataOutputTxPattern(this, 'op_return_eternity_wall'),
memo: createChainDataOutputTxPattern(this, 'op_return_memo'),
bitproof: createChainDataOutputTxPattern(this, 'op_return_bitproof'),
ascribe: createChainDataOutputTxPattern(this, 'op_return_ascribe'),
stampery: createChainDataOutputTxPattern(this, 'op_return_stampery'),
epobc: createChainDataOutputTxPattern(this, 'op_return_epobc'),
bareHash: createChainDataOutputTxPattern(this, 'op_return_bare_hash'),
text: createChainDataOutputTxPattern(this, 'op_return_text'),
empty: createChainDataOutputTxPattern(this, 'op_return_empty'),
unknown: createChainDataOutputTxPattern(this, 'op_return_unknown'),
},
policy: {
standard: createCarrierDataOutputPostPattern(this, 'op_return_policy_standard'),
oversized: createCarrierDataOutputPostPattern(this, 'op_return_policy_oversized'),
multiple: createCarrierDataOutputPostPattern(this, 'op_return_policy_multiple'),
preV30Nonstandard: createCarrierDataOutputPostPattern(this, 'op_return_policy_pre_v30_nonstandard'),
preV30Standard: createChainDataOutputTxPattern(this, 'op_return_policy_pre_v30_standard'),
preV30Nonstandard: createChainDataOutputTxPattern(this, 'op_return_policy_pre_v30_nonstandard'),
oversized: createChainDataOutputTxPattern(this, 'op_return_policy_oversized'),
multiple: createChainDataOutputTxPattern(this, 'op_return_policy_multiple'),
},
},
mining: {
+43 -52
View File
@@ -3432,6 +3432,18 @@ class CentsNegativeToUsdPattern2:
self.to_own_mcap: BpsPercentRatioPattern4 = BpsPercentRatioPattern4(client, _m(acc, 'to_own_mcap'))
self.usd: SeriesPattern1[Dollars] = SeriesPattern1(client, acc)
class ChainDataOutputTxPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.chain_share: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, _m(acc, 'chain_share'))
self.data_bytes: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'data_bytes'))
self.data_share: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, _m(acc, 'data_share'))
self.output_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'output_count'))
self.tx_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'tx_count'))
self.tx_vsize: AverageBlockCumulativeSumPattern[VSize] = AverageBlockCumulativeSumPattern(client, _m(acc, 'tx_vsize'))
class DeltaDominanceHalfInTotalPattern2:
"""Pattern struct for repeated tree structure."""
@@ -3577,17 +3589,6 @@ class CapLossMvrvPriceProfitPattern:
self.price: BpsCentsRatioSatsUsdPattern = BpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price'))
self.profit: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, _m(acc, 'realized_profit'))
class CarrierDataOutputPostPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.carrier_tx_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_tx_count'))
self.carrier_vsize: AverageBlockCumulativeSumPattern[VSize] = AverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_vsize'))
self.data_share: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, _m(acc, 'data_share'))
self.output_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'output_count'))
self.post_op_return_bytes: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'post_op_return_bytes'))
class CentsToUsdPattern4:
"""Pattern struct for repeated tree structure."""
@@ -3768,16 +3769,6 @@ class BtcCentsSatsUsdPattern3:
self.sats: SeriesPattern18[Sats] = SeriesPattern18(client, _m(acc, 'sats'))
self.usd: SeriesPattern18[Dollars] = SeriesPattern18(client, _m(acc, 'usd'))
class CarrierOutputPostPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClient, acc: str):
"""Create pattern node with accumulated series name."""
self.carrier_tx_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_tx_count'))
self.carrier_vsize: AverageBlockCumulativeSumPattern[VSize] = AverageBlockCumulativeSumPattern(client, _m(acc, 'carrier_vsize'))
self.output_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'output_count'))
self.post_op_return_bytes: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _m(acc, 'post_op_return_bytes'))
class CentsDeltaToUsdPattern:
"""Pattern struct for repeated tree structure."""
@@ -5072,47 +5063,47 @@ class SeriesTree_OpReturn_Total:
"""Series tree node."""
def __init__(self, client: BrkClient, base_path: str = ''):
self.post_op_return_bytes: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, 'op_return_post_op_return_bytes')
self.carrier_tx_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, 'op_return_carrier_tx_count')
self.carrier_vsize: AverageBlockCumulativeSumPattern[VSize] = AverageBlockCumulativeSumPattern(client, 'op_return_carrier_vsize')
self.data_share: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, 'op_return_data_share')
self.data_bytes: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, 'op_return_data_bytes')
self.tx_count: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, 'op_return_tx_count')
self.tx_vsize: AverageBlockCumulativeSumPattern[VSize] = AverageBlockCumulativeSumPattern(client, 'op_return_tx_vsize')
self.chain_share: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, 'op_return_chain_share')
class SeriesTree_OpReturn_ByKind:
"""Series tree node."""
def __init__(self, client: BrkClient, base_path: str = ''):
self.runes: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_runes')
self.veri_block: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_veri_block')
self.omni: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_omni')
self.stacks: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_stacks')
self.blockstack: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_blockstack')
self.colu: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_colu')
self.open_assets: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_open_assets')
self.komodo: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_komodo')
self.coin_spark: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_coin_spark')
self.poet: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_poet')
self.docproof: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_docproof')
self.open_timestamps: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_open_timestamps')
self.factom: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_factom')
self.eternity_wall: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_eternity_wall')
self.memo: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_memo')
self.bitproof: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_bitproof')
self.ascribe: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_ascribe')
self.stampery: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_stampery')
self.epobc: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_epobc')
self.bare_hash: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_bare_hash')
self.text: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_text')
self.empty: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_empty')
self.unknown: CarrierOutputPostPattern = CarrierOutputPostPattern(client, 'op_return_unknown')
self.runes: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_runes')
self.veri_block: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_veri_block')
self.omni: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_omni')
self.stacks: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_stacks')
self.blockstack: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_blockstack')
self.colu: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_colu')
self.open_assets: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_open_assets')
self.komodo: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_komodo')
self.coin_spark: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_coin_spark')
self.poet: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_poet')
self.docproof: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_docproof')
self.open_timestamps: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_open_timestamps')
self.factom: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_factom')
self.eternity_wall: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_eternity_wall')
self.memo: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_memo')
self.bitproof: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_bitproof')
self.ascribe: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_ascribe')
self.stampery: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_stampery')
self.epobc: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_epobc')
self.bare_hash: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_bare_hash')
self.text: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_text')
self.empty: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_empty')
self.unknown: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_unknown')
class SeriesTree_OpReturn_Policy:
"""Series tree node."""
def __init__(self, client: BrkClient, base_path: str = ''):
self.standard: CarrierDataOutputPostPattern = CarrierDataOutputPostPattern(client, 'op_return_policy_standard')
self.oversized: CarrierDataOutputPostPattern = CarrierDataOutputPostPattern(client, 'op_return_policy_oversized')
self.multiple: CarrierDataOutputPostPattern = CarrierDataOutputPostPattern(client, 'op_return_policy_multiple')
self.pre_v30_nonstandard: CarrierDataOutputPostPattern = CarrierDataOutputPostPattern(client, 'op_return_policy_pre_v30_nonstandard')
self.pre_v30_standard: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_policy_pre_v30_standard')
self.pre_v30_nonstandard: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_policy_pre_v30_nonstandard')
self.oversized: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_policy_oversized')
self.multiple: ChainDataOutputTxPattern = ChainDataOutputTxPattern(client, 'op_return_policy_multiple')
class SeriesTree_OpReturn:
"""Series tree node."""
+176 -80
View File
@@ -1,7 +1,7 @@
import { colors } from "../../utils/colors.js";
import { brk } from "../../utils/client.js";
import { Unit } from "../../utils/units.js";
import { chartsFromCount, line } from "../series.js";
import { chartsFromCount, line, percentRatio } from "../series.js";
import { groupedWindowsCumulative } from "../shared.js";
const TYPE_DEFINITIONS = /** @type {const} */ ([
@@ -32,9 +32,9 @@ const TYPE_DEFINITIONS = /** @type {const} */ ([
const METRICS = /** @type {const} */ ([
{
key: "carrierTxCount",
key: "txCount",
name: "Transactions",
title: "Carrier Transaction Count",
title: "Transaction Count",
unit: Unit.count,
},
{
@@ -44,24 +44,32 @@ const METRICS = /** @type {const} */ ([
unit: Unit.count,
},
{
key: "carrierVsize",
name: "vBytes",
title: "Carrier Transaction vBytes",
unit: Unit.vb,
},
{
key: "postOpReturnBytes",
name: "Data",
key: "dataBytes",
name: "Data Bytes",
title: "Data Bytes",
unit: Unit.bytes,
},
{
key: "txVsize",
name: "Transaction vSize",
title: "Transaction vSize",
unit: Unit.vb,
},
]);
/** @typedef {(typeof brk.series.opReturn.byKind)[keyof typeof brk.series.opReturn.byKind]} OpReturnMetrics */
/**
* @typedef {Object} OpReturnEntry
* @property {string} name
* @property {Color} color
* @property {boolean} [defaultActive]
* @property {OpReturnMetrics} pattern
*/
/**
* @param {Object} args
* @param {readonly { name: string, color: Color, defaultActive: boolean, pattern: OpReturnMetrics }[]} args.list
* @param {readonly OpReturnEntry[]} args.list
* @param {string} args.category
* @returns {PartialOptionsTree}
*/
@@ -82,23 +90,123 @@ function createComparisons({ list, category }) {
}));
}
/**
* @param {Object} args
* @param {OpReturnMetrics} args.pattern
* @param {string} args.name
* @param {Color} args.color
* @returns {PartialOptionsTree}
*/
function createMetrics({ pattern, name, color }) {
return METRICS.map((metric) => ({
name: metric.name,
tree: chartsFromCount({
pattern: pattern[metric.key],
metric: `OP_RETURN ${name} ${metric.title}`,
unit: metric.unit,
color,
}),
}));
}
/**
* @param {Object} args
* @param {readonly OpReturnEntry[]} args.list
* @param {string} args.category
* @param {string} [args.subject]
* @returns {PartialOptionsTree}
*/
function createShares({ list, category, subject }) {
const shares = /** @type {const} */ ([
{
key: "dataShare",
name: "OP_RETURN Share",
title: subject
? `Cumulative ${subject} Share of OP_RETURN Data`
: `Cumulative OP_RETURN Data Share by ${category}`,
},
{
key: "chainShare",
name: "Blockchain Share",
title: subject
? `Cumulative ${subject} OP_RETURN Data Share of Blockchain`
: `Cumulative Blockchain Share by OP_RETURN ${category}`,
},
]);
return shares.map(({ key, name: shareName, title }) => ({
name: shareName,
title,
bottom: list.flatMap(({ name, color, defaultActive, pattern }) =>
percentRatio({
pattern: pattern[key],
name,
color,
defaultActive,
}),
),
}));
}
/**
* @param {Object} args
* @param {readonly OpReturnEntry[]} args.list
* @param {string} args.name
* @param {string} args.category
* @returns {PartialOptionsGroup}
*/
function createBreakdown({ name, list, category }) {
return {
name,
tree: [
{
name: "Compare",
tree: [
...createComparisons({ list, category }),
...createShares({ list, category }),
],
},
...list.map(({ name, color, pattern }) => ({
name,
tree: [
...createMetrics({ pattern, name, color }),
...createShares({
list: [{ name, color, pattern }],
category,
subject: name,
}),
],
})),
],
};
}
/** @returns {PartialOptionsGroup} */
export function createOpReturnSection() {
const opReturn = brk.series.opReturn;
const outputCount = brk.series.outputs.byType.outputCount.opReturn;
const types = TYPE_DEFINITIONS.map((type, index) => ({
...type,
color: colors.at(index, TYPE_DEFINITIONS.length),
pattern: opReturn.byKind[type.key],
}));
const policies = [
const policyClassifications = [
{
name: "Standard",
color: colors.profit,
defaultActive: true,
pattern: opReturn.policy.standard,
pattern: opReturn.policy.preV30Standard,
},
{
name: "Oversized",
name: "Nonstandard",
color: colors.loss,
defaultActive: true,
pattern: opReturn.policy.preV30Nonstandard,
},
];
const nonstandardReasons = [
{
name: "Over 82 Bytes",
color: colors.loss,
defaultActive: true,
pattern: opReturn.policy.oversized,
@@ -109,82 +217,70 @@ export function createOpReturnSection() {
defaultActive: true,
pattern: opReturn.policy.multiple,
},
{
name: "Pre-v30 Nonstandard",
color: colors.gray,
defaultActive: true,
pattern: opReturn.policy.preV30Nonstandard,
},
];
return {
name: "OP_RETURN",
tree: [
{
name: "Total",
tree: [
{
name: "Transactions",
tree: chartsFromCount({
pattern: opReturn.total.carrierTxCount,
metric: "OP_RETURN Carrier Transaction Count",
unit: Unit.count,
color: colors.scriptType.opReturn,
}),
},
{
name: "vBytes",
tree: chartsFromCount({
pattern: opReturn.total.carrierVsize,
metric: "OP_RETURN Carrier Transaction vBytes",
unit: Unit.vb,
color: colors.scriptType.opReturn,
}),
},
{
name: "Data",
tree: chartsFromCount({
pattern: opReturn.total.postOpReturnBytes,
metric: "OP_RETURN Data Bytes",
unit: Unit.bytes,
color: colors.scriptType.opReturn,
}),
},
{
name: "Share",
title: "Cumulative OP_RETURN Data Share of Blockchain Size",
bottom: [
line({
series: opReturn.total.dataShare.percent,
name: "OP_RETURN Data",
color: colors.scriptType.opReturn,
unit: Unit.percentage,
}),
],
},
],
name: "Transactions",
tree: chartsFromCount({
pattern: opReturn.total.txCount,
metric: "OP_RETURN Transaction Count",
unit: Unit.count,
color: colors.scriptType.opReturn,
}),
},
{
name: "Type",
tree: createComparisons({ list: types, category: "Type" }),
name: "Outputs",
tree: chartsFromCount({
pattern: outputCount,
metric: "OP_RETURN Output Count",
unit: Unit.count,
color: colors.scriptType.opReturn,
}),
},
{
name: "Policy",
name: "Data Bytes",
tree: chartsFromCount({
pattern: opReturn.total.dataBytes,
metric: "OP_RETURN Data Bytes",
unit: Unit.bytes,
color: colors.scriptType.opReturn,
}),
},
{
name: "Transaction vSize",
tree: chartsFromCount({
pattern: opReturn.total.txVsize,
metric: "OP_RETURN Transaction vSize",
unit: Unit.vb,
color: colors.scriptType.opReturn,
}),
},
{
name: "Blockchain Share",
title: "Cumulative OP_RETURN Data Share of Blockchain Size",
bottom: percentRatio({
pattern: opReturn.total.chainShare,
name: "OP_RETURN Data",
color: colors.scriptType.opReturn,
}),
},
createBreakdown({ name: "Types", list: types, category: "Type" }),
{
name: "Pre-v30 Policy",
tree: [
{
name: "Share",
title: "Cumulative OP_RETURN Data Share of Blockchain Size by Policy",
bottom: policies.map(({ name, color, defaultActive, pattern }) =>
line({
series: pattern.dataShare.percent,
name,
color,
defaultActive,
unit: Unit.percentage,
}),
),
},
...createComparisons({ list: policies, category: "Policy" }),
createBreakdown({
name: "Classification",
list: policyClassifications,
category: "Pre-v30 Policy",
}),
createBreakdown({
name: "Nonstandard Reasons",
list: nonstandardReasons,
category: "Pre-v30 Nonstandard Reason",
}),
],
},
],
@@ -12,13 +12,13 @@ export const OP_RETURN_COUNT_SOURCES = [
...OP_RETURN_KIND_FILTERS.map(([, kind, clientKey]) => {
return {
key: `op_return:${kind}`,
series: byKind[clientKey].carrierTxCount.block,
series: byKind[clientKey].txCount.block,
};
}),
...OP_RETURN_POLICY_FILTERS.map(([, filter, clientKey]) => {
return {
key: `op_return_policy:${filter}`,
series: policy[clientKey].carrierTxCount.block,
series: policy[clientKey].txCount.block,
};
}),
];
@@ -37,7 +37,7 @@ export const OP_RETURN_KIND_FILTERS = /** @type {const} */ ([
]);
export const OP_RETURN_POLICY_FILTERS = /** @type {const} */ ([
["standard", "standard", "standard", txColors.opReturnPolicy.standard],
["standard", "standard", "preV30Standard", txColors.opReturnPolicy.standard],
["oversized", "oversized", "oversized", txColors.opReturnPolicy.oversized],
["multiple", "multiple", "multiple", txColors.opReturnPolicy.multiple],
[