Compare commits

..

11 Commits

Author SHA1 Message Date
nym21 4efd98b758 release: v0.0.94 2025-08-28 00:31:36 +02:00
nym21 36640e3710 global: added datasets 2025-08-28 00:31:14 +02:00
nym21 311c4fd29d website: rename default to bitview 2025-08-27 11:52:22 +02:00
nym21 f50374f983 release: v0.0.93 2025-08-26 23:34:57 +02:00
nym21 82ceb7f021 cargo: update 2025-08-26 23:34:38 +02:00
nym21 0aba3bc1d8 release: v0.0.92 2025-08-26 22:27:16 +02:00
nym21 f6c984ff3c website: add screenshot feature 2025-08-26 22:26:55 +02:00
nym21 4091ab6b6c release: v0.0.91 2025-08-26 08:31:30 +02:00
nym21 fb9fd5b51a global: add datasets and charts + fixes 2025-08-26 08:31:08 +02:00
nym21 9389700a01 release: v0.0.90 2025-08-24 17:05:51 +02:00
nym21 016c1b2233 changelog: update 2025-08-24 17:05:35 +02:00
121 changed files with 3126 additions and 7042 deletions
+21 -32
View File
@@ -4,46 +4,35 @@
All notable changes to the Bitcoin Research Kit (BRK) project will be documented in this file. All notable changes to the Bitcoin Research Kit (BRK) project will be documented in this file.
## Unreleased ## [v0.0.89](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.0.89) - 2025-08-24
### Documentation ### Documentation
- **Enhanced**: Comprehensive rewrite of all crate README files for improved clarity and developer experience - **Enhanced**: Comprehensive rewrite of all crate README files for improved clarity and developer experience across all workspace crates: [brk](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk/README.md), [brk_bundler](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_bundler/README.md), [brk_computer](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_computer/README.md), [brk_cli](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_cli/README.md), [brk_error](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_error/README.md)
- **Updated**: Main project README with better structure and documentation - **Updated**: Main project [README](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/README.md) with better structure and comprehensive architecture documentation
- **Standardized**: README format across all workspace crates with consistent styling - **Standardized**: README format across all workspace crates with consistent styling and improved developer experience
- **Improved**: Documentation structure and organization across the entire project - **Added**: More detailed descriptions for each crate's purpose and functionality with examples
- **Added**: More detailed descriptions for each crate's purpose and functionality
### Computer Module ### Computer Module - Major Refactoring
- **Refactored**: Converted ComputedFrom pattern to LazyFrom pattern for improved performance - **Refactored**: Converted ComputedFrom pattern to [LazyFrom pattern](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_computer/src/grouped/builder_lazy.rs) for improved performance and memory efficiency
- **Added**: New LazyVecBuilder implementation for on-demand computation - **Added**: New [LazyVecBuilder implementation](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_computer/src/grouped/builder_lazy.rs) for on-demand computation with support for first, average, sum, max, min, last, and cumulative operations
- **Restructured**: Computer module stateful operations with improved organization - **Restructured**: Computer module [stateful operations](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_computer/src/stateful/mod.rs) with improved organization and rollback functionality
- **Cleaned**: Removed hardcoded format specifications, now using defaults - **Enhanced**: [Address type organization](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_computer/src/stateful/addresstype/) into dedicated module structure
- **Optimized**: Vector storage operations with lazy computation patterns - **Improved**: Stateful rollback functionality for better error recovery and blockchain reorganization handling
- **Refactored**: Address type handling in stateful computations
- **Reorganized**: Stateful module structure for better maintainability
- **Enhanced**: Builder patterns for grouped vector operations
- **Improved**: Memory efficiency through lazy computation strategies
### Vector Storage ### Data Structures
- **Enhanced**: Vector storage engine development workflow - **Added**: New [StoredI16](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_structs/src/structs/stored_i16.rs) data type for efficient 16-bit signed integer storage with compression support
- **Optimized**: Lazy vector computation patterns for better performance - **Enhanced**: StoredF32 with additional [utility methods](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/crates/brk_structs/src/structs/stored_f32.rs) for mathematical operations
- **Improved**: Vector builder architecture with lazy evaluation
### Dependencies ### Website Frontend
- **Updated**: Rayon from 1.10.0 to 1.11.0 for improved parallel processing - **Updated**: Upgraded solid-signals from v0.3.2 to [solidjs-signals v0.4.1](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/websites/default/packages/solidjs-signals/) for improved reactivity and performance
- **Migrated**: vecdb from external version 0.1.0 to local development path for better development workflow - **Enhanced**: Frontend package management and dependency organization
- **Reorganized**: Workspace dependency structure for consistency - **Improved**: Chart rendering performance with updated signal library
### Build System ### Build System
- **Added**: Rust toolchain version specification (1.89) to workspace configuration - **Updated**: All crate versions from 0.0.88 to 0.0.89 across the workspace
- **Enhanced**: Development environment consistency with toolchain pinning - **Enhanced**: [Cargo.toml](https://github.com/bitcoinresearchkit/brk/blob/v0.0.89/Cargo.toml) dependency management and version consistency
### Server Module [View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.0.88...v0.0.89)
- **Improved**: API interface implementations
- **Enhanced**: File serving functionality
### Indexer Module
- **Optimized**: Integration with updated computer module patterns
## [v0.0.88](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.0.88) - 2025-08-10 ## [v0.0.88](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.0.88) - 2025-08-10
Generated
+35 -32
View File
@@ -487,7 +487,7 @@ dependencies = [
[[package]] [[package]]
name = "brk" name = "brk"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"brk_bundler", "brk_bundler",
"brk_cli", "brk_cli",
@@ -506,7 +506,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_bundler" name = "brk_bundler"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"brk_rolldown", "brk_rolldown",
"log", "log",
@@ -517,7 +517,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_cli" name = "brk_cli"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"bitcoincore-rpc", "bitcoincore-rpc",
"brk_bundler", "brk_bundler",
@@ -542,7 +542,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_computer" name = "brk_computer"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -564,7 +564,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_error" name = "brk_error"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"bitcoincore-rpc", "bitcoincore-rpc",
"fjall", "fjall",
@@ -577,7 +577,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_fetcher" name = "brk_fetcher"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"brk_error", "brk_error",
"brk_logger", "brk_logger",
@@ -589,7 +589,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_indexer" name = "brk_indexer"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -606,7 +606,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_interface" name = "brk_interface"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"brk_computer", "brk_computer",
"brk_error", "brk_error",
@@ -623,7 +623,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_logger" name = "brk_logger"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"env_logger", "env_logger",
"jiff", "jiff",
@@ -633,7 +633,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_mcp" name = "brk_mcp"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"axum", "axum",
"brk_interface", "brk_interface",
@@ -643,7 +643,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_parser" name = "brk_parser"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -1021,7 +1021,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_server" name = "brk_server"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"axum", "axum",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -1045,7 +1045,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_store" name = "brk_store"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"brk_error", "brk_error",
"brk_structs", "brk_structs",
@@ -1068,7 +1068,7 @@ dependencies = [
[[package]] [[package]]
name = "brk_structs" name = "brk_structs"
version = "0.0.89" version = "0.0.94"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
@@ -1198,18 +1198,18 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.45" version = "4.5.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
] ]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.44" version = "4.5.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -1735,9 +1735,9 @@ dependencies = [
[[package]] [[package]]
name = "fancy-regex" name = "fancy-regex"
version = "0.14.0" version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" checksum = "bf04c5ec15464ace8355a7b440a33aece288993475556d461154d7a62ad9947c"
dependencies = [ dependencies = [
"bit-set", "bit-set",
"regex-automata", "regex-automata",
@@ -3054,9 +3054,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_resolver" name = "oxc_resolver"
version = "11.6.2" version = "11.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d84cdcd778d15db5b21cc61baf79ac55cee97e7feb725b2664453979ba3cd76" checksum = "0784392356fa78dd4c9047fce7c9046c141f8990736792d00310bf40935b1870"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"indexmap 2.11.0", "indexmap 2.11.0",
@@ -3407,9 +3407,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]] [[package]]
name = "pnp" name = "pnp"
version = "0.12.1" version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab3167cbab15e437e9c7db8a4cf613eb4a77583d4327a8964d50fedd6cf364bd" checksum = "e001eb06e9523653f2a88adb94e286ef5d7acfe64158b21bf57a6f6bc3ba65ca"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"clean-path", "clean-path",
@@ -3602,9 +3602,12 @@ dependencies = [
[[package]] [[package]]
name = "rapidhash" name = "rapidhash"
version = "3.1.0" version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efee4b7317469c6c6e7fdeee3d094313af846a97678d6ed971d83a852d730083" checksum = "9d126f24bc587b080d7823a831d0fe832090a606fd3fd244ecbe23c561104ab8"
dependencies = [
"rustversion",
]
[[package]] [[package]]
name = "rayon" name = "rayon"
@@ -3895,9 +3898,9 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
[[package]] [[package]]
name = "seqdb" name = "seqdb"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567d567faf0a305d66eb0419fc50ba8faec58a3baa8624d7a1fd1c798395044c" checksum = "c54ab988c96efa9d275ca2b12bf2d3c6adec993b8e82ea31a88c984abdaa14fa"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@@ -4723,9 +4726,9 @@ checksum = "8f54a172d0620933a27a4360d3db3e2ae0dd6cceae9730751a036bbf182c4b23"
[[package]] [[package]]
name = "vecdb" name = "vecdb"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "236493fb96b34fe7900a3bf62cbb1bd1c5991bc9db563dbbe7ce5cc8c3037cb1" checksum = "3e5c4ec34c376be3a41435eeb7672d0ea0e9c1d60c5d1d90218912588f91abea"
dependencies = [ dependencies = [
"ctrlc", "ctrlc",
"log", "log",
@@ -4743,9 +4746,9 @@ dependencies = [
[[package]] [[package]]
name = "vecdb_derive" name = "vecdb_derive"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d117eb4f82c996a7de2dd5bca1f53da20fa39ae97646405af29eccde67be041" checksum = "778c4874c05822465e28cae6a7dead593a73124ec80afb85b85adae5ac883368"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.106", "syn 2.0.106",
+16 -15
View File
@@ -4,7 +4,7 @@ members = ["crates/*"]
package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node" package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node"
package.license = "MIT" package.license = "MIT"
package.edition = "2024" package.edition = "2024"
package.version = "0.0.89" package.version = "0.0.94"
package.homepage = "https://bitcoinresearchkit.org" package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk" package.repository = "https://github.com/bitcoinresearchkit/brk"
package.readme = "README.md" package.readme = "README.md"
@@ -26,19 +26,19 @@ inherits = "release"
axum = "0.8.4" axum = "0.8.4"
bitcoin = { version = "0.32.7", features = ["serde"] } bitcoin = { version = "0.32.7", features = ["serde"] }
bitcoincore-rpc = "0.19.0" bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.89", path = "crates/brk_bundler" } brk_bundler = { version = "0.0.94", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.89", path = "crates/brk_cli" } brk_cli = { version = "0.0.94", path = "crates/brk_cli" }
brk_computer = { version = "0.0.89", path = "crates/brk_computer" } brk_computer = { version = "0.0.94", path = "crates/brk_computer" }
brk_error = { version = "0.0.89", path = "crates/brk_error" } brk_error = { version = "0.0.94", path = "crates/brk_error" }
brk_fetcher = { version = "0.0.89", path = "crates/brk_fetcher" } brk_fetcher = { version = "0.0.94", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.89", path = "crates/brk_indexer" } brk_indexer = { version = "0.0.94", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.89", path = "crates/brk_interface" } brk_interface = { version = "0.0.94", path = "crates/brk_interface" }
brk_logger = { version = "0.0.89", path = "crates/brk_logger" } brk_logger = { version = "0.0.94", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.89", path = "crates/brk_mcp" } brk_mcp = { version = "0.0.94", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.89", path = "crates/brk_parser" } brk_parser = { version = "0.0.94", path = "crates/brk_parser" }
brk_server = { version = "0.0.89", path = "crates/brk_server" } brk_server = { version = "0.0.94", path = "crates/brk_server" }
brk_store = { version = "0.0.89", path = "crates/brk_store" } brk_store = { version = "0.0.94", path = "crates/brk_store" }
brk_structs = { version = "0.0.89", path = "crates/brk_structs" } brk_structs = { version = "0.0.94", path = "crates/brk_structs" }
byteview = "=0.6.1" byteview = "=0.6.1"
derive_deref = "1.1.1" derive_deref = "1.1.1"
fjall = "2.11.2" fjall = "2.11.2"
@@ -53,7 +53,7 @@ serde_derive = "1.0.219"
serde_json = { version = "1.0.143", features = ["float_roundtrip"] } serde_json = { version = "1.0.143", features = ["float_roundtrip"] }
tokio = { version = "1.47.1", features = ["rt-multi-thread"] } tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
# vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]} # vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]}
vecdb = { version = "0.2.4", features = ["derive"]} vecdb = { version = "0.2.5", features = ["derive"]}
zerocopy = "0.8.26" zerocopy = "0.8.26"
zerocopy-derive = "0.8.26" zerocopy-derive = "0.8.26"
@@ -66,6 +66,7 @@ tag-message = "release: v{{version}}"
[workspace.metadata.dist] [workspace.metadata.dist]
cargo-dist-version = "0.29.0" cargo-dist-version = "0.29.0"
ci = "github" ci = "github"
allow-dirty = ["ci"]
installers = [] installers = []
targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu"] targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]
rust-toolchain-version = "1.89" rust-toolchain-version = "1.89"
+3 -4
View File
@@ -31,10 +31,9 @@ In other words it's an alternative to [Glassnode](https://glassnode.com), [mempo
The toolkit can be used in various ways to accommodate as many needs as possible: The toolkit can be used in various ways to accommodate as many needs as possible:
- **[Website](https://bitcoinresearchkit.org)** \ - **[Website](https://bitview.space)** \
Everyone is welcome to visit the official instance and showcase of the suite's capabilities. \ Everyone is welcome to visit the official instance and showcase of the suite's capabilities. \
It has a wide range of functionalities including charts, tables and simulations which you can visit for free and without the need for an account. \ It has a wide range of functionalities including charts, tables and simulations which you can visit for free and without the need for an account.
Also available at: [brekit.org](https://brekit.org) // [kibo.money](https://kibo.money) // [satonomics.xyz](https://satonomics.xyz)
- **[API](https://github.com/bitcoinresearchkit/brk/tree/main/crates/brk_server#brk-server)** \ - **[API](https://github.com/bitcoinresearchkit/brk/tree/main/crates/brk_server#brk-server)** \
Researchers and developers are free to use BRK's public API with ![Datasets variant count](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbitcoinresearchkit.org%2Fapi%2Fvecs%2Fvec-count&query=%24&style=flat&label=%20&color=white) dataset variants at their disposal. \ Researchers and developers are free to use BRK's public API with ![Datasets variant count](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbitcoinresearchkit.org%2Fapi%2Fvecs%2Fvec-count&query=%24&style=flat&label=%20&color=white) dataset variants at their disposal. \
Just like the website, it's entirely free, with no authentication or rate-limiting. Just like the website, it's entirely free, with no authentication or rate-limiting.
@@ -62,7 +61,7 @@ If you'd like to have your own instance hosted for you please contact [hosting@b
- Updates delivered at your convenience - Updates delivered at your convenience
- Direct communication for feature requests and support - Direct communication for feature requests and support
- Bitcoin Core or Knots with desired version - Bitcoin Core or Knots with desired version
- Optional subdomains: `*.bitcoinresearchkit.org`, `*.brekit.org`, `*.kibo.money` and `*.satonomics.xyz` - Optional subdomains
- Logo featured in the Readme if desired - Logo featured in the Readme if desired
Pricing: `0.01 BTC / month` *or* `0.1 BTC / year` Pricing: `0.01 BTC / month` *or* `0.1 BTC / year`
+1 -12
View File
@@ -10,30 +10,19 @@
- pull latest version and notify is out of date - pull latest version and notify is out of date
- _computer_ - _computer_
- **add rollback of states (in stateful)** - **add rollback of states (in stateful)**
- remove configurable format (raw/compressed) and chose sane ones instead - add costs basis by percentile (percentile cost basis) back
- linear reads: compressed (height/date/... + txindex_to_height + txindex_to_version + ...)
- random reads: raw (outputindex_to_value + ...)
- add prices paid by percentile (percentile cost basis) back
- add support for per index computation - add support for per index computation
- fix min feerate which is always ZERO due to coinbase transaction - fix min feerate which is always ZERO due to coinbase transaction
- before computing multiple sources check their length, panic if not equal - before computing multiple sources check their length, panic if not equal
- add oracle price dataset (https://utxo.live/oracle/UTXOracle.py) - add oracle price dataset (https://utxo.live/oracle/UTXOracle.py)
- add address counts relative to all datasets - add address counts relative to all datasets
- make decade, quarter, year datasets `computed` instead of `eager`
- add 6 months (semester) interval datasets to builder
- some datasets in `indexes` can probably be removed
- add revived/sent supply datasets - add revived/sent supply datasets
- add `in-sats` version of all price datasets (average and co) - add `in-sats` version of all price datasets (average and co)
- add `p2pk` group (sum of `p2pk33` and `p2pk65`) - add `p2pk` group (sum of `p2pk33` and `p2pk65`)
- add chopiness datasets - add chopiness datasets
- add utxo count, address count, supply data for by reused addresses in groups by address type - add utxo count, address count, supply data for by reused addresses in groups by address type
- add more date ranges (3-6 months and more) - add more date ranges (3-6 months and more)
- add puell multiple dataset
- add pi cycle dataset - add pi cycle dataset
- add emas of price
- add 7d and 30d ema to sell side risk ratio and sopr
- don't compute everything for all cohorts as some datasets combinations are irrelevant
- addresses/utxos by amount don't need mvrvz for example
- add all possible charts from: - add all possible charts from:
- https://mainnet.observer - https://mainnet.observer
- https://glassnode.com - https://glassnode.com
+1 -1
View File
@@ -20,7 +20,7 @@ brk_logger = { workspace = true }
brk_parser = { workspace = true } brk_parser = { workspace = true }
brk_server = { workspace = true } brk_server = { workspace = true }
vecdb = { workspace = true } vecdb = { workspace = true }
clap = { version = "4.5.45", features = ["string"] } clap = { version = "4.5.46", features = ["string"] }
clap_derive = "4.5.45" clap_derive = "4.5.45"
color-eyre = "0.6.5" color-eyre = "0.6.5"
log = { workspace = true } log = { workspace = true }
+1 -1
View File
@@ -284,7 +284,7 @@ Finally, you can run the program with '-h' for help."
} }
pub fn website(&self) -> Website { pub fn website(&self) -> Website {
self.website.unwrap_or(Website::Default) self.website.unwrap_or(Website::Bitview)
} }
pub fn fetch(&self) -> bool { pub fn fetch(&self) -> bool {
+2 -2
View File
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum)]
pub enum Website { pub enum Website {
None, None,
Default, Bitview,
Custom, Custom,
} }
@@ -20,7 +20,7 @@ impl Website {
pub fn to_folder_name(self) -> &'static str { pub fn to_folder_name(self) -> &'static str {
match self { match self {
Self::Custom => "custom", Self::Custom => "custom",
Self::Default => "default", Self::Bitview => "bitview",
Self::None => unreachable!(), Self::None => unreachable!(),
} }
} }
+19 -4
View File
@@ -78,15 +78,25 @@ impl Vecs {
Source::None, Source::None,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?, )?,
indexes_to_block_size: ComputedVecsFromHeight::forced_import( indexes_to_block_size: ComputedVecsFromHeight::forced_import(
&db, &db,
"block_size", "block_size",
Source::None, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?, )?,
height_to_vbytes: EagerVec::forced_import_compressed( height_to_vbytes: EagerVec::forced_import_compressed(
&db, &db,
@@ -99,7 +109,12 @@ impl Vecs {
Source::None, Source::None,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default()
.add_sum()
.add_minmax()
.add_average()
.add_percentiles()
.add_cumulative(),
)?, )?,
difficultyepoch_to_timestamp: EagerVec::forced_import_compressed( difficultyepoch_to_timestamp: EagerVec::forced_import_compressed(
&db, &db,
+75 -185
View File
@@ -26,6 +26,8 @@ pub struct Vecs {
pub constant_4: ComputedVecsFromHeight<StoredU16>, pub constant_4: ComputedVecsFromHeight<StoredU16>,
pub constant_50: ComputedVecsFromHeight<StoredU16>, pub constant_50: ComputedVecsFromHeight<StoredU16>,
pub constant_100: ComputedVecsFromHeight<StoredU16>, pub constant_100: ComputedVecsFromHeight<StoredU16>,
pub constant_144: ComputedVecsFromHeight<StoredU16>,
pub constant_600: ComputedVecsFromHeight<StoredU16>,
pub constant_minus_1: ComputedVecsFromHeight<StoredI16>, pub constant_minus_1: ComputedVecsFromHeight<StoredI16>,
pub constant_minus_2: ComputedVecsFromHeight<StoredI16>, pub constant_minus_2: ComputedVecsFromHeight<StoredI16>,
pub constant_minus_3: ComputedVecsFromHeight<StoredI16>, pub constant_minus_3: ComputedVecsFromHeight<StoredI16>,
@@ -93,6 +95,22 @@ impl Vecs {
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
constant_144: ComputedVecsFromHeight::forced_import(
&db,
"constant_144",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_600: ComputedVecsFromHeight::forced_import(
&db,
"constant_600",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_minus_1: ComputedVecsFromHeight::forced_import( constant_minus_1: ComputedVecsFromHeight::forced_import(
&db, &db,
"constant_minus_1", "constant_minus_1",
@@ -149,192 +167,62 @@ impl Vecs {
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.constant_0.compute_all( [
indexer, (&mut self.constant_0, 0),
indexes, (&mut self.constant_1, 1),
starting_indexes, (&mut self.constant_2, 2),
exit, (&mut self.constant_3, 3),
|vec, _, indexes, starting_indexes, exit| { (&mut self.constant_4, 4),
vec.compute_to( (&mut self.constant_50, 50),
starting_indexes.height, (&mut self.constant_100, 100),
indexes.height_to_date.len(), (&mut self.constant_144, 144),
indexes.height_to_date.version(), (&mut self.constant_600, 600),
|i| (i, StoredU16::new(0)), ]
exit, .into_iter()
)?; .try_for_each(|(vec, value)| {
Ok(()) vec.compute_all(
}, indexer,
)?; indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(value)),
exit,
)?;
Ok(())
},
)
})?;
self.constant_1.compute_all( [
indexer, (&mut self.constant_minus_1, -1),
indexes, (&mut self.constant_minus_2, -2),
starting_indexes, (&mut self.constant_minus_3, 3),
exit, (&mut self.constant_minus_4, 4),
|vec, _, indexes, starting_indexes, exit| { ]
vec.compute_to( .into_iter()
starting_indexes.height, .try_for_each(|(vec, value)| {
indexes.height_to_date.len(), vec.compute_all(
indexes.height_to_date.version(), indexer,
|i| (i, StoredU16::new(1)), indexes,
exit, starting_indexes,
)?; exit,
Ok(()) |vec, _, indexes, starting_indexes, exit| {
}, vec.compute_to(
)?; starting_indexes.height,
indexes.height_to_date.len(),
self.constant_2.compute_all( indexes.height_to_date.version(),
indexer, |i| (i, StoredI16::new(value)),
indexes, exit,
starting_indexes, )?;
exit, Ok(())
|vec, _, indexes, starting_indexes, exit| { },
vec.compute_to( )
starting_indexes.height, })?;
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(2)),
exit,
)?;
Ok(())
},
)?;
self.constant_3.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(3)),
exit,
)?;
Ok(())
},
)?;
self.constant_4.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(4)),
exit,
)?;
Ok(())
},
)?;
self.constant_50.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(50)),
exit,
)?;
Ok(())
},
)?;
self.constant_100.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(100)),
exit,
)?;
Ok(())
},
)?;
self.constant_minus_1.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(-1)),
exit,
)?;
Ok(())
},
)?;
self.constant_minus_2.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(-2)),
exit,
)?;
Ok(())
},
)?;
self.constant_minus_3.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(-3)),
exit,
)?;
Ok(())
},
)?;
self.constant_minus_4.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(-4)),
exit,
)?;
Ok(())
},
)?;
Ok(()) Ok(())
} }
@@ -348,6 +236,8 @@ impl Vecs {
self.constant_4.vecs(), self.constant_4.vecs(),
self.constant_50.vecs(), self.constant_50.vecs(),
self.constant_100.vecs(), self.constant_100.vecs(),
self.constant_144.vecs(),
self.constant_600.vecs(),
self.constant_minus_1.vecs(), self.constant_minus_1.vecs(),
self.constant_minus_2.vecs(), self.constant_minus_2.vecs(),
self.constant_minus_3.vecs(), self.constant_minus_3.vecs(),
@@ -320,26 +320,25 @@ impl ComputedRatioVecsFromDateIndex {
price: &price::Vecs, price: &price::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
date_to_price_opt: Option<&impl AnyIterableVec<DateIndex, Dollars>>, price_opt: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
) -> Result<()> { ) -> Result<()> {
let date_to_price = date_to_price_opt.unwrap_or_else(|| unsafe { let closes = price.timeindexes_to_close.dateindex.as_ref().unwrap();
let price = price_opt.unwrap_or_else(|| unsafe {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex) std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
}); });
let closes = price.timeindexes_to_close.dateindex.as_ref().unwrap();
self.ratio.compute_all( self.ratio.compute_all(
indexer, indexer,
indexes, indexes,
starting_indexes, starting_indexes,
exit, exit,
|v, _, _, starting_indexes, exit| { |v, _, _, starting_indexes, exit| {
let mut price = date_to_price.iter(); v.compute_transform2(
v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
closes, closes,
|(i, close, ..)| { price,
let price = price.unwrap_get_inner(i); |(i, close, price, ..)| {
if price == Dollars::ZERO { if price == Dollars::ZERO {
(i, StoredF32::from(1.0)) (i, StoredF32::from(1.0))
} else { } else {
@@ -553,7 +552,7 @@ impl ComputedRatioVecsFromDateIndex {
None as Option<&EagerVec<_, _>>, None as Option<&EagerVec<_, _>>,
)?; )?;
let date_to_price = date_to_price_opt.unwrap_or_else(|| unsafe { let date_to_price = price_opt.unwrap_or_else(|| unsafe {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex) std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
}); });
+2
View File
@@ -52,6 +52,8 @@ impl Computer {
indexer: &Indexer, indexer: &Indexer,
fetcher: Option<Fetcher>, fetcher: Option<Fetcher>,
) -> Result<Self> { ) -> Result<Self> {
info!("Importing computer...");
let computed_path = outputs_path.join("computed"); let computed_path = outputs_path.join("computed");
let indexes = let indexes =
+220 -17
View File
@@ -48,6 +48,21 @@ pub struct Vecs {
pub indexes_to_200w_sma: ComputedRatioVecsFromDateIndex, pub indexes_to_200w_sma: ComputedRatioVecsFromDateIndex,
pub indexes_to_4y_sma: ComputedRatioVecsFromDateIndex, pub indexes_to_4y_sma: ComputedRatioVecsFromDateIndex,
pub indexes_to_1w_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_8d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_13d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_21d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_1m_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_34d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_55d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_89d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_144d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_200d_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_1y_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_2y_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_200w_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_4y_ema: ComputedRatioVecsFromDateIndex,
pub indexes_to_200d_sma_x2_4: ComputedVecsFromDateIndex<Dollars>, pub indexes_to_200d_sma_x2_4: ComputedVecsFromDateIndex<Dollars>,
pub indexes_to_200d_sma_x0_8: ComputedVecsFromDateIndex<Dollars>, pub indexes_to_200d_sma_x0_8: ComputedVecsFromDateIndex<Dollars>,
@@ -350,6 +365,119 @@ impl Vecs {
true, true,
)?, )?,
indexes_to_1w_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"1w_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_8d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"8d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_13d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"13d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_21d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"21d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_1m_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"1m_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_34d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"34d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_55d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"55d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_89d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"89d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_144d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"144d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_200d_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"200d_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_1y_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"1y_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_2y_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"2y_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_200w_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"200w_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
indexes_to_4y_ema: ComputedRatioVecsFromDateIndex::forced_import(
&db,
"4y_ema",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
true,
)?,
_1d_returns: ComputedVecsFromDateIndex::forced_import( _1d_returns: ComputedVecsFromDateIndex::forced_import(
&db, &db,
"1d_returns", "1d_returns",
@@ -1827,25 +1955,69 @@ impl Vecs {
thread::scope(|s| -> Result<()> { thread::scope(|s| -> Result<()> {
[ [
(&mut self.indexes_to_1w_sma, 7), (&mut self.indexes_to_1w_sma, &mut self.indexes_to_1w_ema, 7),
(&mut self.indexes_to_8d_sma, 8), (&mut self.indexes_to_8d_sma, &mut self.indexes_to_8d_ema, 8),
(&mut self.indexes_to_13d_sma, 13), (
(&mut self.indexes_to_21d_sma, 21), &mut self.indexes_to_13d_sma,
(&mut self.indexes_to_1m_sma, 30), &mut self.indexes_to_13d_ema,
(&mut self.indexes_to_34d_sma, 34), 13,
(&mut self.indexes_to_55d_sma, 55), ),
(&mut self.indexes_to_89d_sma, 89), (
(&mut self.indexes_to_144d_sma, 144), &mut self.indexes_to_21d_sma,
(&mut self.indexes_to_200d_sma, 200), &mut self.indexes_to_21d_ema,
(&mut self.indexes_to_1y_sma, 365), 21,
(&mut self.indexes_to_2y_sma, 2 * 365), ),
(&mut self.indexes_to_200w_sma, 200 * 7), (&mut self.indexes_to_1m_sma, &mut self.indexes_to_1m_ema, 30),
(&mut self.indexes_to_4y_sma, 4 * 365), (
&mut self.indexes_to_34d_sma,
&mut self.indexes_to_34d_ema,
34,
),
(
&mut self.indexes_to_55d_sma,
&mut self.indexes_to_55d_ema,
55,
),
(
&mut self.indexes_to_89d_sma,
&mut self.indexes_to_89d_ema,
89,
),
(
&mut self.indexes_to_144d_sma,
&mut self.indexes_to_144d_ema,
144,
),
(
&mut self.indexes_to_200d_sma,
&mut self.indexes_to_200d_ema,
200,
),
(
&mut self.indexes_to_1y_sma,
&mut self.indexes_to_1y_ema,
365,
),
(
&mut self.indexes_to_2y_sma,
&mut self.indexes_to_2y_ema,
2 * 365,
),
(
&mut self.indexes_to_200w_sma,
&mut self.indexes_to_200w_ema,
200 * 7,
),
(
&mut self.indexes_to_4y_sma,
&mut self.indexes_to_4y_ema,
4 * 365,
),
] ]
.into_iter() .into_iter()
.for_each(|(vecs, sma)| { .for_each(|(sma, ema, days)| {
s.spawn(move || -> Result<()> { s.spawn(move || -> Result<()> {
vecs.compute_all( sma.compute_all(
indexer, indexer,
indexes, indexes,
price, price,
@@ -1855,7 +2027,24 @@ impl Vecs {
v.compute_sma( v.compute_sma(
starting_indexes.dateindex, starting_indexes.dateindex,
price.timeindexes_to_close.dateindex.as_ref().unwrap(), price.timeindexes_to_close.dateindex.as_ref().unwrap(),
sma, days,
exit,
)?;
Ok(())
},
)?;
ema.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_ema(
starting_indexes.dateindex,
price.timeindexes_to_close.dateindex.as_ref().unwrap(),
days,
exit, exit,
)?; )?;
Ok(()) Ok(())
@@ -1935,6 +2124,20 @@ impl Vecs {
self.indexes_to_2y_sma.vecs(), self.indexes_to_2y_sma.vecs(),
self.indexes_to_200w_sma.vecs(), self.indexes_to_200w_sma.vecs(),
self.indexes_to_4y_sma.vecs(), self.indexes_to_4y_sma.vecs(),
self.indexes_to_1w_ema.vecs(),
self.indexes_to_8d_ema.vecs(),
self.indexes_to_13d_ema.vecs(),
self.indexes_to_21d_ema.vecs(),
self.indexes_to_1m_ema.vecs(),
self.indexes_to_34d_ema.vecs(),
self.indexes_to_55d_ema.vecs(),
self.indexes_to_89d_ema.vecs(),
self.indexes_to_144d_ema.vecs(),
self.indexes_to_200d_ema.vecs(),
self.indexes_to_1y_ema.vecs(),
self.indexes_to_2y_ema.vecs(),
self.indexes_to_200w_ema.vecs(),
self.indexes_to_4y_ema.vecs(),
self.indexes_to_200d_sma_x0_8.vecs(), self.indexes_to_200d_sma_x0_8.vecs(),
self.indexes_to_200d_sma_x2_4.vecs(), self.indexes_to_200d_sma_x2_4.vecs(),
self.price_1d_ago.vecs(), self.price_1d_ago.vecs(),
@@ -79,8 +79,8 @@ impl Vecs {
version, version,
indexes, indexes,
price, price,
compute_relative_to_all,
false, false,
compute_relative_to_all,
false, false,
)?, )?,
}) })
+337 -3
View File
@@ -50,10 +50,18 @@ pub struct Vecs {
pub indexes_to_coinblocks_destroyed: ComputedVecsFromHeight<StoredF64>, pub indexes_to_coinblocks_destroyed: ComputedVecsFromHeight<StoredF64>,
pub indexes_to_coindays_destroyed: ComputedVecsFromHeight<StoredF64>, pub indexes_to_coindays_destroyed: ComputedVecsFromHeight<StoredF64>,
pub dateindex_to_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_spent_output_profit_ratio_7d_ema: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_spent_output_profit_ratio_30d_ema: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_adjusted_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>, pub dateindex_to_adjusted_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_adjusted_spent_output_profit_ratio_7d_ema:
Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_adjusted_spent_output_profit_ratio_30d_ema:
Option<EagerVec<DateIndex, StoredF32>>,
pub indexes_to_realized_cap_30d_change: Option<ComputedVecsFromDateIndex<Dollars>>, pub indexes_to_realized_cap_30d_change: Option<ComputedVecsFromDateIndex<Dollars>>,
pub dateindex_to_sell_side_risk_ratio: Option<EagerVec<DateIndex, StoredF32>>, pub dateindex_to_sell_side_risk_ratio: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_spent_output_profit_ratio: Option<EagerVec<DateIndex, StoredF32>>, pub dateindex_to_sell_side_risk_ratio_7d_ema: Option<EagerVec<DateIndex, StoredF32>>,
pub dateindex_to_sell_side_risk_ratio_30d_ema: Option<EagerVec<DateIndex, StoredF32>>,
pub indexes_to_adjusted_value_created: Option<ComputedVecsFromHeight<Dollars>>, pub indexes_to_adjusted_value_created: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_adjusted_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>, pub indexes_to_adjusted_value_destroyed: Option<ComputedVecsFromHeight<Dollars>>,
pub indexes_to_negative_realized_loss: Option<ComputedVecsFromHeight<Dollars>>, pub indexes_to_negative_realized_loss: Option<ComputedVecsFromHeight<Dollars>>,
@@ -79,8 +87,18 @@ pub struct Vecs {
pub indexes_to_negative_unrealized_loss: Option<ComputedVecsFromDateIndex<Dollars>>, pub indexes_to_negative_unrealized_loss: Option<ComputedVecsFromDateIndex<Dollars>>,
pub height_to_net_unrealized_profit_and_loss: Option<EagerVec<Height, Dollars>>, pub height_to_net_unrealized_profit_and_loss: Option<EagerVec<Height, Dollars>>,
pub indexes_to_net_unrealized_profit_and_loss: Option<ComputedVecsFromDateIndex<Dollars>>, pub indexes_to_net_unrealized_profit_and_loss: Option<ComputedVecsFromDateIndex<Dollars>>,
pub height_to_unrealized_profit_relative_to_market_cap: Option<EagerVec<Height, StoredF32>>,
pub height_to_unrealized_loss_relative_to_market_cap: Option<EagerVec<Height, StoredF32>>,
pub height_to_negative_unrealized_loss_relative_to_market_cap:
Option<EagerVec<Height, StoredF32>>,
pub height_to_net_unrealized_profit_and_loss_relative_to_market_cap: pub height_to_net_unrealized_profit_and_loss_relative_to_market_cap:
Option<EagerVec<Height, StoredF32>>, Option<EagerVec<Height, StoredF32>>,
pub indexes_to_unrealized_profit_relative_to_market_cap:
Option<ComputedVecsFromDateIndex<StoredF32>>,
pub indexes_to_unrealized_loss_relative_to_market_cap:
Option<ComputedVecsFromDateIndex<StoredF32>>,
pub indexes_to_negative_unrealized_loss_relative_to_market_cap:
Option<ComputedVecsFromDateIndex<StoredF32>>,
pub indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap: pub indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap:
Option<ComputedVecsFromDateIndex<StoredF32>>, Option<ComputedVecsFromDateIndex<StoredF32>>,
pub indexes_to_realized_profit_relative_to_realized_cap: pub indexes_to_realized_profit_relative_to_realized_cap:
@@ -132,8 +150,8 @@ impl Vecs {
version: Version, version: Version,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
extended: bool,
compute_relative_to_all: bool, compute_relative_to_all: bool,
ratio_extended: bool,
compute_adjusted: bool, compute_adjusted: bool,
) -> Result<Self> { ) -> Result<Self> {
let compute_dollars = price.is_some(); let compute_dollars = price.is_some();
@@ -416,7 +434,7 @@ impl Vecs {
Source::None, Source::None,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
ratio_extended, extended,
) )
.unwrap() .unwrap()
}), }),
@@ -599,6 +617,24 @@ impl Vecs {
) )
.unwrap() .unwrap()
}), }),
dateindex_to_sell_side_risk_ratio_7d_ema: compute_dollars.then(|| {
EagerVec::forced_import(
db,
&suffix("sell_side_risk_ratio_7d_ema"),
version + VERSION + Version::ONE,
format,
)
.unwrap()
}),
dateindex_to_sell_side_risk_ratio_30d_ema: compute_dollars.then(|| {
EagerVec::forced_import(
db,
&suffix("sell_side_risk_ratio_30d_ema"),
version + VERSION + Version::ONE,
format,
)
.unwrap()
}),
dateindex_to_spent_output_profit_ratio: compute_dollars.then(|| { dateindex_to_spent_output_profit_ratio: compute_dollars.then(|| {
EagerVec::forced_import( EagerVec::forced_import(
db, db,
@@ -608,6 +644,24 @@ impl Vecs {
) )
.unwrap() .unwrap()
}), }),
dateindex_to_spent_output_profit_ratio_7d_ema: compute_dollars.then(|| {
EagerVec::forced_import(
db,
&suffix("spent_output_profit_ratio_7d_ema"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
}),
dateindex_to_spent_output_profit_ratio_30d_ema: compute_dollars.then(|| {
EagerVec::forced_import(
db,
&suffix("spent_output_profit_ratio_30d_ema"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
}),
dateindex_to_adjusted_spent_output_profit_ratio: (compute_dollars && compute_adjusted).then(|| { dateindex_to_adjusted_spent_output_profit_ratio: (compute_dollars && compute_adjusted).then(|| {
EagerVec::forced_import( EagerVec::forced_import(
db, db,
@@ -617,6 +671,24 @@ impl Vecs {
) )
.unwrap() .unwrap()
}), }),
dateindex_to_adjusted_spent_output_profit_ratio_7d_ema: (compute_dollars && compute_adjusted).then(|| {
EagerVec::forced_import(
db,
&suffix("adjusted_spent_output_profit_ratio_7d_ema"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
}),
dateindex_to_adjusted_spent_output_profit_ratio_30d_ema: (compute_dollars && compute_adjusted).then(|| {
EagerVec::forced_import(
db,
&suffix("adjusted_spent_output_profit_ratio_30d_ema"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
}),
height_to_halved_supply_value: ComputedHeightValueVecs::forced_import( height_to_halved_supply_value: ComputedHeightValueVecs::forced_import(
db, db,
&suffix("halved_supply"), &suffix("halved_supply"),
@@ -674,6 +746,39 @@ impl Vecs {
) )
.unwrap() .unwrap()
}), }),
height_to_unrealized_profit_relative_to_market_cap: compute_dollars.then(
|| {
EagerVec::forced_import(
db,
&suffix("unrealized_profit_relative_to_market_cap"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
},
),
height_to_unrealized_loss_relative_to_market_cap: compute_dollars.then(
|| {
EagerVec::forced_import(
db,
&suffix("unrealized_loss_relative_to_market_cap"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
},
),
height_to_negative_unrealized_loss_relative_to_market_cap: compute_dollars.then(
|| {
EagerVec::forced_import(
db,
&suffix("negative_unrealized_loss_relative_to_market_cap"),
version + VERSION + Version::ZERO,
format,
)
.unwrap()
},
),
height_to_net_unrealized_profit_and_loss_relative_to_market_cap: compute_dollars.then( height_to_net_unrealized_profit_and_loss_relative_to_market_cap: compute_dollars.then(
|| { || {
EagerVec::forced_import( EagerVec::forced_import(
@@ -685,6 +790,45 @@ impl Vecs {
.unwrap() .unwrap()
}, },
), ),
indexes_to_unrealized_profit_relative_to_market_cap: compute_dollars.then(
|| {
ComputedVecsFromDateIndex::forced_import(
db,
&suffix("unrealized_profit_relative_to_market_cap"),
Source::Compute,
version + VERSION + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)
.unwrap()
},
),
indexes_to_unrealized_loss_relative_to_market_cap: compute_dollars.then(
|| {
ComputedVecsFromDateIndex::forced_import(
db,
&suffix("unrealized_loss_relative_to_market_cap"),
Source::Compute,
version + VERSION + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)
.unwrap()
},
),
indexes_to_negative_unrealized_loss_relative_to_market_cap: compute_dollars.then(
|| {
ComputedVecsFromDateIndex::forced_import(
db,
&suffix("negative_unrealized_loss_relative_to_market_cap"),
Source::Compute,
version + VERSION + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)
.unwrap()
},
),
indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap: compute_dollars.then( indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap: compute_dollars.then(
|| { || {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
@@ -2177,6 +2321,30 @@ impl Vecs {
exit, exit,
)?; )?;
self.dateindex_to_spent_output_profit_ratio_7d_ema
.as_mut()
.unwrap()
.compute_ema(
starting_indexes.dateindex,
self.dateindex_to_spent_output_profit_ratio
.as_ref()
.unwrap(),
7,
exit,
)?;
self.dateindex_to_spent_output_profit_ratio_30d_ema
.as_mut()
.unwrap()
.compute_ema(
starting_indexes.dateindex,
self.dateindex_to_spent_output_profit_ratio
.as_ref()
.unwrap(),
30,
exit,
)?;
self.dateindex_to_sell_side_risk_ratio self.dateindex_to_sell_side_risk_ratio
.as_mut() .as_mut()
.unwrap() .unwrap()
@@ -2195,6 +2363,26 @@ impl Vecs {
exit, exit,
)?; )?;
self.dateindex_to_sell_side_risk_ratio_7d_ema
.as_mut()
.unwrap()
.compute_ema(
starting_indexes.dateindex,
self.dateindex_to_sell_side_risk_ratio.as_ref().unwrap(),
7,
exit,
)?;
self.dateindex_to_sell_side_risk_ratio_30d_ema
.as_mut()
.unwrap()
.compute_ema(
starting_indexes.dateindex,
self.dateindex_to_sell_side_risk_ratio.as_ref().unwrap(),
30,
exit,
)?;
self.indexes_to_supply_in_profit self.indexes_to_supply_in_profit
.as_mut() .as_mut()
.unwrap() .unwrap()
@@ -2316,6 +2504,33 @@ impl Vecs {
Ok(()) Ok(())
}, },
)?; )?;
self.height_to_unrealized_profit_relative_to_market_cap
.as_mut()
.unwrap()
.compute_percentage(
starting_indexes.height,
self.height_to_unrealized_profit.as_ref().unwrap(),
&market.height_to_marketcap,
exit,
)?;
self.height_to_unrealized_loss_relative_to_market_cap
.as_mut()
.unwrap()
.compute_percentage(
starting_indexes.height,
self.height_to_unrealized_loss.as_ref().unwrap(),
&market.height_to_marketcap,
exit,
)?;
self.height_to_negative_unrealized_loss_relative_to_market_cap
.as_mut()
.unwrap()
.compute_percentage(
starting_indexes.height,
self.height_to_negative_unrealized_loss.as_ref().unwrap(),
&market.height_to_marketcap,
exit,
)?;
self.height_to_net_unrealized_profit_and_loss_relative_to_market_cap self.height_to_net_unrealized_profit_and_loss_relative_to_market_cap
.as_mut() .as_mut()
.unwrap() .unwrap()
@@ -2327,6 +2542,65 @@ impl Vecs {
&market.height_to_marketcap, &market.height_to_marketcap,
exit, exit,
)?; )?;
self.indexes_to_unrealized_profit_relative_to_market_cap
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_percentage(
starting_indexes.dateindex,
self.dateindex_to_unrealized_profit.as_ref().unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
},
)?;
self.indexes_to_unrealized_loss_relative_to_market_cap
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_percentage(
starting_indexes.dateindex,
self.dateindex_to_unrealized_loss.as_ref().unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
},
)?;
self.indexes_to_negative_unrealized_loss_relative_to_market_cap
.as_mut()
.unwrap()
.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_negative_unrealized_loss
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
market.indexes_to_marketcap.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
},
)?;
self.indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap self.indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap
.as_mut() .as_mut()
.unwrap() .unwrap()
@@ -2757,6 +3031,30 @@ impl Vecs {
.unwrap_sum(), .unwrap_sum(),
exit, exit,
)?; )?;
self.dateindex_to_adjusted_spent_output_profit_ratio_7d_ema
.as_mut()
.unwrap()
.compute_ema(
starting_indexes.dateindex,
self.dateindex_to_adjusted_spent_output_profit_ratio
.as_ref()
.unwrap(),
7,
exit,
)?;
self.dateindex_to_adjusted_spent_output_profit_ratio_30d_ema
.as_mut()
.unwrap()
.compute_ema(
starting_indexes.dateindex,
self.dateindex_to_adjusted_spent_output_profit_ratio
.as_ref()
.unwrap(),
30,
exit,
)?;
} }
} }
@@ -2823,9 +3121,21 @@ impl Vecs {
self.dateindex_to_spent_output_profit_ratio self.dateindex_to_spent_output_profit_ratio
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]), .map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_spent_output_profit_ratio_7d_ema
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_spent_output_profit_ratio_30d_ema
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_adjusted_spent_output_profit_ratio self.dateindex_to_adjusted_spent_output_profit_ratio
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]), .map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_adjusted_spent_output_profit_ratio_7d_ema
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_to_adjusted_spent_output_profit_ratio_30d_ema
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.indexes_to_value_destroyed self.indexes_to_value_destroyed
.as_ref() .as_ref()
.map_or(vec![], |v| v.vecs()), .map_or(vec![], |v| v.vecs()),
@@ -2844,6 +3154,12 @@ impl Vecs {
self.dateindex_to_sell_side_risk_ratio self.dateindex_to_sell_side_risk_ratio
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v]), .map_or(vec![], |v| vec![v]),
self.dateindex_to_sell_side_risk_ratio_7d_ema
.as_ref()
.map_or(vec![], |v| vec![v]),
self.dateindex_to_sell_side_risk_ratio_30d_ema
.as_ref()
.map_or(vec![], |v| vec![v]),
self.height_to_supply_in_profit self.height_to_supply_in_profit
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v]), .map_or(vec![], |v| vec![v]),
@@ -2914,9 +3230,27 @@ impl Vecs {
self.indexes_to_net_unrealized_profit_and_loss self.indexes_to_net_unrealized_profit_and_loss
.as_ref() .as_ref()
.map_or(vec![], |v| v.vecs()), .map_or(vec![], |v| v.vecs()),
self.height_to_unrealized_profit_relative_to_market_cap
.as_ref()
.map_or(vec![], |v| vec![v]),
self.height_to_unrealized_loss_relative_to_market_cap
.as_ref()
.map_or(vec![], |v| vec![v]),
self.height_to_negative_unrealized_loss_relative_to_market_cap
.as_ref()
.map_or(vec![], |v| vec![v]),
self.height_to_net_unrealized_profit_and_loss_relative_to_market_cap self.height_to_net_unrealized_profit_and_loss_relative_to_market_cap
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v]), .map_or(vec![], |v| vec![v]),
self.indexes_to_unrealized_profit_relative_to_market_cap
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_unrealized_loss_relative_to_market_cap
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_negative_unrealized_loss_relative_to_market_cap
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap self.indexes_to_net_unrealized_profit_and_loss_relative_to_market_cap
.as_ref() .as_ref()
.map_or(vec![], |v| v.vecs()), .map_or(vec![], |v| v.vecs()),
@@ -32,8 +32,8 @@ impl Vecs {
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
states_path: Option<&Path>, states_path: Option<&Path>,
extended: bool,
compute_relative_to_all: bool, compute_relative_to_all: bool,
ratio_extended: bool,
compute_adjusted: bool, compute_adjusted: bool,
) -> Result<Self> { ) -> Result<Self> {
let compute_dollars = price.is_some(); let compute_dollars = price.is_some();
@@ -56,8 +56,8 @@ impl Vecs {
version, version,
indexes, indexes,
price, price,
extended,
compute_relative_to_all, compute_relative_to_all,
ratio_extended,
compute_adjusted, compute_adjusted,
)?, )?,
}) })
@@ -38,12 +38,12 @@ impl Vecs {
db, db,
None, None,
format, format,
version + VERSION + Version::ZERO, version + VERSION + Version::ONE,
indexes, indexes,
price, price,
None, None,
false,
true, true,
false,
true, true,
)?, )?,
term: ByTerm { term: ByTerm {
@@ -143,8 +143,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2pk33: utxo_cohort::Vecs::forced_import( p2pk33: utxo_cohort::Vecs::forced_import(
@@ -155,8 +155,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2pkh: utxo_cohort::Vecs::forced_import( p2pkh: utxo_cohort::Vecs::forced_import(
@@ -167,8 +167,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2sh: utxo_cohort::Vecs::forced_import( p2sh: utxo_cohort::Vecs::forced_import(
@@ -179,8 +179,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2wpkh: utxo_cohort::Vecs::forced_import( p2wpkh: utxo_cohort::Vecs::forced_import(
@@ -191,8 +191,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2wsh: utxo_cohort::Vecs::forced_import( p2wsh: utxo_cohort::Vecs::forced_import(
@@ -203,8 +203,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2tr: utxo_cohort::Vecs::forced_import( p2tr: utxo_cohort::Vecs::forced_import(
@@ -215,8 +215,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2a: utxo_cohort::Vecs::forced_import( p2a: utxo_cohort::Vecs::forced_import(
@@ -227,8 +227,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
p2ms: utxo_cohort::Vecs::forced_import( p2ms: utxo_cohort::Vecs::forced_import(
@@ -239,8 +239,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
empty: utxo_cohort::Vecs::forced_import( empty: utxo_cohort::Vecs::forced_import(
@@ -251,8 +251,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
unknown: utxo_cohort::Vecs::forced_import( unknown: utxo_cohort::Vecs::forced_import(
@@ -263,8 +263,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
}, },
@@ -955,8 +955,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_1sat_to_10sats: utxo_cohort::Vecs::forced_import( _1sat_to_10sats: utxo_cohort::Vecs::forced_import(
@@ -967,8 +967,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_10sats_to_100sats: utxo_cohort::Vecs::forced_import( _10sats_to_100sats: utxo_cohort::Vecs::forced_import(
@@ -979,8 +979,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_100sats_to_1k_sats: utxo_cohort::Vecs::forced_import( _100sats_to_1k_sats: utxo_cohort::Vecs::forced_import(
@@ -991,8 +991,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_1k_sats_to_10k_sats: utxo_cohort::Vecs::forced_import( _1k_sats_to_10k_sats: utxo_cohort::Vecs::forced_import(
@@ -1003,8 +1003,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_10k_sats_to_100k_sats: utxo_cohort::Vecs::forced_import( _10k_sats_to_100k_sats: utxo_cohort::Vecs::forced_import(
@@ -1015,8 +1015,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_100k_sats_to_1m_sats: utxo_cohort::Vecs::forced_import( _100k_sats_to_1m_sats: utxo_cohort::Vecs::forced_import(
@@ -1027,8 +1027,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_1m_sats_to_10m_sats: utxo_cohort::Vecs::forced_import( _1m_sats_to_10m_sats: utxo_cohort::Vecs::forced_import(
@@ -1039,8 +1039,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_10m_sats_to_1btc: utxo_cohort::Vecs::forced_import( _10m_sats_to_1btc: utxo_cohort::Vecs::forced_import(
@@ -1051,8 +1051,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_1btc_to_10btc: utxo_cohort::Vecs::forced_import( _1btc_to_10btc: utxo_cohort::Vecs::forced_import(
@@ -1063,8 +1063,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_10btc_to_100btc: utxo_cohort::Vecs::forced_import( _10btc_to_100btc: utxo_cohort::Vecs::forced_import(
@@ -1075,8 +1075,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_100btc_to_1k_btc: utxo_cohort::Vecs::forced_import( _100btc_to_1k_btc: utxo_cohort::Vecs::forced_import(
@@ -1087,8 +1087,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_1k_btc_to_10k_btc: utxo_cohort::Vecs::forced_import( _1k_btc_to_10k_btc: utxo_cohort::Vecs::forced_import(
@@ -1099,8 +1099,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_10k_btc_to_100k_btc: utxo_cohort::Vecs::forced_import( _10k_btc_to_100k_btc: utxo_cohort::Vecs::forced_import(
@@ -1111,8 +1111,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
_100k_btc_or_more: utxo_cohort::Vecs::forced_import( _100k_btc_or_more: utxo_cohort::Vecs::forced_import(
@@ -1123,8 +1123,8 @@ impl Vecs {
indexes, indexes,
price, price,
Some(states_path), Some(states_path),
true,
false, false,
true,
false, false,
)?, )?,
}, },
@@ -1137,8 +1137,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100sats: utxo_cohort::Vecs::forced_import( _100sats: utxo_cohort::Vecs::forced_import(
@@ -1149,8 +1149,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1k_sats: utxo_cohort::Vecs::forced_import( _1k_sats: utxo_cohort::Vecs::forced_import(
@@ -1161,8 +1161,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10k_sats: utxo_cohort::Vecs::forced_import( _10k_sats: utxo_cohort::Vecs::forced_import(
@@ -1173,8 +1173,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100k_sats: utxo_cohort::Vecs::forced_import( _100k_sats: utxo_cohort::Vecs::forced_import(
@@ -1185,8 +1185,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1m_sats: utxo_cohort::Vecs::forced_import( _1m_sats: utxo_cohort::Vecs::forced_import(
@@ -1197,8 +1197,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10m_sats: utxo_cohort::Vecs::forced_import( _10m_sats: utxo_cohort::Vecs::forced_import(
@@ -1209,8 +1209,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1btc: utxo_cohort::Vecs::forced_import( _1btc: utxo_cohort::Vecs::forced_import(
@@ -1221,8 +1221,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10btc: utxo_cohort::Vecs::forced_import( _10btc: utxo_cohort::Vecs::forced_import(
@@ -1233,8 +1233,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100btc: utxo_cohort::Vecs::forced_import( _100btc: utxo_cohort::Vecs::forced_import(
@@ -1245,8 +1245,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1k_btc: utxo_cohort::Vecs::forced_import( _1k_btc: utxo_cohort::Vecs::forced_import(
@@ -1257,8 +1257,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10k_btc: utxo_cohort::Vecs::forced_import( _10k_btc: utxo_cohort::Vecs::forced_import(
@@ -1269,8 +1269,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100k_btc: utxo_cohort::Vecs::forced_import( _100k_btc: utxo_cohort::Vecs::forced_import(
@@ -1281,8 +1281,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
}, },
@@ -1295,8 +1295,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10sats: utxo_cohort::Vecs::forced_import( _10sats: utxo_cohort::Vecs::forced_import(
@@ -1307,8 +1307,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100sats: utxo_cohort::Vecs::forced_import( _100sats: utxo_cohort::Vecs::forced_import(
@@ -1319,8 +1319,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1k_sats: utxo_cohort::Vecs::forced_import( _1k_sats: utxo_cohort::Vecs::forced_import(
@@ -1331,8 +1331,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10k_sats: utxo_cohort::Vecs::forced_import( _10k_sats: utxo_cohort::Vecs::forced_import(
@@ -1343,8 +1343,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100k_sats: utxo_cohort::Vecs::forced_import( _100k_sats: utxo_cohort::Vecs::forced_import(
@@ -1355,8 +1355,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1m_sats: utxo_cohort::Vecs::forced_import( _1m_sats: utxo_cohort::Vecs::forced_import(
@@ -1367,8 +1367,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10m_sats: utxo_cohort::Vecs::forced_import( _10m_sats: utxo_cohort::Vecs::forced_import(
@@ -1379,8 +1379,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1btc: utxo_cohort::Vecs::forced_import( _1btc: utxo_cohort::Vecs::forced_import(
@@ -1391,8 +1391,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10btc: utxo_cohort::Vecs::forced_import( _10btc: utxo_cohort::Vecs::forced_import(
@@ -1403,8 +1403,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_100btc: utxo_cohort::Vecs::forced_import( _100btc: utxo_cohort::Vecs::forced_import(
@@ -1415,8 +1415,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_1k_btc: utxo_cohort::Vecs::forced_import( _1k_btc: utxo_cohort::Vecs::forced_import(
@@ -1427,8 +1427,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
_10k_btc: utxo_cohort::Vecs::forced_import( _10k_btc: utxo_cohort::Vecs::forced_import(
@@ -1439,8 +1439,8 @@ impl Vecs {
indexes, indexes,
price, price,
None, None,
true,
false, false,
true,
false, false,
)?, )?,
}, },
@@ -1644,7 +1644,13 @@ impl Vecs {
let by_size_range = self.0.amount_range.as_vec(); let by_size_range = self.0.amount_range.as_vec();
[ [
vec![(&mut self.0.all.1, self.0.epoch.vecs().to_vec())], vec![(
&mut self.0.all.1,
by_date_range
.into_iter()
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)],
self.0 self.0
.min_age .min_age
.as_mut_vec() .as_mut_vec()
+9 -9
View File
@@ -36,20 +36,20 @@ pub struct Indexer {
impl Indexer { impl Indexer {
pub fn forced_import(outputs_dir: &Path) -> Result<Self> { pub fn forced_import(outputs_dir: &Path) -> Result<Self> {
info!("Importing indexer...");
let db = Database::open(&outputs_dir.join("indexed/vecs"))?; let db = Database::open(&outputs_dir.join("indexed/vecs"))?;
db.set_min_len(PAGE_SIZE * 50_000_000)?;
info!("Opened database");
let vecs = Vecs::forced_import(&db, VERSION + Version::ZERO)?; let vecs = Vecs::forced_import(&db, VERSION + Version::ZERO)?;
info!("Imported vecs");
db.set_min_len(PAGE_SIZE * 50_000_000)?; let stores =
Stores::forced_import(&outputs_dir.join("indexed/stores"), VERSION + Version::ZERO)?;
info!("Imported stores");
Ok(Self { Ok(Self { vecs, stores, db })
vecs,
stores: Stores::forced_import(
&outputs_dir.join("indexed/stores"),
VERSION + Version::ZERO,
)?,
db,
})
} }
pub fn index( pub fn index(
+1 -1
View File
@@ -17,7 +17,7 @@ vecdb = {workspace = true}
byteview = { workspace = true } byteview = { workspace = true }
derive_deref = { workspace = true } derive_deref = { workspace = true }
jiff = { workspace = true } jiff = { workspace = true }
rapidhash = "3.1.0" rapidhash = "4.0.0"
serde = { workspace = true } serde = { workspace = true }
serde_bytes = { workspace = true } serde_bytes = { workspace = true }
zerocopy = { workspace = true } zerocopy = { workspace = true }
+10 -1
View File
@@ -1,4 +1,7 @@
use std::ops::{Add, AddAssign, Div}; use std::{
iter::Sum,
ops::{Add, AddAssign, Div},
};
use derive_deref::{Deref, DerefMut}; use derive_deref::{Deref, DerefMut};
use serde::{Serialize, Serializer, ser::SerializeTuple}; use serde::{Serialize, Serializer, ser::SerializeTuple};
@@ -566,6 +569,12 @@ where
} }
} }
impl Sum for Close<Dollars> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
Self(Dollars::from(iter.map(|v| f64::from(v.0)).sum::<f64>()))
}
}
// impl<T> Mul<usize> for Close<T> // impl<T> Mul<usize> for Close<T>
// where // where
// T: Mul<usize, Output = T>, // T: Mul<usize, Output = T>,
+1 -1
View File
@@ -141,7 +141,7 @@ impl Mul<StoredF64> for Sats {
impl Sum for Sats { impl Sum for Sats {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sats: u64 = iter.map(|sats| sats.0).sum(); let sats: u64 = iter.map(|sats| sats.0).sum();
Sats::from(sats) Self::from(sats)
} }
} }
@@ -2,6 +2,7 @@ use core::panic;
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
f32, f32,
iter::Sum,
ops::{Add, AddAssign, Div, Mul, Sub}, ops::{Add, AddAssign, Div, Mul, Sub},
}; };
@@ -178,3 +179,9 @@ impl Printable for StoredF32 {
&["f32"] &["f32"]
} }
} }
impl Sum for StoredF32 {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
Self(iter.map(|v| v.0).sum::<f32>())
}
}

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 511 B

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 594 B

Before

Width:  |  Height:  |  Size: 562 B

After

Width:  |  Height:  |  Size: 562 B

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="description" content="Bitcoin with X-ray vision" /> <meta name="description" content="Bitcoin transparency, amplified" />
<meta <meta
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
@@ -215,7 +215,7 @@
--light-gray: oklch(90% 0.01 44); --light-gray: oklch(90% 0.01 44);
--gray: oklch(60% 0.01 44); --gray: oklch(60% 0.01 44);
--dark-gray: oklch(30% 0.01 44); --dark-gray: oklch(30% 0.01 44);
--black: oklch(17.5% 0.005 44); --black: oklch(15% 0.005 44);
--red: oklch(0.607 0.241 26.328); --red: oklch(0.607 0.241 26.328);
--orange: oklch(67.64% 0.191 44.41); --orange: oklch(67.64% 0.191 44.41);
--amber: oklch(0.7175 0.1835 64.199); --amber: oklch(0.7175 0.1835 64.199);
@@ -285,6 +285,15 @@
font-style: normal; font-style: normal;
} }
/*@font-face {
font-family: "Lilex";
src: url("./assets/fonts/Lilex-Italic[wght]-2.601.woff2")
format("woff2");
font-weight: 100 900;
font-display: block;
font-style: normal;
}*/
/* /*
* --- * ---
*/ */
@@ -438,9 +447,9 @@
h1, h1,
h2 { h2 {
text-transform: uppercase; text-transform: uppercase;
font-size: var(--font-size-lg); font-size: var(--font-size-xl);
line-height: var(--line-height-lg); line-height: var(--line-height-xl);
font-weight: 375; font-weight: 350;
} }
h3 { h3 {
@@ -547,6 +556,10 @@
&:has(input:checked) { &:has(input:checked) {
color: var(--color); color: var(--color);
} }
[data-screenshot="true"] &:has(input:not(:checked)) {
display: none;
}
} }
main { main {
@@ -962,7 +975,6 @@
flex-shrink: 0; flex-shrink: 0;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 1.5rem;
margin: -0.5rem var(--negative-main-padding); margin: -0.5rem var(--negative-main-padding);
padding: 0.75rem var(--main-padding); padding: 0.75rem var(--main-padding);
overflow-x: auto; overflow-x: auto;
@@ -980,13 +992,33 @@
margin-top: 2rem; margin-top: 2rem;
margin-bottom: 1rem; margin-bottom: 1rem;
button#screenshot {
width: 100%;
text-align: left;
padding-left: 1rem;
height: 100%;
font-size: var(--font-size-sm);
line-height: var(--line-height-sm);
[data-screenshot="true"] & {
display: none;
}
}
> legend { > legend {
gap: 1.5rem;
&:empty { &:empty {
display: none; display: none;
} }
> div { > div {
[data-screenshot="true"] &:has(input:not(:checked)) {
display: none;
}
flex: 0; flex: 0;
height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -1024,6 +1056,11 @@
padding-right: 0.375rem; padding-right: 0.375rem;
margin-left: -0.375rem; margin-left: -0.375rem;
margin-right: -0.375rem; margin-right: -0.375rem;
[data-screenshot="true"] & {
width: 0;
opacity: 0;
}
} }
} }
} }
@@ -1109,6 +1146,16 @@
width: 100%; width: 100%;
min-height: 0; min-height: 0;
padding: var(--main-padding); padding: var(--main-padding);
background-color: var(--background-color);
p#domain {
position: absolute;
left: 2rem;
top: 0.75rem;
color: var(--gray);
font-size: var(--font-size-sm);
line-height: var(--line-height-sm);
}
header { header {
flex-shrink: 0; flex-shrink: 0;
@@ -1117,7 +1164,7 @@
white-space: nowrap; white-space: nowrap;
overflow-x: auto; overflow-x: auto;
padding-bottom: 1rem; padding-bottom: 1rem;
margin-bottom: -2rem; margin-bottom: -1.5rem;
padding-left: var(--main-padding); padding-left: var(--main-padding);
margin-left: var(--negative-main-padding); margin-left: var(--negative-main-padding);
padding-right: var(--main-padding); padding-right: var(--main-padding);
@@ -1132,6 +1179,17 @@
flex: 1; flex: 1;
} }
#interval {
> span {
display: none;
[data-screenshot="true"] & {
color: var(--gray);
display: inline-block;
}
}
}
> .chart > legend, > .chart > legend,
> fieldset { > fieldset {
z-index: 20; z-index: 20;
@@ -1687,7 +1745,9 @@
<div class="shadow-bottom"></div> <div class="shadow-bottom"></div>
<div id="resize-bar"></div> <div id="resize-bar"></div>
<nav id="nav" hidden></nav> <nav id="nav" hidden>
<!-- <h4>bitview</h4> -->
</nav>
<search id="search" hidden> <search id="search" hidden>
<header> <header>
@@ -1,7 +1,7 @@
{ {
"name": "Bitcoin Research Kit", "name": "bitview",
"short_name": "₿RK", "short_name": "bitview",
"description": "A better, FOSS, Bitcoin-only, self-hostable Glassnode", "description": "Bitcoin transparency, amplified",
"categories": [ "categories": [
"bitcoin", "bitcoin",
"on-chain", "on-chain",
@@ -1,7 +1,7 @@
LICENSE LICENSE
*.json *.json
*webcomponent* *webcomponent*
README.md README*.md
cli* cli*
extras/ extras/
*.cjs *.cjs
@@ -9,3 +9,7 @@ dev.js
*.development* *.development*
*.iife.* *.iife.*
nano.* nano.*
worker.*
*.ts
*.mts
*.cts
@@ -4,7 +4,7 @@
* *
* uFuzzy.js (μFuzzy) * uFuzzy.js (μFuzzy)
* A tiny, efficient fuzzy matcher that doesn't suck * A tiny, efficient fuzzy matcher that doesn't suck
* https://github.com/leeoniya/uFuzzy (v1.0.18) * https://github.com/leeoniya/uFuzzy (v1.0.19)
*/ */
const cmp = (a, b) => a > b ? 1 : a < b ? -1 : 0; const cmp = (a, b) => a > b ? 1 : a < b ? -1 : 0;
@@ -925,40 +925,50 @@ function uFuzzy(opts) {
const latinize = (() => { const latinize = (() => {
let accents = { let accents = {
A: 'ÁÀÃÂÄĄ', A: 'ÁÀÃÂÄĄĂÅ',
a: 'áàãâäą', a: 'áàãâäąăå',
E: 'ÉÈÊËĖ', E: 'ÉÈÊËĖĚ',
e: 'éèêëę', e: 'éèêëęě',
I: 'ÍÌÎÏĮ', I: 'ÍÌÎÏĮİ',
i: 'íìîïį', i: 'íìîïįı',
O: 'ÓÒÔÕÖ', O: 'ÓÒÔÕÖ',
o: 'óòôõö', o: 'óòôõö',
U: 'ÚÙÛÜŪŲ', U: 'ÚÙÛÜŪŲŮŰ',
u: 'úùûüūų', u: 'úùûüūųůű',
C: 'ÇČĆ', C: 'ÇČĆ',
c: 'çčć', c: 'çčć',
D: 'Ď',
d: 'ď',
G: 'Ğ',
g: 'ğ',
L: 'Ł', L: 'Ł',
l: 'ł', l: 'ł',
N: 'ÑŃ', N: 'ÑŃŇ',
n: 'ñń', n: 'ñńň',
S: 'ŠŚ', S: 'ŠŚȘŞ',
s: 'šś', s: 'šśșş',
Z: 'ŻŹ', T: 'ŢȚŤ',
z: 'żź' t: 'ţțť',
Y: 'Ý',
y: 'ý',
Z: 'ŻŹŽ',
z: 'żźž'
}; };
let accentsMap = new Map(); // str.normalize("NFD").replace(/\p{Diacritic}/gu, "")
let accentsMap = {};
let accentsTpl = ''; let accentsTpl = '';
for (let r in accents) { for (let r in accents) {
accents[r].split('').forEach(a => { accents[r].split('').forEach(a => {
accentsTpl += a; accentsTpl += a;
accentsMap.set(a, r); accentsMap[a] = r;
}); });
} }
let accentsRe = new RegExp(`[${accentsTpl}]`, 'g'); let accentsRe = new RegExp(`[${accentsTpl}]`, 'g');
let replacer = m => accentsMap.get(m); let replacer = m => accentsMap[m];
return strings => { return strings => {
if (typeof strings == 'string') if (typeof strings == 'string')
@@ -50,6 +50,8 @@ import {
const oklchToRGBA = createOklchToRGBA(); const oklchToRGBA = createOklchToRGBA();
const lineWidth = /** @type {any} */ (1.5);
/** /**
* @param {Object} args * @param {Object} args
* @param {string} args.id * @param {string} args.id
@@ -436,9 +438,9 @@ function createChartElement({
value: v, value: v,
}; };
} else { } else {
if (sameTime) { // if (sameTime) {
console.log(data[offsetedI]); // console.log(data[offsetedI]);
} // }
let [open, high, low, close] = v; let [open, high, low, close] = v;
data[offsetedI] = { data[offsetedI] = {
time, time,
@@ -690,7 +692,7 @@ function createChartElement({
ichart.addSeries( ichart.addSeries(
/** @type {SeriesDefinition<'Line'>} */ (LineSeries), /** @type {SeriesDefinition<'Line'>} */ (LineSeries),
{ {
lineWidth: /** @type {any} */ (1.5), lineWidth,
visible: defaultActive !== false, visible: defaultActive !== false,
priceLineVisible: false, priceLineVisible: false,
color: color(), color: color(),
@@ -744,7 +746,7 @@ function createChartElement({
ichart.addSeries( ichart.addSeries(
/** @type {SeriesDefinition<'Baseline'>} */ (BaselineSeries), /** @type {SeriesDefinition<'Baseline'>} */ (BaselineSeries),
{ {
lineWidth: /** @type {any} */ (1.5), lineWidth,
visible: defaultActive !== false, visible: defaultActive !== false,
baseValue: { baseValue: {
price: options?.baseValue?.price ?? 0, price: options?.baseValue?.price ?? 0,
@@ -0,0 +1 @@
*.js
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,13 @@
import { domToBlob } from "./4.6.6/dist/index.mjs";
/**
* @param {Element} element
*/
export async function screenshot(element) {
const blob = await domToBlob(element, {
scale: 2,
});
const url = URL.createObjectURL(blob);
window.open(url, "_blank");
setTimeout(() => URL.revokeObjectURL(url), 100);
}
@@ -386,10 +386,10 @@ main() {
# Check if the directory already exists and has content # Check if the directory already exists and has content
if [[ -d "$output_dir" ]] && [[ -n "$(ls -A "$output_dir" 2>/dev/null)" ]]; then if [[ -d "$output_dir" ]] && [[ -n "$(ls -A "$output_dir" 2>/dev/null)" ]]; then
print_error "Directory already exists and is not empty: $output_dir" print_warning "Directory already exists and is not empty: $output_dir"
print_error "Package $package_name@$resolved_version appears to already be downloaded." print_warning "Package $package_name@$resolved_version appears to already be downloaded."
print_error "Remove the directory or choose a different output location to proceed." print_warning "Remove the directory or choose a different output location to proceed."
exit 1 return
fi fi
# Create the base output directory # Create the base output directory
@@ -409,3 +409,4 @@ main "@solidjs/signals"
main "@leeoniya/ufuzzy" main "@leeoniya/ufuzzy"
main "lean-qr" main "lean-qr"
main "lightweight-charts" main "lightweight-charts"
main "modern-screenshot"
@@ -21,6 +21,7 @@ const CANDLE = "candle";
* @param {Elements} args.elements * @param {Elements} args.elements
* @param {VecsResources} args.vecsResources * @param {VecsResources} args.vecsResources
* @param {VecIdToIndexes} args.vecIdToIndexes * @param {VecIdToIndexes} args.vecIdToIndexes
* @param {Packages} args.packages
*/ */
export function init({ export function init({
colors, colors,
@@ -32,6 +33,7 @@ export function init({
webSockets, webSockets,
vecsResources, vecsResources,
vecIdToIndexes, vecIdToIndexes,
packages,
}) { }) {
elements.charts.append(utils.dom.createShadow("left")); elements.charts.append(utils.dom.createShadow("left"));
elements.charts.append(utils.dom.createShadow("right")); elements.charts.append(utils.dom.createShadow("right"));
@@ -95,6 +97,35 @@ export function init({
}, },
}); });
const chartBottomRightCanvas = Array.from(
chart.inner.chartElement().getElementsByTagName("tr"),
).at(-1)?.lastChild?.firstChild?.firstChild;
if (chartBottomRightCanvas) {
const charts = elements.charts;
const domain = window.document.createElement("p");
domain.innerText = `${window.location.host}`;
domain.id = "domain";
const screenshotButton = window.document.createElement("button");
screenshotButton.id = "screenshot";
const camera = "[ ◉¯]";
screenshotButton.innerHTML = camera;
screenshotButton.title = "Screenshot";
chartBottomRightCanvas.replaceWith(screenshotButton);
screenshotButton.addEventListener("click", () => {
packages.modernScreenshot().then(async ({ screenshot }) => {
charts.dataset.screenshot = "true";
charts.append(domain);
seriesTypeField.hidden = true;
try {
await screenshot(charts);
} catch {}
charts.removeChild(domain);
seriesTypeField.hidden = false;
charts.dataset.screenshot = "false";
});
});
}
chart.inner.timeScale().subscribeVisibleLogicalRangeChange( chart.inner.timeScale().subscribeVisibleLogicalRangeChange(
utils.debounce((t) => { utils.debounce((t) => {
if (t) { if (t) {
@@ -500,6 +531,7 @@ function createIndexSelector({ option, vecIdToIndexes, signals, utils }) {
const rawIndexes = new Set( const rawIndexes = new Set(
[Object.values(o.top), Object.values(o.bottom)] [Object.values(o.top), Object.values(o.bottom)]
.flat(2) .flat(2)
.filter((blueprint) => !blueprint.key.startsWith("constant_"))
.map((blueprint) => vecIdToIndexes[blueprint.key]) .map((blueprint) => vecIdToIndexes[blueprint.key])
.flat(), .flat(),
); );
@@ -524,6 +556,12 @@ function createIndexSelector({ option, vecIdToIndexes, signals, utils }) {
}); });
const fieldset = window.document.createElement("fieldset"); const fieldset = window.document.createElement("fieldset");
fieldset.id = "interval";
const screenshotSpan = window.document.createElement("span");
screenshotSpan.innerText = "interval:";
fieldset.append(screenshotSpan);
fieldset.append(field); fieldset.append(field);
fieldset.dataset.size = "sm"; fieldset.dataset.size = "sm";
@@ -3,7 +3,7 @@
/** /**
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType } from "./options" * @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType } from "./options"
* @import { Valued, SingleValueData, CandlestickData, OHLCTuple, Series, ISeries, HistogramData, LineData, BaselineData, LineSeriesPartialOptions, BaselineSeriesPartialOptions, HistogramSeriesPartialOptions, CandlestickSeriesPartialOptions } from "../packages/lightweight-charts/wrapper" * @import { Valued, SingleValueData, CandlestickData, OHLCTuple, Series, ISeries, HistogramData, LineData, BaselineData, LineSeriesPartialOptions, BaselineSeriesPartialOptions, HistogramSeriesPartialOptions, CandlestickSeriesPartialOptions } from "../packages/lightweight-charts/wrapper"
* @import * as _ from "../packages/leeoniya-ufuzzy/1.0.18/dist/uFuzzy.d.ts" * @import * as _ from "../packages/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.d.ts"
* @import { SerializedChartableIndex } from "./chart"; * @import { SerializedChartableIndex } from "./chart";
* @import { Signal, Signals, Accessor } from "../packages/solidjs-signals/wrapper"; * @import { Signal, Signals, Accessor } from "../packages/solidjs-signals/wrapper";
* @import { DateIndex, DecadeIndex, DifficultyEpoch, Index, HalvingEpoch, Height, MonthIndex, P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2MSOutputIndex, P2AAddressIndex, P2TRAddressIndex, P2WPKHAddressIndex, P2WSHAddressIndex, TxIndex, InputIndex, OutputIndex, VecId, WeekIndex, SemesterIndex, YearIndex, VecIdToIndexes, QuarterIndex, EmptyOutputIndex, OpReturnIndex, UnknownOutputIndex } from "./vecid-to-indexes" * @import { DateIndex, DecadeIndex, DifficultyEpoch, Index, HalvingEpoch, Height, MonthIndex, P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2MSOutputIndex, P2AAddressIndex, P2TRAddressIndex, P2WPKHAddressIndex, P2WSHAddressIndex, TxIndex, InputIndex, OutputIndex, VecId, WeekIndex, SemesterIndex, YearIndex, VecIdToIndexes, QuarterIndex, EmptyOutputIndex, OpReturnIndex, UnknownOutputIndex } from "./vecid-to-indexes"
@@ -24,11 +24,10 @@
* "Gigabytes" | * "Gigabytes" |
* "Hash" | * "Hash" |
* "Index" | * "Index" |
* "mb" |
* "percentage" | * "percentage" |
* "Ratio" | * "Ratio" |
* "Sats" | * "Sats" |
* "Seconds" | * "secs" |
* "Timestamp" | * "Timestamp" |
* "tx" | * "tx" |
* "Type" | * "Type" |
@@ -78,10 +77,13 @@ function initPackages() {
return import("../packages/lean-qr/2.5.0/index.mjs").then((d) => d); return import("../packages/lean-qr/2.5.0/index.mjs").then((d) => d);
}, },
async ufuzzy() { async ufuzzy() {
return import("../packages/leeoniya-ufuzzy/1.0.18/dist/uFuzzy.mjs").then( return import("../packages/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.mjs").then(
({ default: d }) => d, ({ default: d }) => d,
); );
}, },
async modernScreenshot() {
return import("../packages/modern-screenshot/wrapper.js").then((d) => d);
},
}; };
/** /**
@@ -106,6 +108,7 @@ function initPackages() {
lightweightCharts: importPackage("lightweightCharts"), lightweightCharts: importPackage("lightweightCharts"),
leanQr: importPackage("leanQr"), leanQr: importPackage("leanQr"),
ufuzzy: importPackage("ufuzzy"), ufuzzy: importPackage("ufuzzy"),
modernScreenshot: importPackage("modernScreenshot"),
}; };
} }
/** /**
@@ -727,7 +730,7 @@ function createUtils() {
id.endsWith("stack") || id.endsWith("stack") ||
(id.endsWith("value") && !id.includes("realized")) || (id.endsWith("value") && !id.includes("realized")) ||
((id.includes("coinbase") || ((id.includes("coinbase") ||
id.includes("fee") || (id.includes("fee") && !id.includes("feerate")) ||
id.includes("subsidy") || id.includes("subsidy") ||
id.includes("rewards")) && id.includes("rewards")) &&
!( !(
@@ -762,7 +765,7 @@ function createUtils() {
((id.includes("realized") || id.includes("true_market_mean")) && ((id.includes("realized") || id.includes("true_market_mean")) &&
!id.includes("ratio") && !id.includes("ratio") &&
!id.includes("relative_to")) || !id.includes("relative_to")) ||
((id.endsWith("sma") || id.includes("sma_x")) && ((id.endsWith("sma") || id.includes("sma_x") || id.endsWith("ema")) &&
!id.includes("ratio")) || !id.includes("ratio")) ||
id === "ath") id === "ath")
) { ) {
@@ -777,7 +780,9 @@ function createUtils() {
((!unit || thoroughUnitCheck) && ((!unit || thoroughUnitCheck) &&
(id.endsWith("ratio") || (id.endsWith("ratio") ||
(id.includes("ratio") && (id.includes("ratio") &&
(id.endsWith("sma") || id.endsWith("zscore"))) || (id.endsWith("sma") ||
id.endsWith("ema") ||
id.endsWith("zscore"))) ||
id.endsWith("_5sd") || id.endsWith("_5sd") ||
id.endsWith("1sd") || id.endsWith("1sd") ||
id.endsWith("2sd") || id.endsWith("2sd") ||
@@ -806,11 +811,15 @@ function createUtils() {
(id.endsWith("count") || (id.endsWith("count") ||
id.includes("_count_") || id.includes("_count_") ||
id.startsWith("block_count") || id.startsWith("block_count") ||
id.includes("tx_v")) (id.includes("tx_v") && !id.includes("vsize")))
) { ) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`); if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "Count"; unit = "Count";
} }
if ((!unit || thoroughUnitCheck) && id.includes("feerate")) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "sat/vB";
}
if ((!unit || thoroughUnitCheck) && id.startsWith("is_")) { if ((!unit || thoroughUnitCheck) && id.startsWith("is_")) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`); if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "Bool"; unit = "Bool";
@@ -824,7 +833,7 @@ function createUtils() {
(id === "interval" || id.startsWith("block_interval")) (id === "interval" || id.startsWith("block_interval"))
) { ) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`); if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "Seconds"; unit = "secs";
} }
if ((!unit || thoroughUnitCheck) && id.endsWith("returns")) { if ((!unit || thoroughUnitCheck) && id.endsWith("returns")) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`); if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
@@ -844,7 +853,11 @@ function createUtils() {
} }
if ( if (
(!unit || thoroughUnitCheck) && (!unit || thoroughUnitCheck) &&
(id === "txid" || (id.endsWith("bytes") && !id.endsWith("vbytes"))) (id === "txid" ||
(id.endsWith("bytes") && !id.endsWith("vbytes")) ||
id.endsWith("base_size") ||
id.endsWith("total_size") ||
id.includes("block_size"))
) { ) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`); if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "Bytes"; unit = "Bytes";
@@ -855,19 +868,7 @@ function createUtils() {
} }
if ( if (
(!unit || thoroughUnitCheck) && (!unit || thoroughUnitCheck) &&
(id.endsWith("_size") || (id.includes("vsize") || id.includes("vbytes"))
id.endsWith("_size_sum") ||
id.endsWith("_size_cumulative"))
) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "mb";
}
if (
(!unit || thoroughUnitCheck) &&
(id.endsWith("vsize") ||
id.endsWith("vbytes") ||
id.endsWith("_vbytes_sum") ||
id.endsWith("_vbytes_cumulative"))
) { ) {
if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`); if (unit) throw Error(`Unit "${unit}" already assigned "${id}"`);
unit = "vB"; unit = "vB";
@@ -2279,6 +2280,7 @@ function main() {
webSockets, webSockets,
vecsResources, vecsResources,
vecIdToIndexes, vecIdToIndexes,
packages,
}), }),
), ),
), ),
@@ -2402,9 +2404,7 @@ function main() {
return treeElement; return treeElement;
}); });
if (localhost) { setTimeout(scrollToSelected, 10);
setTimeout(scrollToSelected, 10);
}
}); });
} }
initFolders(); initFolders();
File diff suppressed because it is too large Load Diff
@@ -770,7 +770,7 @@ export function init({
data: bitcoinPriceData, data: bitcoinPriceData,
}, },
{ {
title: "Average Price Paid", title: "Average Cost Basis",
type: "Line", type: "Line",
color: colors.lime, color: colors.lime,
data: averagePricePaidData, data: averagePricePaidData,

Some files were not shown because too many files have changed in this diff Show More