bindex: back to sanakirja

This commit is contained in:
nym21
2025-01-14 23:35:42 +01:00
parent d373c6398e
commit 4cc57e9c91
25 changed files with 1245 additions and 727 deletions
Generated
+463 -240
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
allocative = "0.3.3"
allocative = "0.3.4"
axum = "0.7.9"
bincode = { git = "https://github.com/bincode-org/bincode.git", features = [
"serde",
@@ -14,26 +14,26 @@ bincode = { git = "https://github.com/bincode-org/bincode.git", features = [
bitcoin_hashes = { version = "0.15.0" }
biter = { path = "./src/crates/biter" }
chrono = { version = "0.4.39", features = ["serde"] }
clap = { version = "4.5.23", features = ["derive"] }
clap = { version = "4.5.26", features = ["derive"] }
color-eyre = "0.6.3"
ctrlc = { version = "3.4.5", features = ["termination"] }
derive_deref = "1.1.1"
env_logger = "0.11.5"
inferno = "0.12.0"
env_logger = "0.11.6"
inferno = "0.12.1"
itertools = "0.13.0"
log = { version = "0.4.22", features = ["std", "serde"] }
ordered-float = "4.5.0"
log = { version = "0.4.25", features = ["std", "serde"] }
ordered-float = "4.6.0"
rayon = "1.10.0"
regex = "1.11.1"
reqwest = { version = "0.12.9", features = ["blocking", "json"] }
reqwest = { version = "0.12.12", features = ["blocking", "json"] }
rlimit = "0.10.2"
snkrj = { path = "./src/crates/snkrj" }
serde = { version = "1.0.216", features = ["derive"] }
serde_json = "1.0.133"
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.135"
struct_iterable = { path = "./src/crates/iterable" }
swc = "9.0.0"
swc = "9.0.2"
swc_common = "5.0.0"
tokio = { version = "1.42.0", features = ["full"] }
tokio = { version = "1.43.0", features = ["full"] }
toml = "0.8.19"
tower-http = { version = "0.6.2", features = ["compression-full"] }
zstd = "0.13.2"
+277 -140
View File
@@ -17,6 +17,25 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "arrayvec"
version = "0.7.6"
@@ -67,17 +86,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d"
[[package]]
name = "bitbase"
name = "bindex"
version = "0.1.0"
dependencies = [
"bitcoin_hashes 0.16.0",
"biter",
"canopydb",
"color-eyre",
"ctrlc",
"derive_deref",
"fjall",
"memmap2",
"rayon",
"snkrj",
]
[[package]]
@@ -198,6 +218,12 @@ dependencies = [
"serde_json",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
@@ -210,6 +236,37 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "canopydb"
version = "0.1.0"
source = "git+https://github.com/arthurprs/canopydb#daab91758a7905abc2a7d1a9c7e9f6c41227e72b"
dependencies = [
"bitflags 2.6.0",
"dashmap",
"derive_more",
"fail",
"foldhash",
"fslock",
"hashbrown",
"libc",
"lock_api",
"log",
"lz4_flex",
"memmap2",
"nix",
"parking_lot 0.12.3",
"quick_cache",
"rand",
"serde",
"serde_json",
"smallvec 2.0.0-alpha.9",
"sptr",
"tempfile",
"triomphe",
"xxhash-rust",
"zerocopy",
]
[[package]]
name = "cc"
version = "1.2.4"
@@ -308,16 +365,6 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-skiplist"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
@@ -345,7 +392,7 @@ dependencies = [
"hashbrown",
"lock_api",
"once_cell",
"parking_lot_core",
"parking_lot_core 0.9.10",
]
[[package]]
@@ -359,6 +406,27 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "derive_more"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.95",
"unicode-xid",
]
[[package]]
name = "derived-deref"
version = "2.1.0"
@@ -370,30 +438,12 @@ dependencies = [
"syn 2.0.95",
]
[[package]]
name = "double-ended-peekable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0d05e1c0dbad51b52c38bda7adceef61b9efc2baf04acfe8726a8c4630a6f57"
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "enum_dispatch"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd"
dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.95",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -420,6 +470,17 @@ dependencies = [
"once_cell",
]
[[package]]
name = "fail"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe5e43d0f78a42ad591453aedb1d7ae631ce7ee445c7643691055a9ed8d3b01c"
dependencies = [
"log",
"once_cell",
"rand",
]
[[package]]
name = "fastrand"
version = "2.3.0"
@@ -427,19 +488,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fjall"
version = "2.5.0"
name = "foldhash"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80910a26e4fb5e5393ff64d293602ac1ade56cf4d14d244c02a7d4ddcd5f10bc"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"byteorder",
"dashmap",
"log",
"lsm-tree",
"path-absolutize",
"std-semaphore",
"tempfile",
"xxhash-rust",
"libc",
"winapi",
]
[[package]]
name = "fslock"
version = "0.2.1"
source = "git+https://github.com/arthurprs/fslock.git?rev=7ec91154136a2b3d567b1f79e87cae5d3ca3d927#7ec91154136a2b3d567b1f79e87cae5d3ca3d927"
dependencies = [
"libc",
"winapi",
]
[[package]]
@@ -459,17 +529,15 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "guardian"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "493913a18c0d7bebb75127a26a432162c59edbe06f6cf712001e3e769345e8b5"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "hex-conservative"
@@ -501,6 +569,15 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
]
[[package]]
name = "itoa"
version = "1.0.14"
@@ -533,9 +610,9 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "lock_api"
@@ -553,29 +630,6 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "lsm-tree"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d858efa63a32a286a06aa3968f3ed09811d556697e9f9804aa72ea679ed3b83"
dependencies = [
"byteorder",
"crossbeam-skiplist",
"double-ended-peekable",
"enum_dispatch",
"guardian",
"log",
"lz4_flex",
"path-absolutize",
"quick_cache",
"rustc-hash",
"self_cell",
"tempfile",
"value-log",
"varint-rs",
"xxhash-rust",
]
[[package]]
name = "lz4_flex"
version = "0.11.3"
@@ -597,12 +651,6 @@ dependencies = [
"libc",
]
[[package]]
name = "min-max-heap"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2687e6cf9c00f48e9284cf9fd15f2ef341d03cc7743abf9df4c5f07fdee50b18"
[[package]]
name = "miniz_oxide"
version = "0.7.4"
@@ -629,7 +677,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags",
"bitflags 2.6.0",
"cfg-if",
"cfg_aliases",
"libc",
@@ -656,6 +704,41 @@ version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.6",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core 0.9.10",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall 0.2.16",
"smallvec 1.13.2",
"winapi",
]
[[package]]
name = "parking_lot_core"
version = "0.9.10"
@@ -664,29 +747,11 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"redox_syscall 0.5.8",
"smallvec 1.13.2",
"windows-targets",
]
[[package]]
name = "path-absolutize"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4af381fe79fa195b4909485d99f73a80792331df0625188e707854f0b3383f5"
dependencies = [
"path-dedot",
]
[[package]]
name = "path-dedot"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397"
dependencies = [
"once_cell",
]
[[package]]
name = "pin-project-lite"
version = "0.2.15"
@@ -717,8 +782,10 @@ version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d7c94f8935a9df96bb6380e8592c70edf497a643f94bd23b2f76b399385dbf4"
dependencies = [
"ahash",
"equivalent",
"hashbrown",
"parking_lot 0.12.3",
]
[[package]]
@@ -780,13 +847,22 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
"bitflags",
"bitflags 2.6.0",
]
[[package]]
@@ -795,19 +871,13 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
[[package]]
name = "rustix"
version = "0.38.42"
version = "0.38.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
dependencies = [
"bitflags",
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
@@ -820,6 +890,27 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "sanakirja"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81aaf70d064e2122209f04d01fd91e8908e7a327b516236e1cbc0c3f34ac6d11"
dependencies = [
"fs2",
"log",
"memmap2",
"parking_lot 0.11.2",
"sanakirja-core",
"serde",
"thiserror",
]
[[package]]
name = "sanakirja-core"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8376db34ae3eac6e7bd91168bc638450073b708ce9fb46940de676f552238bf5"
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -847,12 +938,6 @@ dependencies = [
"cc",
]
[[package]]
name = "self_cell"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe"
[[package]]
name = "serde"
version = "1.0.216"
@@ -907,10 +992,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "std-semaphore"
version = "0.1.0"
name = "smallvec"
version = "2.0.0-alpha.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ae9eec00137a8eed469fb4148acd9fc6ac8c3f9b110f52cd34698c8b5bfa0e"
checksum = "5e22442b16a0c1bfae679ffed8ec5e160ae2aa8495cea891f0d2ff7b84fe5c4c"
[[package]]
name = "snkrj"
version = "0.1.1"
dependencies = [
"sanakirja",
]
[[package]]
name = "sptr"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a"
[[package]]
name = "syn"
@@ -936,17 +1034,38 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.14.0"
version = "3.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
dependencies = [
"cfg-if",
"fastrand",
"getrandom",
"once_cell",
"rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.95",
]
[[package]]
name = "thread_local"
version = "1.1.8"
@@ -998,12 +1117,24 @@ dependencies = [
"tracing-core",
]
[[package]]
name = "triomphe"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85"
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "valuable"
version = "0.1.0"
@@ -1011,26 +1142,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "value-log"
version = "1.4.1"
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f90495556d09c3026f7f3897f8a7db59c8c701082e32dcf58c2319062ae1eb0"
dependencies = [
"byteorder",
"log",
"min-max-heap",
"path-absolutize",
"quick_cache",
"rustc-hash",
"tempfile",
"xxhash-rust",
]
[[package]]
name = "varint-rs"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f54a172d0620933a27a4360d3db3e2ae0dd6cceae9730751a036bbf182c4b23"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasi"
@@ -1038,6 +1153,28 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.59.0"
+2 -1
View File
@@ -9,6 +9,7 @@ biter = "0.2.2"
color-eyre = "0.6.3"
ctrlc = "3.4.5"
derive_deref = "1.1.1"
fjall = "2.5.0"
memmap2 = "0.9.5"
rayon = "1.10.0"
snkrj = { path = "../snkrj" }
canopydb = { git = "https://github.com/arthurprs/canopydb" }
+75 -97
View File
@@ -14,11 +14,10 @@ use biter::{
mod structs;
use color_eyre::eyre::{eyre, ContextCompat};
use fjall::{PersistMode, Slice, TransactionalKeyspace, WriteTransaction};
use rayon::prelude::*;
use structs::{
Addressbytes, AddressbytesPrefix, Addressindex, Addressindextxoutindex, Addresstype, Addresstypeindex, Amount,
AnyVecdisk, BlockHashPrefix, Exit, Height, Partitions, TxidPrefix, Txindex, Txindexvout, Txoutindex, Vecdisks,
AnyVecdisk, BlockHashPrefix, Databases, Exit, Height, TxidPrefix, Txindex, Txindexvout, Txoutindex, Vecdisks,
};
// https://github.com/fjall-rs/fjall/discussions/72
@@ -30,6 +29,8 @@ enum TxInOrAddressindextoutindex<'a> {
Addressindextoutindex(Addressindextxoutindex),
}
const MONTHLY_BLOCK_TARGET: usize = 144 * 30;
fn main() -> color_eyre::Result<()> {
let i = std::time::Instant::now();
@@ -45,13 +46,9 @@ fn main() -> color_eyre::Result<()> {
let mut vecdisks = Vecdisks::import(path_database)?;
let keyspace = fjall::Config::new(path_database).open_transactional()?;
let databases = Databases::open(path_database)?;
let parts = Partitions::import(&keyspace, &exit)?;
let wtx = keyspace.write_tx();
let mut height = parts.start_height();
let mut height = Height::from(0_u32);
let mut txindex = vecdisks
.height_to_first_txindex
@@ -71,24 +68,17 @@ fn main() -> color_eyre::Result<()> {
.cloned()
.unwrap_or(Addressindex::default());
let export = |keyspace: &TransactionalKeyspace,
mut wtx: WriteTransaction,
parts: &Partitions,
vecdisks: &mut Vecdisks,
height: Height|
-> color_eyre::Result<()> {
parts.udpate_meta(&mut wtx, height);
let export = |databases: Databases, vecdisks: &mut Vecdisks, height: Height| -> color_eyre::Result<()> {
exit.block();
println!("Exporting...");
wtx.commit()?;
keyspace.persist(PersistMode::SyncAll)?;
databases.export();
vecdisks.flush()?;
println!("Export done");
exit.unblock();
Ok(())
};
let mut wtx_opt = Some(wtx);
let mut databases_opt = Some(databases);
biter::new(data_dir, Some(height.into()), Some(400_000), rpc)
.iter()
@@ -97,7 +87,7 @@ fn main() -> color_eyre::Result<()> {
height = Height::from(_height);
let mut wtx = wtx_opt.take().context("option should have wtx")?;
let mut databases = databases_opt.take().context("option should have wtx")?;
// if let Some(saved_blockhash) = vecdisks.height_to_blockhash.get(height)? {
// if &blockhash != saved_blockhash {
@@ -108,22 +98,21 @@ fn main() -> color_eyre::Result<()> {
// }
// }
if parts.blockhash_prefix_to_height.needs(height) {
let blockhash_prefix = BlockHashPrefix::from(&blockhash);
// if parts.blockhash_prefix_to_height.needs(height) {
let blockhash_prefix = BlockHashPrefix::try_from(&blockhash)?;
if check_collisions {
if let Some(prev_height_slice) =
wtx.get(parts.blockhash_prefix_to_height.data(), blockhash_prefix.clone())?
{
dbg!(blockhash, Height::try_from(prev_height_slice)?);
return Err(eyre!("Collision, expect prefix to need be set yet"));
}
if check_collisions {
if let Some(prev_height) =
databases.blockhash_prefix_to_height.get(&blockhash_prefix)
{
dbg!(blockhash, prev_height);
return Err(eyre!("Collision, expect prefix to need be set yet"));
}
wtx.insert(parts.blockhash_prefix_to_height.data(), blockhash_prefix.clone(),Slice::from(height));
}
databases.blockhash_prefix_to_height.insert(blockhash_prefix,height);
// }
vecdisks.height_to_blockhash.push_if_needed(height, blockhash)?;
vecdisks.height_to_first_txindex.push_if_needed(height, txindex)?;
vecdisks.height_to_first_txoutindex.push_if_needed(height, txoutindex)?;
@@ -152,14 +141,16 @@ fn main() -> color_eyre::Result<()> {
.map(|(index, tx)| -> color_eyre::Result<_> {
let txid = tx.compute_txid();
let txid_prefix = TxidPrefix::try_from(&txid)?;
let prev_txindex_slice_opt = if check_collisions {
// Should only find collisions for two txids (duplicates), see below
wtx.get(parts.txid_prefix_to_txindex.data(), TxidPrefix::from(&txid).clone())?.map(Txindex::try_from)
databases.txid_prefix_to_txindex.get(&txid_prefix).cloned()
} else {
None
};
Ok((TxidPrefix::from(&txid), (txid, Txindex::from(index), prev_txindex_slice_opt)))
Ok((txid_prefix, (txid, Txindex::from(index), prev_txindex_slice_opt)))
})
.try_fold(
BTreeMap::new,
@@ -190,26 +181,24 @@ fn main() -> color_eyre::Result<()> {
let txid = outpoint.txid;
let vout = outpoint.vout;
let txindex_local = if let Some(txindex_local) = wtx
.get(parts.txid_prefix_to_txindex.data(), TxidPrefix::from(&txid).clone())?
.map(Txindex::try_from)
let txindex_local = if let Some(txindex_local) = databases.txid_prefix_to_txindex
.get(&TxidPrefix::try_from(&txid)?)
{
txindex_local
*txindex_local
} else {
return Ok(TxInOrAddressindextoutindex::TxIn(txin));
}?;
};
let txindexvout = Txindexvout::from((txindex_local, vout));
let txoutindex = Txoutindex::try_from(
wtx.get(parts.txindexvout_to_txoutindex.data(), Slice::from(txindexvout))?
let txoutindex =
*databases.txindexvout_to_txoutindex.get(&txindexvout)
.context("Expect txoutindex to not be none")
.inspect_err(|_| {
// let height = vecdisks.txindex_to_height.get(txindex.into()).expect("txindex_to_height get not fail")
// .expect("Expect height for txindex");
dbg!(outpoint.txid, txindex_local, vout, txindexvout);
})?,
)?;
})?;
let addressindex = *vecdisks.txoutindex_to_addressindex.get(txoutindex)?
.context("Expect addressindex to not be none")
@@ -229,9 +218,10 @@ fn main() -> color_eyre::Result<()> {
|mut vec, addressindextxoutindex| {
// There is no need to check for bad_tx as there are only 2 instances known
// Which you can find below and which are coinbase tx and thus which are already filtered
if parts.addressindextxoutindex_out.needs(height) {
// if parts.addressindextxoutindex_out.needs(height) {
vec.push(addressindextxoutindex?);
}
// }
Ok(vec)
},
@@ -248,7 +238,7 @@ fn main() -> color_eyre::Result<()> {
});
let txoutindex_to_txout_addresstype_addressbytes_res_addressindex_opt_handle = scope.spawn(|| -> color_eyre::Result<BTreeMap<Txoutindex,
(&TxOut, Txindexvout, Addresstype, color_eyre::Result<Addressbytes>, Option<Slice>)>> {
(&TxOut, Txindexvout, Addresstype, color_eyre::Result<Addressbytes>, Option<Addressindex>)>> {
outputs.into_par_iter().enumerate()
.map(
|(block_txoutindex, (block_txindex, vout, txout))| {
@@ -265,24 +255,18 @@ fn main() -> color_eyre::Result<()> {
});
let addressindex_slice_opt = addressbytes_res.as_ref().ok().and_then(|addressbytes| {
let prefix = AddressbytesPrefix::from(addressbytes);
wtx.get(
parts.addressbytes_prefix_to_addressindex.data(),
prefix.clone(),
)
.ok()
.and_then(|s| s)
databases.addressbytes_prefix_to_addressindex.get(
&AddressbytesPrefix::try_from(addressbytes).unwrap(),
).cloned()
});
let is_new_address = addressindex_slice_opt.is_none();
if check_collisions && is_new_address {
if let Ok(addressbytes) = &addressbytes_res {
let prefix = AddressbytesPrefix::from(addressbytes);
if let Some(prev) = wtx.get(
parts.addressbytes_prefix_to_addressindex.data(),
prefix.clone(),
)? {
if let Some(prev) = databases.addressbytes_prefix_to_addressindex.get(
&AddressbytesPrefix::try_from(addressbytes)?,
) {
dbg!(prev);
return Err(eyre!("addressbytes_prefix_to_addressindex collision, expect none"));
}
@@ -327,16 +311,15 @@ fn main() -> color_eyre::Result<()> {
txoutindex_to_txout_addresstype_addressbytes_res_addressindex_opt
.into_iter()
.try_for_each(|(txoutindex, (txout, txindexvout, addresstype, addressbytes_res, addressindex_slice_opt))| -> color_eyre::Result<()> {
.try_for_each(|(txoutindex, (txout, txindexvout, addresstype, addressbytes_res, addressindex_opt))| -> color_eyre::Result<()> {
let amount = Amount::from(txout.value);
if parts.txindexvout_to_txoutindex.needs(height) {
wtx.insert(
parts.txindexvout_to_txoutindex.data(),
Slice::from(txindexvout),
Slice::from(txoutindex),
// if parts.txindexvout_to_txoutindex.needs(height) {
databases.txindexvout_to_txoutindex.insert(
txindexvout,
txoutindex,
);
}
// }
vecdisks.txoutindex_to_amount.push_if_needed(
txoutindex,
@@ -345,8 +328,8 @@ fn main() -> color_eyre::Result<()> {
let mut addressindex_local = addressindex;
if let Some(addressindex_slice) = addressindex_slice_opt {
addressindex_local = Addressindex::try_from(addressindex_slice)?;
if let Some(addressindex) = addressindex_opt {
addressindex_local = addressindex;
} else {
vecdisks.addressindex_to_addresstype.push_if_needed(addressindex_local, addresstype)?;
@@ -356,13 +339,12 @@ fn main() -> color_eyre::Result<()> {
vecdisks.addressindex_to_addresstypeindex.push_if_needed(addressindex_local, addresstypeindex)?;
if let Ok(addressbytes) = addressbytes_res {
if parts.addressbytes_prefix_to_addressindex.needs(height) {
wtx.insert(
parts.addressbytes_prefix_to_addressindex.data(),
AddressbytesPrefix::from(&addressbytes).clone(),
Slice::from(addressindex_local),
// if parts.addressbytes_prefix_to_addressindex.needs(height) {
databases.addressbytes_prefix_to_addressindex.insert(
AddressbytesPrefix::try_from(&addressbytes)?,
addressindex_local,
);
}
// }
vecdisks.push_addressbytes_if_needed(addresstypeindex, addressbytes)?;
}
@@ -377,19 +359,18 @@ fn main() -> color_eyre::Result<()> {
addressindex_local,
)?;
if parts.addressindextxoutindex_in.needs(height) {
// if parts.addressindextxoutindex_in.needs(height) {
let addressindextxoutindex = Addressindextxoutindex::from((addressindex_local, txoutindex));
wtx.insert(
parts.addressindextxoutindex_in.data(),
Slice::from(addressindextxoutindex),
Slice::from(&[]),
databases.addressindextxoutindex_in.insert(
addressindextxoutindex,
(),
);
}
// }
Ok(())
})?;
if parts.addressindextxoutindex_out.needs(height) {
// if parts.addressindextxoutindex_out.needs(height) {
txin_or_addressindextxoutindex_vec
.into_iter()
.map(|txin_or_addressindextxoutindex| -> color_eyre::Result<Addressindextxoutindex> {
@@ -400,7 +381,7 @@ fn main() -> color_eyre::Result<()> {
let txid = outpoint.txid;
let vout = outpoint.vout;
let index = txid_prefix_to_txid_and_block_txindex_and_prev_txindex
.get(&TxidPrefix::from(&txid))
.get(&TxidPrefix::try_from(&txid)?)
.context("txid should be in same block")?.1;
let txindex_local = txindex + index;
@@ -415,14 +396,13 @@ fn main() -> color_eyre::Result<()> {
}
})
.try_for_each(|addressindextxoutindex| -> color_eyre::Result<()> {
wtx.insert(
parts.addressindextxoutindex_out.data(),
Slice::from(addressindextxoutindex?),
Slice::from(&[]),
databases.addressindextxoutindex_out.insert(
addressindextxoutindex?,
(),
);
Ok(())
})?;
}
// }
drop(new_txindexvout_to_addressindextxoutindex);
@@ -436,13 +416,11 @@ fn main() -> color_eyre::Result<()> {
match prev_txindex_opt {
None => {
if parts.txid_prefix_to_txindex.needs(height) {
wtx.insert(parts.txid_prefix_to_txindex.data(), txid_prefix.clone(), Slice::from(txindex_local));
}
// if parts.txid_prefix_to_txindex.needs(height) {
databases.txid_prefix_to_txindex.insert(txid_prefix, txindex_local);
// }
}
Some(prev_txindex_res) => {
let prev_txindex = prev_txindex_res?;
Some(prev_txindex) => {
// In case if we start at an already parsed height
if txindex_local == prev_txindex {
return Ok(())
@@ -487,12 +465,12 @@ fn main() -> color_eyre::Result<()> {
vecdisks.height_to_last_txoutindex.push_if_needed(height, txoutindex.decremented())?;
vecdisks.height_to_last_addressindex.push_if_needed(height, addressindex.decremented())?;
let should_snapshot = _height % 100 == 0 && !exit.active();
let should_snapshot = _height % MONTHLY_BLOCK_TARGET == 0 && !exit.active();
if should_snapshot {
export(&keyspace, wtx, &parts, &mut vecdisks, height)?;
wtx_opt.replace(keyspace.write_tx());
export(databases, &mut vecdisks, height)?;
databases_opt.replace(Databases::open(path_database)?);
} else {
wtx_opt.replace(wtx);
databases_opt.replace(databases);
}
txindex += Txindex::from(tx_len);
@@ -505,8 +483,8 @@ fn main() -> color_eyre::Result<()> {
pause();
let wtx = wtx_opt.take().context("option should have wtx")?;
export(&keyspace, wtx, &parts, &mut vecdisks, height)?;
let databases = databases_opt.take().context("option should have wtx")?;
export(databases, &mut vecdisks, height)?;
pause();
+2 -21
View File
@@ -1,10 +1,9 @@
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use super::SliceExtended;
use snkrj::{direct_repr, Storable, UnsizedStorable};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
pub struct Addressindex(u32);
direct_repr!(Addressindex);
impl Addressindex {
pub const BYTES: usize = size_of::<Self>();
@@ -49,21 +48,3 @@ impl From<Addressindex> for usize {
value.0 as usize
}
}
impl TryFrom<Slice> for Addressindex {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
Self::try_from(&value[..])
}
}
impl TryFrom<&[u8]> for Addressindex {
type Error = color_eyre::Report;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self::from(value.read_be_u32()?))
}
}
impl From<Addressindex> for Slice {
fn from(value: Addressindex) -> Self {
value.to_be_bytes().into()
}
}
@@ -1,12 +1,13 @@
use fjall::Slice;
use snkrj::{direct_repr, Storable, UnsizedStorable};
use super::{Addressindex, Txoutindex};
#[derive(Debug)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Addressindextxoutindex {
addressindex: Addressindex,
txoutindex: Txoutindex,
}
direct_repr!(Addressindextxoutindex);
impl From<(Addressindex, Txoutindex)> for Addressindextxoutindex {
fn from(value: (Addressindex, Txoutindex)) -> Self {
@@ -16,23 +17,3 @@ impl From<(Addressindex, Txoutindex)> for Addressindextxoutindex {
}
}
}
impl From<Addressindextxoutindex> for Slice {
fn from(value: Addressindextxoutindex) -> Self {
let addressindex_slice = Self::from(value.addressindex);
let txindexvout_slice = Self::from(value.txoutindex);
Self::from([addressindex_slice, txindexvout_slice].concat())
}
}
impl TryFrom<Slice> for Addressindextxoutindex {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
let addressindex = Addressindex::try_from(&value[..Addressindex::BYTES])?;
let txindexvout = Txoutindex::try_from(&value[Addressindex::BYTES..])?;
Ok(Self {
addressindex,
txoutindex: txindexvout,
})
}
}
@@ -1,10 +1,9 @@
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use super::SliceExtended;
use snkrj::{direct_repr, Storable, UnsizedStorable};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
pub struct Addresstypeindex(u32);
direct_repr!(Addresstypeindex);
impl Addresstypeindex {
pub fn decremented(self) -> Self {
@@ -47,35 +46,3 @@ impl From<Addresstypeindex> for usize {
value.0 as usize
}
}
impl TryFrom<Slice> for Addresstypeindex {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
Self::try_from(&value[..])
}
}
impl TryFrom<&[u8]> for Addresstypeindex {
type Error = color_eyre::Report;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self::from(value.read_be_u32()?))
}
}
impl From<Addresstypeindex> for Slice {
fn from(value: Addresstypeindex) -> Self {
value.to_be_bytes().into()
}
}
// impl Bytes for Addresstypeindex {
// const SIZE: usize = size_of::<Self>();
// type ByteArray = [u8; Self::SIZE];
// // fn try_from_bytes(bytes: &[u8]) -> color_eyre::Result<Self> {
// // Ok(Self(Self::read_u32(bytes)))
// // }
// fn to_bytes(&self) -> Self::ByteArray {
// self.to_ne_bytes()
// }
// }
+14 -19
View File
@@ -5,12 +5,13 @@ use std::{
use biter::bitcoin;
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use snkrj::{direct_repr, Storable, UnsizedStorable};
use super::Height;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
pub struct Amount(bitcoin::Amount);
direct_repr!(Amount);
impl Amount {
pub const ZERO: Self = Self(bitcoin::Amount::ZERO);
@@ -22,24 +23,6 @@ impl Amount {
}
}
impl From<u64> for Amount {
fn from(value: u64) -> Self {
Self(bitcoin::Amount::from_sat(value))
}
}
impl From<bitcoin::Amount> for Amount {
fn from(value: bitcoin::Amount) -> Self {
Self(value)
}
}
impl From<Amount> for Slice {
fn from(value: Amount) -> Self {
value.to_sat().to_be_bytes().into()
}
}
impl Add for Amount {
type Output = Amount;
fn add(self, rhs: Amount) -> Self::Output {
@@ -93,3 +76,15 @@ impl Sum for Amount {
Amount::from(sats)
}
}
impl From<u64> for Amount {
fn from(value: u64) -> Self {
Self(bitcoin::Amount::from_sat(value))
}
}
impl From<bitcoin::Amount> for Amount {
fn from(value: bitcoin::Amount) -> Self {
Self(value)
}
}
@@ -0,0 +1,23 @@
use std::time::Duration;
use canopydb::{Database as CanopyDatabase, DbOptions};
use derive_deref::{Deref, DerefMut};
use super::Environment;
#[derive(Debug, Deref, DerefMut)]
pub struct Database(CanopyDatabase);
impl Database {
pub fn new(environment: &Environment, name: &str) -> color_eyre::Result<Self> {
let mut options = DbOptions::default();
options.use_wal = false;
options.checkpoint_interval = Duration::from_secs(u64::MAX);
options.checkpoint_target_size = usize::MAX;
options.throttle_memory_limit = usize::MAX;
options.stall_memory_limit = usize::MAX;
options.write_txn_memory_limit = usize::MAX;
Ok(Self(environment.get_or_create_database_with(name, options)?))
}
}
@@ -0,0 +1,20 @@
use std::path::Path;
use canopydb::{EnvOptions, Environment as CanopyEnvironment};
use derive_deref::{Deref, DerefMut};
#[derive(Debug, Deref, DerefMut)]
pub struct Environment(CanopyEnvironment);
impl Environment {
pub fn new(path: &Path) -> color_eyre::Result<Self> {
let mut options = EnvOptions::new(path);
// options.use_mmap = true;
options.disable_fsync = true;
options.wal_new_file_on_checkpoint = false;
options.wal_background_sync_interval = None;
options.wal_write_batch_memory_limit = usize::MAX;
Ok(Self(CanopyEnvironment::with_options(options)?))
}
}
@@ -0,0 +1,9 @@
mod database;
mod environment;
// mod transaction;
mod tree;
pub use database::*;
pub use environment::*;
// pub use transaction::*;
pub use tree::*;
@@ -0,0 +1,19 @@
use canopydb::{Tree as CanopyTree, TreeOptions, WriteTransaction};
use super::{Database, Tree};
#[derive(Debug)]
pub struct Transaction<'a, K, V> {
tx: WriteTransaction,
tree: Tree<'a, K, V>,
}
impl<'a, K, V> Transaction<'a, K, V> {
pub fn new(db: &Database) -> color_eyre::Result<Self> {
let tx = db.begin_write()?;
let tree = Tree::new(&tx)?;
Ok(Self { tx, tree })
}
}
@@ -0,0 +1,84 @@
use std::{
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
};
use canopydb::{Tree as CanopyTree, TreeOptions, WriteTransaction};
use color_eyre::eyre::eyre;
#[derive(Debug)]
pub struct Tree<'a, K, V> {
tree: CanopyTree<'a>,
k: PhantomData<K>,
v: PhantomData<V>,
}
impl<'a, K, V> Deref for Tree<'a, K, V> {
type Target = CanopyTree<'a>;
fn deref(&self) -> &Self::Target {
&self.tree
}
}
impl<'a, K, V> DerefMut for Tree<'a, K, V> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.tree
}
}
impl<'a, K, V> Tree<'a, K, V>
where
K: Debug + Sized,
V: Debug + Sized + Clone + Copy,
{
const SIZE_OF_K: usize = size_of::<K>();
const SIZE_OF_V: usize = size_of::<V>();
pub fn new(tx: &'a WriteTransaction) -> color_eyre::Result<Self> {
let mut options = TreeOptions::new();
options.compress_overflow_values = None;
options.fixed_key_len = size_of::<K>() as i8;
options.fixed_value_len = size_of::<V>() as i8;
Ok(Self {
tree: tx.get_or_create_tree_with(b"tree", options)?,
k: PhantomData,
v: PhantomData,
})
}
pub fn get(&self, key: &K) -> color_eyre::Result<Option<V>> {
let slice = self.tree.get(Self::key_as_slice(key))?;
if slice.is_none() {
return Ok(None);
}
let slice = slice.unwrap();
let (prefix, shorts, suffix) = unsafe { slice.align_to::<V>() };
if !prefix.is_empty() || shorts.len() != 1 || !suffix.is_empty() {
dbg!(&key, &prefix, &shorts, &suffix);
return Err(eyre!("align_to issue"));
}
Ok(Some(shorts[0]))
}
pub fn insert(&mut self, key: &K, value: &V) -> Result<(), canopydb::Error> {
self.tree
.insert(Self::key_as_slice(key), Self::value_as_slice(value))
}
fn key_as_slice(key: &K) -> &[u8] {
let data: *const K = key;
let data: *const u8 = data as *const u8;
unsafe { std::slice::from_raw_parts(data, Self::SIZE_OF_K) }
}
fn value_as_slice(value: &V) -> &[u8] {
let data: *const V = value;
let data: *const u8 = data as *const u8;
unsafe { std::slice::from_raw_parts(data, Self::SIZE_OF_V) }
}
}
+186
View File
@@ -0,0 +1,186 @@
use std::{path::Path, thread};
use snkrj::{AnyDatabase, Database};
use crate::structs::Height;
use super::{
AddressbytesPrefix, Addressindex, Addressindextxoutindex, BlockHashPrefix, TxidPrefix, Txindex, Txindexvout,
Txoutindex,
};
pub struct Databases {
pub addressbytes_prefix_to_addressindex: Database<AddressbytesPrefix, Addressindex>,
pub addressindextxoutindex_in: Database<Addressindextxoutindex, ()>,
pub addressindextxoutindex_out: Database<Addressindextxoutindex, ()>,
pub blockhash_prefix_to_height: Database<BlockHashPrefix, Height>,
pub txid_prefix_to_txindex: Database<TxidPrefix, Txindex>,
pub txindexvout_to_txoutindex: Database<Txindexvout, Txoutindex>,
}
const UNSAFE_BLOCKS: usize = 100;
impl Databases {
pub fn open(path: &Path) -> color_eyre::Result<Self> {
Ok(Self {
addressbytes_prefix_to_addressindex: Database::open(path.join("addressbytes_prefix_to_addressindex"))?,
addressindextxoutindex_in: Database::open(path.join("addresstxoutindexes_in"))?,
addressindextxoutindex_out: Database::open(path.join("addresstxoutindexes_out"))?,
blockhash_prefix_to_height: Database::open(path.join("blockhash_prefix_to_height"))?,
txid_prefix_to_txindex: Database::open(path.join("txid_prefix_to_txindex"))?,
txindexvout_to_txoutindex: Database::open(path.join("txindexvout_to_txoutindex"))?,
})
}
// pub fn rollback_from(
// &mut self,
// _wtx: &mut WriteTransaction,
// _height: Height,
// _exit: &Exit,
// ) -> color_eyre::Result<()> {
// panic!();
// let mut txindex = None;
// wtx.range(self.height_to_blockhash.data(), Slice::from(height)..)
// .try_for_each(|slice| -> color_eyre::Result<()> {
// let (height_slice, slice_blockhash) = slice?;
// let blockhash = BlockHash::from_slice(&slice_blockhash)?;
// wtx.remove(self.height_to_blockhash.data(), height_slice);
// wtx.remove(self.blockhash_prefix_to_height.data(), blockhash.prefix());
// if txindex.is_none() {
// txindex.replace(
// wtx.get(self.height_to_first_txindex.data(), height_slice)?
// .context("for height to have first txindex")?,
// );
// }
// wtx.remove(self.height_to_first_txindex.data(), height_slice);
// wtx.remove(self.height_to_last_txindex.data(), height_slice);
// Ok(())
// })?;
// let txindex = txindex.context("txindex to not be none by now")?;
// wtx.range(self.txindex_to_txid.data(), Slice::from(txindex)..)
// .try_for_each(|slice| -> color_eyre::Result<()> {
// let (slice_txindex, slice_txid) = slice?;
// let txindex = Txindex::from(slice_txindex);
// let txid = Txid::from_slice(&slice_txid)?;
// wtx.remove(self.txindex_to_txid.data(), Slice::from(txindex));
// wtx.remove(self.txindex_to_height.data(), Slice::from(txindex));
// wtx.remove(self.txid_prefix_to_txindex.data(), txid.prefix());
// Ok(())
// })?;
// let txoutindex = Txoutindex::from(txindex);
// let mut addressindexes = BTreeSet::new();
// wtx.range(self.txoutindex_to_amount.data(), Slice::from(txoutindex)..)
// .try_for_each(|slice| -> color_eyre::Result<()> {
// let (txoutindex_slice, _) = slice?;
// wtx.remove(self.txoutindex_to_amount.data(), txoutindex_slice);
// if let Some(addressindex_slice) =
// wtx.get(self.txoutindex_to_addressindex.data(), txoutindex_slice)?
// {
// wtx.remove(self.txoutindex_to_addressindex.data(), txoutindex_slice);
// let addressindex = Addressindex::from(addressindex_slice);
// addressindexes.insert(addressindex);
// let txoutindex = Txoutindex::from(txoutindex_slice);
// let addresstxoutindex = Addresstxoutindex::from((addressindex, txoutindex));
// wtx.remove(
// self.addressindex_to_txoutindexes.data(),
// Slice::from(addresstxoutindex),
// );
// }
// Ok(())
// })?;
// addressindexes
// .into_iter()
// .filter(|addressindex| {
// let is_empty = wtx
// .prefix(
// self.addressindex_to_txoutindexes.data(),
// Slice::from(*addressindex),
// )
// .next()
// .is_none();
// is_empty
// })
// .try_for_each(|addressindex| -> color_eyre::Result<()> {
// let addressindex_slice = Slice::from(addressindex);
// let addressbytes = Addressbytes::from(
// wtx.get(
// self.addressindex_to_addressbytes.data(),
// &addressindex_slice,
// )?
// .context("addressindex_to_address to have value")?,
// );
// wtx.remove(
// self.addressbytes_prefix_to_addressindex.data(),
// addressbytes.prefix(),
// );
// wtx.remove(
// self.addressindex_to_addressbytes.data(),
// &addressindex_slice,
// );
// wtx.remove(self.addressindex_to_addresstype.data(), &addressindex_slice);
// Ok(())
// })?;
//
// todo!("clear addresstxoutindexes_out")
// todo!("clear addresstxoutindexes_in")
// todo!("clear zero_txoutindexes")
// todo!("clear txindexvout_to_txoutindex")
// Ok(())
// }
fn to_ref_vec(&self) -> Vec<&dyn AnyDatabase> {
vec![
&self.addressbytes_prefix_to_addressindex as &dyn AnyDatabase,
&self.addressindextxoutindex_in,
&self.addressindextxoutindex_out,
&self.blockhash_prefix_to_height,
&self.txid_prefix_to_txindex,
&self.txindexvout_to_txoutindex,
]
}
fn to_ref_mut_vec(&mut self) -> Vec<&mut dyn AnyDatabase> {
vec![
&mut self.addressbytes_prefix_to_addressindex as &mut dyn AnyDatabase,
&mut self.addressindextxoutindex_in,
&mut self.addressindextxoutindex_out,
&mut self.blockhash_prefix_to_height,
&mut self.txid_prefix_to_txindex,
&mut self.txindexvout_to_txoutindex,
]
}
pub fn export(self) {
thread::scope(|scope| {
scope.spawn(|| self.addressbytes_prefix_to_addressindex.export(false));
scope.spawn(|| self.addressindextxoutindex_in.export(false));
scope.spawn(|| self.addressindextxoutindex_out.export(false));
scope.spawn(|| self.blockhash_prefix_to_height.export(false));
scope.spawn(|| self.txid_prefix_to_txindex.export(false));
scope.spawn(|| self.txindexvout_to_txoutindex.export(false));
});
}
}
+2 -29
View File
@@ -5,12 +5,11 @@ use std::{
use biter::bitcoincore_rpc::{self, RpcApi};
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use super::SliceExtended;
use snkrj::{direct_repr, Storable, UnsizedStorable};
#[derive(Debug, Clone, Copy, Deref, DerefMut, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct Height(u32);
direct_repr!(Height);
impl PartialEq<u64> for Height {
fn eq(&self, other: &u64) -> bool {
@@ -75,18 +74,6 @@ impl fmt::Display for Height {
}
}
impl TryFrom<Slice> for Height {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
Ok(Self::from((&value[..]).read_be_u32()?))
}
}
impl From<Height> for Slice {
fn from(value: Height) -> Self {
value.to_be_bytes().into()
}
}
impl From<u32> for Height {
fn from(value: u32) -> Self {
Self(value)
@@ -110,17 +97,3 @@ impl TryFrom<&bitcoincore_rpc::Client> for Height {
Ok((value.get_blockchain_info()?.blocks as usize - 1).into())
}
}
// impl Bytes for Height {
// const SIZE: usize = size_of::<Self>();
// type ByteArray = [u8; Self::SIZE];
// // fn try_from_bytes(bytes: &[u8]) -> color_eyre::Result<Self> {
// // Ok(Self(Self::read_u32(bytes)))
// // }
// fn to_bytes(&self) -> Self::ByteArray {
// self.to_ne_bytes()
// }
// }
+4 -6
View File
@@ -4,10 +4,10 @@ mod addressindextxoutindex;
mod addresstype;
mod addresstypeindex;
mod amount;
mod canopy;
mod databases;
mod exit;
mod height;
mod partition;
mod partitions;
mod prefix;
mod slice;
mod txindex;
@@ -15,7 +15,6 @@ mod txindexvout;
mod txoutindex;
mod vecdisk;
mod vecdisks;
mod version;
pub use addressbytes::*;
pub use addressindex::*;
@@ -23,10 +22,10 @@ pub use addressindextxoutindex::*;
pub use addresstype::*;
pub use addresstypeindex::*;
pub use amount::*;
pub use canopy::*;
pub use databases::*;
pub use exit::*;
pub use height::*;
pub use partition::*;
pub use partitions::*;
pub use prefix::*;
pub use slice::*;
pub use txindex::*;
@@ -34,4 +33,3 @@ pub use txindexvout::*;
pub use txoutindex::*;
pub use vecdisk::*;
pub use vecdisks::*;
pub use version::*;
+28 -30
View File
@@ -1,32 +1,26 @@
use biter::bitcoin::{BlockHash, Txid};
use derive_deref::Deref;
use fjall::Slice;
use snkrj::{direct_repr, Storable, UnsizedStorable};
use super::Addressbytes;
use super::{Addressbytes, SliceExtended};
#[derive(Debug, Deref, PartialEq, Eq, PartialOrd, Ord)]
pub struct Prefix(Slice);
impl From<&[u8]> for Prefix {
fn from(value: &[u8]) -> Self {
Self(Slice::from(&value[..8]))
#[derive(Debug, Deref, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Prefix([u8; 8]);
direct_repr!(Prefix);
impl TryFrom<&[u8]> for Prefix {
type Error = color_eyre::Report;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self(value.read_8xU8()?))
}
}
// pub struct Prefix([u8; 8]);
// impl From<&[u8]> for Prefix {
// fn from(value: &[u8]) -> Self {
// let mut buf: [u8; 8] = [0; 8];
// value.iter().take(8).enumerate().for_each(|(i, v)| {
// buf[i] = *v;
// });
// Self(buf)
// }
// }
#[derive(Debug, Deref)]
#[derive(Debug, Deref, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct AddressbytesPrefix(Prefix);
impl From<&Addressbytes> for AddressbytesPrefix {
fn from(value: &Addressbytes) -> Self {
Self(Prefix::from(match value {
direct_repr!(AddressbytesPrefix);
impl TryFrom<&Addressbytes> for AddressbytesPrefix {
type Error = color_eyre::Report;
fn try_from(value: &Addressbytes) -> Result<Self, Self::Error> {
Ok(Self(Prefix::try_from(match value {
Addressbytes::P2PK65(bytes) => &bytes[..],
Addressbytes::P2PK33(bytes) => &bytes[..],
Addressbytes::P2PKH(bytes) => &bytes[..],
@@ -34,22 +28,26 @@ impl From<&Addressbytes> for AddressbytesPrefix {
Addressbytes::P2WPKH(bytes) => &bytes[..],
Addressbytes::P2WSH(bytes) => &bytes[..],
Addressbytes::P2TR(bytes) => &bytes[..],
}))
})?))
}
}
#[derive(Debug, Deref)]
#[derive(Debug, Deref, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct BlockHashPrefix(Prefix);
impl From<&BlockHash> for BlockHashPrefix {
fn from(value: &BlockHash) -> Self {
Self(Prefix::from(&value[..]))
direct_repr!(BlockHashPrefix);
impl TryFrom<&BlockHash> for BlockHashPrefix {
type Error = color_eyre::Report;
fn try_from(value: &BlockHash) -> Result<Self, Self::Error> {
Ok(Self(Prefix::try_from(&value[..])?))
}
}
#[derive(Debug, Deref, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, Deref, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct TxidPrefix(Prefix);
impl From<&Txid> for TxidPrefix {
fn from(value: &Txid) -> Self {
Self(Prefix::from(&value[..]))
direct_repr!(TxidPrefix);
impl TryFrom<&Txid> for TxidPrefix {
type Error = color_eyre::Report;
fn try_from(value: &Txid) -> Result<Self, Self::Error> {
Ok(Self(Prefix::try_from(&value[..])?))
}
}
+7
View File
@@ -2,6 +2,7 @@ use color_eyre::eyre::eyre;
#[allow(unused)]
pub trait SliceExtended {
fn read_8xU8(&self) -> color_eyre::Result<[u8; 8]>;
fn read_be_u8(&self) -> color_eyre::Result<u8>;
fn read_be_u16(&self) -> color_eyre::Result<u16>;
fn read_be_u32(&self) -> color_eyre::Result<u32>;
@@ -10,6 +11,12 @@ pub trait SliceExtended {
}
impl SliceExtended for &[u8] {
fn read_8xU8(&self) -> color_eyre::Result<[u8; 8]> {
let mut buf: [u8; 8] = [0; 8];
(&self[..8]).read_exact(&mut buf)?;
Ok(buf)
}
fn read_be_u8(&self) -> color_eyre::Result<u8> {
let mut buf: [u8; 1] = [0; 1];
self.read_exact(&mut buf)?;
+2 -21
View File
@@ -1,12 +1,11 @@
use std::ops::{Add, AddAssign};
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use super::SliceExtended;
use snkrj::{direct_repr, Storable, UnsizedStorable};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
pub struct Txindex(u32);
direct_repr!(Txindex);
impl Txindex {
pub fn incremented(self) -> Self {
@@ -58,21 +57,3 @@ impl From<Txindex> for usize {
value.0 as usize
}
}
impl TryFrom<Slice> for Txindex {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
Self::try_from(&value[..])
}
}
impl TryFrom<&[u8]> for Txindex {
type Error = color_eyre::Report;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self::from(value.read_be_u32()?))
}
}
impl From<Txindex> for Slice {
fn from(value: Txindex) -> Self {
value.to_be_bytes().into()
}
}
+3 -26
View File
@@ -1,14 +1,13 @@
use fjall::Slice;
use snkrj::{direct_repr, Storable, UnsizedStorable};
use super::{SliceExtended, Txindex};
use super::Txindex;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default)]
pub struct Txindexvout {
pub txindex: Txindex,
pub vout: u32,
}
const BYTES: usize = size_of::<Txindexvout>();
direct_repr!(Txindexvout);
impl From<Txindex> for Txindexvout {
fn from(value: Txindex) -> Self {
@@ -27,25 +26,3 @@ impl From<(Txindex, u32)> for Txindexvout {
}
}
}
impl From<Txindexvout> for Slice {
fn from(value: Txindexvout) -> Self {
let txindex_slice = Self::from(value.txindex);
let vout_slice = Self::from(value.vout.to_be_bytes());
Self::from([txindex_slice, vout_slice].concat())
}
}
impl TryFrom<Slice> for Txindexvout {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
Self::try_from(&value[..])
}
}
impl TryFrom<&[u8]> for Txindexvout {
type Error = color_eyre::Report;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let txindex = Txindex::try_from(&value[..BYTES])?;
let vout = (&value[BYTES..]).read_be_u32()?;
Ok(Self { txindex, vout })
}
}
+2 -21
View File
@@ -1,12 +1,11 @@
use std::ops::{Add, AddAssign};
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use super::SliceExtended;
use snkrj::{direct_repr, Storable, UnsizedStorable};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
pub struct Txoutindex(u64);
direct_repr!(Txoutindex);
impl Txoutindex {
pub fn incremented(self) -> Self {
@@ -52,21 +51,3 @@ impl From<Txoutindex> for usize {
value.0 as usize
}
}
impl TryFrom<Slice> for Txoutindex {
type Error = color_eyre::Report;
fn try_from(value: Slice) -> Result<Self, Self::Error> {
Self::try_from(&value[..])
}
}
impl TryFrom<&[u8]> for Txoutindex {
type Error = color_eyre::Report;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self::from(value.read_be_u64()?))
}
}
impl From<Txoutindex> for Slice {
fn from(value: Txoutindex) -> Self {
value.to_be_bytes().into()
}
}
-1
View File
@@ -1,5 +1,4 @@
use derive_deref::{Deref, DerefMut};
use fjall::Slice;
use super::SliceExtended;
+6 -6
View File
@@ -299,9 +299,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.92"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
@@ -414,9 +414,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.134"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
dependencies = [
"itoa",
"memchr",
@@ -432,9 +432,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.93"
version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
+1 -1
View File
@@ -13,7 +13,7 @@ bitcoin = { version = "0.32.5", features = ["serde"] }
rayon = "1.10.0"
crossbeam = { version = "0.8.4", features = ["crossbeam-channel"] }
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.134"
serde_json = "1.0.135"
derived-deref = "2.1.0"
bitcoincore-rpc = "0.19.0"
# tokio = { version = "1.39.2", features = ["rt-multi-thread"] }