diff --git a/Cargo.lock b/Cargo.lock index 898a1b836..8e4209fa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,2144 +1,2145 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "abc-rust-error" version = "0.1.0" dependencies = [ "abc-rust-lint", "eyre", "http", "stable-eyre", "thiserror", ] [[package]] name = "abc-rust-lint" version = "0.1.0" [[package]] name = "addr2line" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ "gimli", ] [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] [[package]] name = "anyhow" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "async-trait" version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "atomic-polyfill" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" dependencies = [ "critical-section", ] [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" dependencies = [ "async-trait", "axum-core", "base64", "bytes", "futures-util", "http", "http-body", "http-body-util", "hyper", "hyper-util", "itoa", "matchit", "memchr", "mime", "percent-encoding", "pin-project-lite", "rustversion", "serde", "serde_json", "serde_path_to_error", "serde_urlencoded", "sha1", "sync_wrapper", "tokio", "tokio-tungstenite", "tower", "tower-layer", "tower-service", "tracing", ] [[package]] name = "axum-core" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" dependencies = [ "async-trait", "bytes", "futures-util", "http", "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", "sync_wrapper", "tower-layer", "tower-service", "tracing", ] [[package]] name = "backtrace" version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", ] [[package]] name = "base64" version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "bimap" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" [[package]] name = "bindgen" version = "0.65.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" dependencies = [ "bitflags 1.3.2", "cexpr", "clang-sys", "lazy_static", "lazycell", "peeking_take_while", "prettyplease 0.2.12", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", "syn 2.0.29", ] [[package]] name = "bitcoinsuite-core" version = "0.1.0" dependencies = [ "abc-rust-lint", "bytes", "hex", "hex-literal", "ripemd", "serde", "sha2", "thiserror", ] [[package]] name = "bitcoinsuite-slp" version = "0.1.0" dependencies = [ "abc-rust-lint", "bitcoinsuite-core", "bytes", "hex", "itertools", "pretty_assertions", "serde", "thiserror", ] [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] [[package]] name = "bzip2-sys" version = "0.1.11+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" dependencies = [ "cc", "libc", "pkg-config", ] [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", ] [[package]] name = "cexpr" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ "nom", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chronik-bridge" version = "0.1.0" dependencies = [ "abc-rust-lint", "bitcoinsuite-core", "cxx", "cxx-build", ] [[package]] name = "chronik-db" version = "0.1.0" dependencies = [ "abc-rust-error", "abc-rust-lint", "bimap", "bitcoinsuite-core", "bitcoinsuite-slp", "bytes", "chronik-util", "fastrand", "hex", "itertools", "postcard", "pretty_assertions", "rocksdb", "seahash", "serde", "tempdir", "thiserror", "topo_sort", ] [[package]] name = "chronik-http" version = "0.1.0" dependencies = [ "abc-rust-error", "abc-rust-lint", "async-trait", "axum", "bitcoinsuite-core", "bitcoinsuite-slp", + "chronik-bridge", "chronik-db", "chronik-indexer", "chronik-proto", "chronik-util", "futures", "hex", "http", "http-body-util", "hyper", "prost", "thiserror", "tokio", "tower-service", ] [[package]] name = "chronik-indexer" version = "0.1.0" dependencies = [ "abc-rust-error", "abc-rust-lint", "bitcoinsuite-core", "bitcoinsuite-slp", "bytes", "chronik-bridge", "chronik-db", "chronik-proto", "chronik-util", "cxx", "pretty_assertions", "prost", "prost-build", "tempdir", "thiserror", "tokio", ] [[package]] name = "chronik-lib" version = "0.1.0" dependencies = [ "abc-rust-error", "abc-rust-lint", "bitcoinsuite-core", "chronik-bridge", "chronik-db", "chronik-http", "chronik-indexer", "chronik-plugin", "chronik-util", "cxx", "cxx-build", "thiserror", "tokio", ] [[package]] name = "chronik-plugin" version = "0.1.0" dependencies = [ "abc-rust-error", "abc-rust-lint", "chronik-plugin-impl", ] [[package]] name = "chronik-plugin-impl" version = "0.1.0" dependencies = [ "abc-rust-error", "abc-rust-lint", "bitcoinsuite-core", "bitcoinsuite-slp", "chronik-util", "pyo3", ] [[package]] name = "chronik-proto" version = "0.1.0" dependencies = [ "abc-rust-lint", "prost", "prost-build", ] [[package]] name = "chronik-util" version = "0.1.0" dependencies = [ "abc-rust-lint", ] [[package]] name = "clang-sys" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", "libloading", ] [[package]] name = "cobs" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "codespan-reporting" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", "unicode-width", ] [[package]] name = "cpufeatures" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "critical-section" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" [[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", ] [[package]] name = "cxx" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28403c86fc49e3401fdf45499ba37fad6493d9329449d6449d7f0e10f4654d28" dependencies = [ "cc", "cxxbridge-flags", "cxxbridge-macro", "link-cplusplus", ] [[package]] name = "cxx-build" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78da94fef01786dc3e0c76eafcd187abcaa9972c78e05ff4041e24fdf059c285" dependencies = [ "cc", "codespan-reporting", "once_cell", "proc-macro2", "quote", "scratch", "syn 2.0.29", ] [[package]] name = "cxxbridge-flags" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2a6f5e1dfb4b34292ad4ea1facbfdaa1824705b231610087b00b17008641809" [[package]] name = "cxxbridge-macro" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50c49547d73ba8dcfd4ad7325d64c6d5391ff4224d498fc39a6f3f49825a530d" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "data-encoding" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "diff" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", ] [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", "windows-sys", ] [[package]] name = "errno-dragonfly" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" dependencies = [ "cc", "libc", ] [[package]] name = "eyre" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" dependencies = [ "indenter", "once_cell", ] [[package]] name = "fastrand" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", "futures-executor", "futures-io", "futures-sink", "futures-task", "futures-util", ] [[package]] name = "futures-channel" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", "futures-util", ] [[package]] name = "futures-io" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "futures-sink" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", "futures-io", "futures-macro", "futures-sink", "futures-task", "memchr", "pin-project-lite", "pin-utils", "slab", ] [[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", ] [[package]] name = "getrandom" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "gimli" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", "http", "indexmap", "slab", "tokio", "tokio-util", "tracing", ] [[package]] name = "hash32" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" dependencies = [ "byteorder", ] [[package]] name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "heapless" version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" dependencies = [ "atomic-polyfill", "hash32", "rustc_version", "serde", "spin", "stable_deref_trait", ] [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "http" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" dependencies = [ "bytes", "fnv", "itoa", ] [[package]] name = "http-body" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", "http", ] [[package]] name = "http-body-util" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" dependencies = [ "bytes", "futures-util", "http", "http-body", "pin-project-lite", ] [[package]] name = "httparse" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" dependencies = [ "bytes", "futures-channel", "futures-util", "h2", "http", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", "tokio", ] [[package]] name = "hyper-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", "futures-util", "http", "http-body", "hyper", "pin-project-lite", "socket2", "tokio", ] [[package]] name = "idna" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", ] [[package]] name = "indenter" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "indoc" version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" [[package]] name = "itertools" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libloading" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if", "winapi", ] [[package]] name = "librocksdb-sys" version = "0.11.0+8.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" dependencies = [ "bindgen", "bzip2-sys", "cc", "glob", "libc", "libz-sys", ] [[package]] name = "libz-sys" version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" dependencies = [ "cc", "pkg-config", "vcpkg", ] [[package]] name = "link-cplusplus" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" dependencies = [ "cc", ] [[package]] name = "linux-raw-sys" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "lock_api" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", ] [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "matchit" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", "windows-sys", ] [[package]] name = "multimap" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", ] [[package]] name = "num_cpus" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", ] [[package]] name = "object" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", "redox_syscall 0.4.1", "smallvec", "windows-targets", ] [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "petgraph" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", "indexmap", ] [[package]] name = "pin-project" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "pin-project-lite" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "postcard" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9ee729232311d3cd113749948b689627618133b1c5012b77342c1950b25eaeb" dependencies = [ "cobs", "heapless", "serde", ] [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pretty_assertions" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ "diff", "yansi", ] [[package]] name = "prettyplease" version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", "syn 1.0.109", ] [[package]] name = "prettyplease" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" dependencies = [ "proc-macro2", "syn 2.0.29", ] [[package]] name = "proc-macro2" version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "prost" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", "prost-derive", ] [[package]] name = "prost-build" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck", "itertools", "lazy_static", "log", "multimap", "petgraph", "prettyplease 0.1.25", "prost", "prost-types", "regex", "syn 1.0.109", "tempfile", "which", ] [[package]] name = "prost-derive" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", "syn 1.0.109", ] [[package]] name = "prost-types" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ "prost", ] [[package]] name = "pyo3" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a89dc7a5850d0e983be1ec2a463a171d20990487c3cfcd68b5363f1ee3d6fe0" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", "parking_lot", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", "unindent", ] [[package]] name = "pyo3-build-config" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07426f0d8fe5a601f26293f300afd1a7b1ed5e78b2a705870c5f30893c5163be" dependencies = [ "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb7dec17e17766b46bca4f1a4215a85006b4c2ecde122076c562dd058da6cf1" dependencies = [ "libc", "pyo3-build-config", ] [[package]] name = "pyo3-macros" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f738b4e40d50b5711957f142878cfa0f28e054aa0ebdfc3fd137a843f74ed3" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", "syn 2.0.29", ] [[package]] name = "pyo3-macros-backend" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc910d4851847827daf9d6cdd4a823fbdaab5b8818325c5e97a86da79e8881f" dependencies = [ "heck", "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "quote" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" dependencies = [ "fuchsia-cprng", "libc", "rand_core 0.3.1", "rdrand", "winapi", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core 0.6.4", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core 0.6.4", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ "rand_core 0.4.2", ] [[package]] name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" dependencies = [ "rand_core 0.3.1", ] [[package]] name = "redox_syscall" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "remove_dir_all" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ "winapi", ] [[package]] name = "ripemd" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ "digest", ] [[package]] name = "rocksdb" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" dependencies = [ "libc", "librocksdb-sys", ] [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] [[package]] name = "rustix" version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", "windows-sys", ] [[package]] name = "rustversion" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scratch" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" [[package]] name = "seahash" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "semver" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "serde_json" version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "serde_path_to_error" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ "itoa", "serde", ] [[package]] name = "serde_urlencoded" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", "itoa", "ryu", "serde", ] [[package]] name = "sha1" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", "digest", ] [[package]] name = "sha2" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] [[package]] name = "shlex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", "windows-sys", ] [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] [[package]] name = "stable-eyre" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "556fec8c2da34c70b75f16d88df8a8cd7e652e567ff097b7e9df0022c8695cc4" dependencies = [ "backtrace", "eyre", "indenter", ] [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "syn" version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "sync_wrapper" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "target-lexicon" version = "0.12.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" [[package]] name = "tempdir" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" dependencies = [ "rand 0.4.6", "remove_dir_all", ] [[package]] name = "tempfile" version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", "rustix", "windows-sys", ] [[package]] name = "termcolor" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "tinyvec" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", "socket2", "tokio-macros", "windows-sys", ] [[package]] name = "tokio-macros" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", "syn 2.0.29", ] [[package]] name = "tokio-tungstenite" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", "tokio", "tungstenite", ] [[package]] name = "tokio-util" version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", "tracing", ] [[package]] name = "topo_sort" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "156552d3c80df430aaac98c605a4e0eb7da8d06029cce2d40b4a6b095a34b37e" [[package]] name = "tower" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", "pin-project", "pin-project-lite", "tokio", "tower-layer", "tower-service", "tracing", ] [[package]] name = "tower-layer" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] [[package]] name = "tungstenite" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", "data-encoding", "http", "httparse", "log", "rand 0.8.5", "sha1", "thiserror", "url", "utf-8", ] [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-bidi" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unindent" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" [[package]] name = "url" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] [[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "which" version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", "once_cell", ] [[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-util" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] [[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.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/chronik/chronik-bridge/src/ffi.rs b/chronik/chronik-bridge/src/ffi.rs index a183f7dae..7e1bb8673 100644 --- a/chronik/chronik-bridge/src/ffi.rs +++ b/chronik/chronik-bridge/src/ffi.rs @@ -1,314 +1,318 @@ // Copyright (c) 2022 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. //! Module containing the cxx definitions for the bridge from C++ to Rust. pub use self::ffi_inner::*; #[allow(unsafe_code)] #[cxx::bridge(namespace = "chronik_bridge")] mod ffi_inner { /// Info about a block #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct BlockInfo { /// Hash of the block (or 000...000 if no block) pub hash: [u8; 32], /// Height of the block (or -1 if no block) pub height: i32, } /// Block coming from bitcoind to Chronik. /// /// We don't index all fields (e.g. hashMerkleRoot), only those that are /// needed when querying a range of blocks. /// /// Instead of storing all the block data for Chronik again, we only store /// file_num, data_pos and undo_pos of the block data of the node. /// /// This makes the index relatively small, as it's mostly just pointing to /// the data the node already stores. /// /// Note that this prohibits us from using Chronik in pruned mode. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Block { /// Block hash pub hash: [u8; 32], /// hashPrevBlock, hash of the previous block in the chain pub prev_hash: [u8; 32], /// nBits, difficulty of the header pub n_bits: u32, /// Timestamp of the block pub timestamp: i64, /// Height of the block in the chain. pub height: i32, /// File number of the block file this block is stored in. /// This can be used to later slice out transactions, so we don't have /// to index txs twice. pub file_num: u32, /// Position of the block within the block file, starting at the block /// header. pub data_pos: u32, /// Position of the undo data within the undo file. pub undo_pos: u32, /// Serialized size of the block pub size: u64, /// Txs of this block, including positions within the block/undo files. pub txs: Vec, } /// Tx in a block #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct BlockTx { /// Tx (without disk data) pub tx: Tx, /// Where the tx is stored within the block file. pub data_pos: u32, /// Where the tx's undo data is stored within the block's undo file. pub undo_pos: u32, } /// CTransaction, in a block or in the mempool. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Tx { /// TxId of the tx. pub txid: [u8; 32], /// nVersion of the tx. pub version: i32, /// Tx inputs. pub inputs: Vec, /// Tx outputs. pub outputs: Vec, /// Locktime of the tx. pub locktime: u32, } /// COutPoint, pointing to a coin being spent. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct OutPoint { /// TxId of the output of the coin. pub txid: [u8; 32], /// Index in the outputs of the tx of the coin. pub out_idx: u32, } /// CTxIn, spending an unspent output. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct TxInput { /// Points to an output being spent. pub prev_out: OutPoint, /// scriptSig unlocking the output. pub script: Vec, /// nSequence. pub sequence: u32, /// Coin being spent by this tx. pub coin: Coin, } /// CTxOut, creating a new output. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct TxOutput { /// Value of the output. pub value: i64, /// Script locking the output. pub script: Vec, } /// Coin, can be spent by providing a valid unlocking script. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Coin { /// Output, locking the coins. pub output: TxOutput, /// Height of the coin in the chain. pub height: i32, /// Whether the coin is a coinbase. pub is_coinbase: bool, } #[allow(missing_debug_implementations)] unsafe extern "C++" { include!("blockindex.h"); include!("chronik-cpp/chronik_bridge.h"); include!("coins.h"); include!("node/context.h"); include!("primitives/block.h"); include!("primitives/transaction.h"); /// node::NodeContext from node/context.h #[namespace = "node"] type NodeContext; /// ::CBlockIndex from blockindex.h #[namespace = ""] type CBlockIndex; /// ::CBlock from primitives/block.h #[namespace = ""] type CBlock; /// ::Coin from coins.h (renamed to CCoin to prevent a name clash) #[namespace = ""] #[cxx_name = "Coin"] type CCoin; /// ::Config from config.h #[namespace = ""] type Config; /// ::CTransaction from primitives/transaction.h #[namespace = ""] type CTransaction; /// Bridge to bitcoind to access the node type ChronikBridge; /// Print the message to bitcoind's logs. fn log_print( logging_function: &str, source_file: &str, source_line: u32, msg: &str, ); /// Print the message to bitcoind's logs under the BCLog::Chronik /// category. fn log_print_chronik( logging_function: &str, source_file: &str, source_line: u32, msg: &str, ); /// Make the bridge given the NodeContext fn make_bridge( config: &Config, node: &NodeContext, ) -> UniquePtr; /// Return the tip of the chain of the node. /// Returns hash=000...000, height=-1 if there's no block on the chain. fn get_chain_tip(self: &ChronikBridge) -> Result<&CBlockIndex>; /// Lookup the block index with the given hash, or throw an error /// if it couldn't be found. fn lookup_block_index( self: &ChronikBridge, hash: [u8; 32], ) -> Result<&CBlockIndex>; /// Load the CBlock data of this CBlockIndex from the disk fn load_block( self: &ChronikBridge, block_index: &CBlockIndex, ) -> Result>; /// Find at which block the given block_index forks off from the node. fn find_fork( self: &ChronikBridge, block_index: &CBlockIndex, ) -> Result<&CBlockIndex>; /// Lookup the spent coins of a tx and fill them in in-place. /// - `not_found` will be the outpoints that couldn't be found in the /// node or the DB. /// - `coins_to_uncache` will be the outpoints that need to be uncached /// if the tx doesn't end up being broadcast. This is so that clients /// can't fill our cache with useless old coins. It mirrors the /// behavior of `MemPoolAccept::PreChecks`, which uncaches the queried /// coins if they don't end up being spent. fn lookup_spent_coins( self: &ChronikBridge, tx: &mut Tx, not_found: &mut Vec, coins_to_uncache: &mut Vec, ) -> Result<()>; /// Remove the coins from the coin cache. /// This must be done after a call to `lookup_spent_coins` where the tx /// wasn't broadcast, to avoid clients filling our cache with unneeded /// coins. fn uncache_coins( self: &ChronikBridge, coins: &[OutPoint], ) -> Result<()>; /// Add the given tx to the mempool, and if that succeeds, broadcast it /// to all our peers. /// Also check the actual tx fee doesn't exceed max_fee. /// Note max_fee is absolute, not a fee rate (as in sendrawtransaction). fn broadcast_tx( self: &ChronikBridge, raw_tx: &[u8], max_fee: i64, ) -> Result<[u8; 32]>; /// Bridge CTransaction -> ffi::Tx, using the given spent coins. fn bridge_tx( tx: &CTransaction, spent_coins: &CxxVector, ) -> Result; /// Bridge bitcoind's classes to the shared struct [`Block`]. fn bridge_block( block: &CBlock, block_index: &CBlockIndex, ) -> Result; /// Load the CTransaction and CTxUndo data from disk and turn it into a /// bridged Tx, containing spent coins etc. fn load_tx(file_num: u32, data_pos: u32, undo_pos: u32) -> Result; /// Load the CTransaction from disk and serialize it. fn load_raw_tx(file_num: u32, data_pos: u32) -> Result>; /// Get a BlockInfo for this CBlockIndex. fn get_block_info(block_index: &CBlockIndex) -> BlockInfo; /// CBlockIndex::GetAncestor fn get_block_ancestor( block_index: &CBlockIndex, height: i32, ) -> Result<&CBlockIndex>; /// Compress the given script using `ScriptCompression`. fn compress_script(script: &[u8]) -> Vec; /// Decompress the given script using `ScriptCompression`. fn decompress_script(compressed: &[u8]) -> Result>; /// Calc the fee in satoshis for the given tx size in bytes. fn calc_fee(num_bytes: usize, sats_fee_per_kb: i64) -> i64; /// Default maximum fee rate when broadcasting txs. fn default_max_raw_tx_fee_rate_per_kb() -> i64; + /// Calls `SyncWithValidationInterfaceQueue` from validationinterface.h + /// to make sure wallet/indexes are synced. + fn sync_with_validation_interface_queue(); + /// Calls `InitError` from `node/ui_interface.h` to report an error to /// the user and then gracefully shut down the node. fn init_error(msg: &str) -> bool; /// Calls `AbortNode` from shutdown.h to gracefully shut down the node /// when an unrecoverable error occured. fn abort_node(msg: &str, user_msg: &str); /// Returns true if a shutdown is requested, false otherwise. /// See `ShutdownRequested` in `shutdown.h`. fn shutdown_requested() -> bool; } } /// SAFETY: All fields of ChronikBridge (const Consensus::Params &, const /// node::NodeContext &) can be moved betweed threads safely. #[allow(unsafe_code)] unsafe impl Send for ChronikBridge {} /// SAFETY: All fields of ChronikBridge (const Consensus::Params &, const /// node::NodeContext &) can be accessed from different threads safely. #[allow(unsafe_code)] unsafe impl Sync for ChronikBridge {} impl std::fmt::Debug for ChronikBridge { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ChronikBridge").finish_non_exhaustive() } } diff --git a/chronik/chronik-cpp/chronik_bridge.cpp b/chronik/chronik-cpp/chronik_bridge.cpp index 0d4aa24e1..59d8d9769 100644 --- a/chronik/chronik-cpp/chronik_bridge.cpp +++ b/chronik/chronik-cpp/chronik_bridge.cpp @@ -1,376 +1,381 @@ // Copyright (c) 2022 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include chronik_bridge::OutPoint BridgeOutPoint(const COutPoint &outpoint) { return { .txid = chronik::util::HashToArray(outpoint.GetTxId()), .out_idx = outpoint.GetN(), }; } chronik_bridge::TxOutput BridgeTxOutput(const CTxOut &output) { return { .value = output.nValue / Amount::satoshi(), .script = chronik::util::ToRustVec(output.scriptPubKey), }; } chronik_bridge::Coin BridgeCoin(const Coin &coin) { const int32_t nHeight = coin.GetHeight() == 0x7fff'ffff ? -1 : coin.GetHeight(); return { .output = BridgeTxOutput(coin.GetTxOut()), .height = nHeight, .is_coinbase = coin.IsCoinBase(), }; } rust::Vec BridgeTxInputs(bool isCoinbase, const std::vector &inputs, const std::vector &spent_coins) { rust::Vec bridged_inputs; bridged_inputs.reserve(inputs.size()); for (size_t idx = 0; idx < inputs.size(); ++idx) { const CTxIn &input = inputs[idx]; chronik_bridge::Coin bridge_coin{}; // empty coin if (!isCoinbase) { if (idx >= spent_coins.size()) { throw std::runtime_error("Missing coin for input"); } bridge_coin = BridgeCoin(spent_coins[idx]); } bridged_inputs.push_back({ .prev_out = BridgeOutPoint(input.prevout), .script = chronik::util::ToRustVec(input.scriptSig), .sequence = input.nSequence, .coin = std::move(bridge_coin), }); } return bridged_inputs; } rust::Vec BridgeTxOutputs(const std::vector &outputs) { rust::Vec bridged_outputs; bridged_outputs.reserve(outputs.size()); for (const CTxOut &output : outputs) { bridged_outputs.push_back(BridgeTxOutput(output)); } return bridged_outputs; } chronik_bridge::Tx BridgeTx(bool isCoinbase, const CTransaction &tx, const std::vector &spent_coins) { return { .txid = chronik::util::HashToArray(tx.GetId()), .version = tx.nVersion, .inputs = BridgeTxInputs(isCoinbase, tx.vin, spent_coins), .outputs = BridgeTxOutputs(tx.vout), .locktime = tx.nLockTime, }; } chronik_bridge::BlockTx BridgeBlockTx(bool isCoinbase, const CTransaction &tx, const std::vector &spent_coins, size_t data_pos, size_t undo_pos) { return {.tx = BridgeTx(isCoinbase, tx, spent_coins), .data_pos = uint32_t(data_pos), .undo_pos = uint32_t(isCoinbase ? 0 : undo_pos)}; } size_t GetFirstBlockTxOffset(const CBlock &block, const CBlockIndex &bindex) { return bindex.nDataPos + ::GetSerializeSize(CBlockHeader()) + GetSizeOfCompactSize(block.vtx.size()); } size_t GetFirstUndoOffset(const CBlock &block, const CBlockIndex &bindex) { // We have to -1 here, because coinbase txs don't have undo data. return bindex.nUndoPos + GetSizeOfCompactSize(block.vtx.size() - 1); } chronik_bridge::Block BridgeBlock(const CBlock &block, const CBlockIndex &bindex) { size_t data_pos = GetFirstBlockTxOffset(block, bindex); size_t undo_pos = 0; CBlockUndo block_undo; // Read undo data (genesis block doesn't have undo data) if (bindex.nHeight > 0) { undo_pos = GetFirstUndoOffset(block, bindex); if (!node::UndoReadFromDisk(block_undo, &bindex)) { throw std::runtime_error("Reading block undo data failed"); } } rust::Vec bridged_txs; for (size_t tx_idx = 0; tx_idx < block.vtx.size(); ++tx_idx) { const bool isCoinbase = tx_idx == 0; const CTransaction &tx = *block.vtx[tx_idx]; if (!isCoinbase && tx_idx - 1 >= block_undo.vtxundo.size()) { throw std::runtime_error("Missing undo data for tx"); } const std::vector &spent_coins = isCoinbase ? std::vector() : block_undo.vtxundo[tx_idx - 1].vprevout; bridged_txs.push_back( BridgeBlockTx(isCoinbase, tx, spent_coins, data_pos, undo_pos)); // advance data_pos and undo_pos positions data_pos += ::GetSerializeSize(tx); if (!isCoinbase) { undo_pos += ::GetSerializeSize(block_undo.vtxundo[tx_idx - 1]); } } return {.hash = chronik::util::HashToArray(block.GetHash()), .prev_hash = chronik::util::HashToArray(block.hashPrevBlock), .n_bits = block.nBits, .timestamp = block.GetBlockTime(), .height = bindex.nHeight, .file_num = uint32_t(bindex.nFile), .data_pos = bindex.nDataPos, .undo_pos = bindex.nUndoPos, .size = ::GetSerializeSize(block), .txs = bridged_txs}; } namespace chronik_bridge { void log_print(const rust::Str logging_function, const rust::Str source_file, const uint32_t source_line, const rust::Str msg) { LogInstance().LogPrintStr(std::string(msg), std::string(logging_function), std::string(source_file), source_line); } void log_print_chronik(const rust::Str logging_function, const rust::Str source_file, const uint32_t source_line, const rust::Str msg) { if (LogInstance().WillLogCategory(BCLog::CHRONIK)) { log_print(logging_function, source_file, source_line, msg); } } const CBlockIndex &ChronikBridge::get_chain_tip() const { const CBlockIndex *tip = WITH_LOCK(cs_main, return m_node.chainman->ActiveTip()); if (tip == nullptr) { throw block_index_not_found(); } return *tip; } const CBlockIndex & ChronikBridge::lookup_block_index(std::array hash) const { BlockHash block_hash{chronik::util::ArrayToHash(hash)}; const CBlockIndex *pindex = WITH_LOCK( cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(block_hash)); if (!pindex) { throw block_index_not_found(); } return *pindex; } std::unique_ptr ChronikBridge::load_block(const CBlockIndex &bindex) const { CBlock block; if (!node::ReadBlockFromDisk(block, &bindex, m_consensus)) { throw std::runtime_error("Reading block data failed"); } return std::make_unique(std::move(block)); } Tx bridge_tx(const CTransaction &tx, const std::vector<::Coin> &spent_coins) { return BridgeTx(false, tx, spent_coins); } const CBlockIndex &ChronikBridge::find_fork(const CBlockIndex &index) const { const CBlockIndex *fork = WITH_LOCK( cs_main, return m_node.chainman->ActiveChainstate().m_chain.FindFork(&index)); if (!fork) { throw block_index_not_found(); } return *fork; } void ChronikBridge::lookup_spent_coins( Tx &tx, rust::Vec ¬_found, rust::Vec &coins_to_uncache) const { not_found.clear(); coins_to_uncache.clear(); LOCK(cs_main); CCoinsViewCache &coins_cache = m_node.chainman->ActiveChainstate().CoinsTip(); CCoinsViewMemPool coin_view(&coins_cache, *m_node.mempool); for (TxInput &input : tx.inputs) { TxId txid = TxId(chronik::util::ArrayToHash(input.prev_out.txid)); COutPoint outpoint = COutPoint(txid, input.prev_out.out_idx); // Remember if coin was already cached const bool had_cached = coins_cache.HaveCoinInCache(outpoint); ::Coin coin; if (!coin_view.GetCoin(outpoint, coin)) { not_found.push_back(input.prev_out); continue; } if (!had_cached) { // Only add if previously uncached. // We don't check if the prev_out is now cached (which wouldn't be // the case for a mempool UTXO), as uncaching an outpoint is cheap, // so we save one extra cache lookup here. coins_to_uncache.push_back(input.prev_out); } input.coin = BridgeCoin(coin); } } void ChronikBridge::uncache_coins( rust::Slice coins_to_uncache) const { LOCK(cs_main); CCoinsViewCache &coins_cache = m_node.chainman->ActiveChainstate().CoinsTip(); for (const OutPoint &outpoint : coins_to_uncache) { TxId txid = TxId(chronik::util::ArrayToHash(outpoint.txid)); coins_cache.Uncache(COutPoint(txid, outpoint.out_idx)); } } std::array ChronikBridge::broadcast_tx(rust::Slice raw_tx, int64_t max_fee) const { std::vector vec = chronik::util::FromRustSlice(raw_tx); CDataStream stream{vec, SER_NETWORK, PROTOCOL_VERSION}; CMutableTransaction tx; stream >> tx; CTransactionRef tx_ref = MakeTransactionRef(tx); std::string err_str; TransactionError error = node::BroadcastTransaction( m_node, tx_ref, err_str, max_fee * Amount::satoshi(), /*relay=*/true, /*wait_callback=*/false); if (error != TransactionError::OK) { bilingual_str txErrorMsg = TransactionErrorString(error); if (err_str.empty()) { throw std::runtime_error(txErrorMsg.original.c_str()); } else { std::string msg = strprintf("%s: %s", txErrorMsg.original, err_str); throw std::runtime_error(msg.c_str()); } } return chronik::util::HashToArray(tx_ref->GetId()); } std::unique_ptr make_bridge(const Config &config, const node::NodeContext &node) { return std::make_unique( config.GetChainParams().GetConsensus(), node); } chronik_bridge::Block bridge_block(const CBlock &block, const CBlockIndex &bindex) { return BridgeBlock(block, bindex); } Tx load_tx(uint32_t file_num, uint32_t data_pos, uint32_t undo_pos) { CMutableTransaction tx; CTxUndo txundo{}; const bool isCoinbase = undo_pos == 0; if (!node::ReadTxFromDisk(tx, FlatFilePos(file_num, data_pos))) { throw std::runtime_error("Reading tx data from disk failed"); } if (!isCoinbase) { if (!node::ReadTxUndoFromDisk(txundo, FlatFilePos(file_num, undo_pos))) { throw std::runtime_error("Reading tx undo data from disk failed"); } } return BridgeTx(isCoinbase, CTransaction(std::move(tx)), txundo.vprevout); } rust::Vec load_raw_tx(uint32_t file_num, uint32_t data_pos) { CMutableTransaction tx; if (!node::ReadTxFromDisk(tx, FlatFilePos(file_num, data_pos))) { throw std::runtime_error("Reading tx data from disk failed"); } CDataStream raw_tx{SER_NETWORK, PROTOCOL_VERSION}; raw_tx << tx; return chronik::util::ToRustVec(raw_tx); } BlockInfo get_block_info(const CBlockIndex &bindex) { return { .hash = chronik::util::HashToArray(bindex.GetBlockHash()), .height = bindex.nHeight, }; } const CBlockIndex &get_block_ancestor(const CBlockIndex &index, int32_t height) { const CBlockIndex *pindex = index.GetAncestor(height); if (!pindex) { throw block_index_not_found(); } return *pindex; } rust::Vec compress_script(rust::Slice bytecode) { std::vector vec = chronik::util::FromRustSlice(bytecode); CScript script{vec.begin(), vec.end()}; CDataStream compressed{SER_NETWORK, PROTOCOL_VERSION}; compressed << Using(script); return chronik::util::ToRustVec(compressed); } rust::Vec decompress_script(rust::Slice compressed) { std::vector vec = chronik::util::FromRustSlice(compressed); CDataStream stream{vec, SER_NETWORK, PROTOCOL_VERSION}; CScript script; stream >> Using(script); return chronik::util::ToRustVec(script); } int64_t calc_fee(size_t num_bytes, int64_t sats_fee_per_kb) { return CFeeRate(sats_fee_per_kb * SATOSHI).GetFee(num_bytes) / SATOSHI; } int64_t default_max_raw_tx_fee_rate_per_kb() { return node::DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK() / SATOSHI; } +void sync_with_validation_interface_queue() { + SyncWithValidationInterfaceQueue(); +} + bool init_error(const rust::Str msg) { return InitError(Untranslated(std::string(msg))); } void abort_node(const rust::Str msg, const rust::Str user_msg) { AbortNode(std::string(msg), Untranslated(std::string(user_msg))); } bool shutdown_requested() { return ShutdownRequested(); } } // namespace chronik_bridge diff --git a/chronik/chronik-cpp/chronik_bridge.h b/chronik/chronik-cpp/chronik_bridge.h index 68cbf8f11..b4431a837 100644 --- a/chronik/chronik-cpp/chronik_bridge.h +++ b/chronik/chronik-cpp/chronik_bridge.h @@ -1,106 +1,108 @@ // Copyright (c) 2022 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CHRONIK_CPP_CHRONIK_BRIDGE_H #define BITCOIN_CHRONIK_CPP_CHRONIK_BRIDGE_H #include #include #include class CBlock; class CBlockIndex; class Coin; class Config; class CTransaction; namespace Consensus { struct Params; } // namespace Consensus namespace node { struct NodeContext; } // namespace node class uint256; namespace chronik_bridge { struct BlockInfo; struct Block; struct Tx; struct OutPoint; class block_index_not_found : public std::exception { public: const char *what() const noexcept override { return "CBlockIndex not found"; } }; void log_print(const rust::Str logging_function, const rust::Str source_file, const uint32_t source_line, const rust::Str msg); void log_print_chronik(const rust::Str logging_function, const rust::Str source_file, const uint32_t source_line, const rust::Str msg); /** * Bridge to bitcoind to access the node. */ class ChronikBridge { const Consensus::Params &m_consensus; const node::NodeContext &m_node; public: ChronikBridge(const Consensus::Params &consensus, const node::NodeContext &node) : m_consensus(consensus), m_node(node) {} const CBlockIndex &get_chain_tip() const; const CBlockIndex &lookup_block_index(std::array hash) const; std::unique_ptr load_block(const CBlockIndex &bindex) const; const CBlockIndex &find_fork(const CBlockIndex &index) const; void lookup_spent_coins(Tx &, rust::Vec ¬_found, rust::Vec &coins_to_uncache) const; void uncache_coins(rust::Slice) const; std::array broadcast_tx(rust::Slice raw_tx, int64_t max_fee) const; }; std::unique_ptr make_bridge(const Config &config, const node::NodeContext &node); Tx bridge_tx(const CTransaction &tx, const std::vector &spent_coins); Block bridge_block(const CBlock &block, const CBlockIndex &bindex); Tx load_tx(uint32_t file_num, uint32_t data_pos, uint32_t undo_pos); rust::Vec load_raw_tx(uint32_t file_num, uint32_t data_pos); BlockInfo get_block_info(const CBlockIndex &index); const CBlockIndex &get_block_ancestor(const CBlockIndex &index, int32_t height); rust::Vec compress_script(rust::Slice script); rust::Vec decompress_script(rust::Slice compressed); int64_t calc_fee(size_t num_bytes, int64_t sats_fee_per_kb); int64_t default_max_raw_tx_fee_rate_per_kb(); +void sync_with_validation_interface_queue(); + bool init_error(const rust::Str msg); void abort_node(const rust::Str msg, const rust::Str user_msg); bool shutdown_requested(); } // namespace chronik_bridge #endif // BITCOIN_CHRONIK_CPP_CHRONIK_BRIDGE_H diff --git a/chronik/chronik-http/Cargo.toml b/chronik/chronik-http/Cargo.toml index a30e9beec..fffce8e3f 100644 --- a/chronik/chronik-http/Cargo.toml +++ b/chronik/chronik-http/Cargo.toml @@ -1,55 +1,56 @@ # Copyright (c) 2022 The Bitcoin developers [package] name = "chronik-http" version = "0.1.0" edition = "2021" rust-version.workspace = true license = "MIT" [dependencies] abc-rust-error = { path = "../abc-rust-error" } abc-rust-lint = { path = "../abc-rust-lint" } bitcoinsuite-core = { path = "../bitcoinsuite-core" } bitcoinsuite-slp = { path = "../bitcoinsuite-slp" } +chronik-bridge = { path = "../chronik-bridge" } chronik-db = { path = "../chronik-db" } chronik-indexer = { path = "../chronik-indexer" } chronik-proto = { path = "../chronik-proto" } chronik-util = { path = "../chronik-util" } # Allow traits to use async functions async-trait = "0.1" # HTTP webapps axum = { version = "0.7", features = ["ws"] } # Async toolkit futures = "0.3" # En-/decode hex hex = "0.4" # HTTP types http = "1.0" # Helpers for dealing with the http 1.0 Body type http-body-util = "0.1" # HTTP implementation hyper = "1.1" # Protobuf en-/decoding prost = "0.11" # Derive error enums thiserror = "1.0" # Trait representing an asynchronous server. tower-service = "0.3" # Async runtime [dependencies.tokio] version = "1.25" features = ["sync", "rt", "rt-multi-thread", "macros"] diff --git a/chronik/chronik-http/src/server.rs b/chronik/chronik-http/src/server.rs index 13476ab3a..b1f3cd4eb 100644 --- a/chronik/chronik-http/src/server.rs +++ b/chronik/chronik-http/src/server.rs @@ -1,479 +1,492 @@ // Copyright (c) 2022 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. //! Module for [`ChronikServer`]. use std::collections::HashMap; use std::time::Duration; use std::{net::SocketAddr, sync::Arc}; use abc_rust_error::{Result, WrapErr}; use axum::{ extract::{Path, Query, WebSocketUpgrade}, response::IntoResponse, routing::{self, MethodFilter}, Extension, Router, }; use bitcoinsuite_core::tx::TxId; +use chronik_bridge::ffi; use chronik_indexer::{ indexer::{ChronikIndexer, Node}, pause::PauseNotify, }; use chronik_proto::proto; use thiserror::Error; use tokio::sync::RwLock; use crate::{ error::ReportError, handlers, protobuf::Protobuf, ws::handle_subscribe_socket, }; /// Ref-counted indexer with read or write access pub type ChronikIndexerRef = Arc>; /// Ref-counted access to the bitcoind node pub type NodeRef = Arc; /// Ref-counted pause notifier for Chronik indexing pub type PauseNotifyRef = Arc; /// Settings to tune Chronik #[derive(Clone, Debug)] pub struct ChronikSettings { /// Duration between WebSocket pings initiated by Chronik. pub ws_ping_interval: Duration, } /// Params defining what and where to serve for [`ChronikServer`]. #[derive(Clone, Debug)] pub struct ChronikServerParams { /// Host address (port + IP) where to serve Chronik at. pub hosts: Vec, /// Indexer to read data from pub indexer: ChronikIndexerRef, /// Access to the bitcoind node pub node: NodeRef, /// Handle for pausing/resuming indexing any updates from the node pub pause_notify: PauseNotifyRef, /// Settings to tune Chronik pub settings: ChronikSettings, } /// Chronik HTTP server, holding all the data/handles required to serve an /// instance. #[derive(Debug)] pub struct ChronikServer { tcp_listeners: Vec, indexer: ChronikIndexerRef, node: NodeRef, pause_notify: PauseNotifyRef, settings: ChronikSettings, } /// Errors for [`ChronikServer`]. #[derive(Debug, Eq, Error, PartialEq)] pub enum ChronikServerError { /// Binding to host address failed #[error("Chronik failed binding to {0}: {1}")] FailedBindingAddress(SocketAddr, String), /// Serving Chronik failed #[error("Chronik failed serving: {0}")] ServingFailed(String), /// Query is neither a hex hash nor an integer string #[error("400: Not a hash or height: {0}")] NotHashOrHeight(String), /// Query is not a txid #[error("400: Not a txid: {0}")] NotTxId(String), /// Block not found in DB #[error("404: Block not found: {0}")] BlockNotFound(String), } use self::ChronikServerError::*; impl ChronikServer { /// Binds the Chronik server on the given hosts pub fn setup(params: ChronikServerParams) -> Result { let tcp_listeners = params .hosts .into_iter() .map(|host| -> Result<_> { let tcp = std::net::TcpListener::bind(host).map_err(|err| { FailedBindingAddress(host, err.to_string()) })?; // Important: We need to set non-blocking ourselves tcp.set_nonblocking(true)?; Ok(tokio::net::TcpListener::from_std(tcp)?) }) .collect::>>()?; Ok(ChronikServer { tcp_listeners, indexer: params.indexer, node: params.node, pause_notify: params.pause_notify, settings: params.settings, }) } /// Serve a Chronik HTTP endpoint with the given parameters. pub async fn serve(self) -> Result<()> { let app = Self::make_router( self.indexer, self.node, self.pause_notify, self.settings, ); let servers = self .tcp_listeners .into_iter() .zip(std::iter::repeat(app)) .map(|(tcp_listener, app)| { Box::pin(async move { axum::serve(tcp_listener, app.into_make_service()) .await .map_err(|err| ServingFailed(err.to_string())) }) }); let (result, _, _) = futures::future::select_all(servers).await; result?; Ok(()) } fn make_router( indexer: ChronikIndexerRef, node: NodeRef, pause_notify: PauseNotifyRef, settings: ChronikSettings, ) -> Router { Router::new() .route("/blockchain-info", routing::get(handle_blockchain_info)) .route("/block/:hash_or_height", routing::get(handle_block)) .route("/block-txs/:hash_or_height", routing::get(handle_block_txs)) .route("/blocks/:start/:end", routing::get(handle_block_range)) .route("/chronik-info", routing::get(handle_chronik_info)) .route("/tx/:txid", routing::get(handle_tx)) .route("/token/:txid", routing::get(handle_token_info)) .route( "/validate-tx", routing::post(handle_validate_tx) .on(MethodFilter::OPTIONS, handle_post_options), ) .route( "/broadcast-tx", routing::post(handle_broadcast_tx) .on(MethodFilter::OPTIONS, handle_post_options), ) .route( "/broadcast-txs", routing::post(handle_broadcast_txs) .on(MethodFilter::OPTIONS, handle_post_options), ) .route("/raw-tx/:txid", routing::get(handle_raw_tx)) .route( "/script/:type/:payload/confirmed-txs", routing::get(handle_script_confirmed_txs), ) .route( "/script/:type/:payload/history", routing::get(handle_script_history), ) .route( "/script/:type/:payload/unconfirmed-txs", routing::get(handle_script_unconfirmed_txs), ) .route( "/script/:type/:payload/utxos", routing::get(handle_script_utxos), ) .route( "/token-id/:token_id/confirmed-txs", routing::get(handle_token_id_confirmed_txs), ) .route( "/token-id/:token_id/history", routing::get(handle_token_id_history), ) .route( "/token-id/:token_id/unconfirmed-txs", routing::get(handle_token_id_unconfirmed_txs), ) .route( "/token-id/:token_id/utxos", routing::get(handle_token_id_utxos), ) .route("/ws", routing::get(handle_ws)) .route("/pause", routing::get(handle_pause)) .route("/resume", routing::get(handle_resume)) .fallback(handlers::handle_not_found) .layer(Extension(indexer)) .layer(Extension(node)) .layer(Extension(pause_notify)) .layer(Extension(settings)) } } async fn handle_blockchain_info( Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; let blocks = indexer.blocks(); Ok(Protobuf(blocks.blockchain_info()?)) } async fn handle_chronik_info( ) -> Result, ReportError> { let this_chronik_version: String = env!("CARGO_PKG_VERSION").to_string(); let chronik_info = proto::ChronikInfo { version: this_chronik_version, }; Ok(Protobuf(chronik_info)) } async fn handle_block_range( Path((start_height, end_height)): Path<(i32, i32)>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; let blocks = indexer.blocks(); Ok(Protobuf(blocks.by_range(start_height, end_height)?)) } async fn handle_block( Path(hash_or_height): Path, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; let blocks = indexer.blocks(); Ok(Protobuf(blocks.by_hash_or_height(hash_or_height)?)) } async fn handle_block_txs( Path(hash_or_height): Path, Query(query_params): Query>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_block_txs(hash_or_height, &query_params, &indexer) .await?, )) } async fn handle_tx( Path(txid): Path, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; let txid = txid.parse::().wrap_err(NotTxId(txid))?; Ok(Protobuf(indexer.txs().tx_by_id(txid)?)) } async fn handle_token_info( Path(txid): Path, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; let txid = txid.parse::().wrap_err(NotTxId(txid))?; Ok(Protobuf(indexer.txs().token_info(&txid)?)) } async fn handle_broadcast_tx( Extension(indexer): Extension, Extension(node): Extension, Protobuf(request): Protobuf, ) -> Result, ReportError> { let indexer = indexer.read().await; - let txids = indexer + let txids_result = indexer .broadcast(node.as_ref()) - .broadcast_txs(&[request.raw_tx.into()], request.skip_token_checks)?; + .broadcast_txs(&[request.raw_tx.into()], request.skip_token_checks); + // Drop indexer before syncing otherwise we get a deadlock + drop(indexer); + // Block for indexer being synced before returning so the user can query + // the broadcast txs right away + ffi::sync_with_validation_interface_queue(); + let txids = txids_result?; Ok(Protobuf(proto::BroadcastTxResponse { txid: txids[0].to_vec(), })) } async fn handle_broadcast_txs( Extension(indexer): Extension, Extension(node): Extension, Protobuf(request): Protobuf, ) -> Result, ReportError> { let indexer = indexer.read().await; - let txids = indexer.broadcast(node.as_ref()).broadcast_txs( + let txids_result = indexer.broadcast(node.as_ref()).broadcast_txs( &request .raw_txs .into_iter() .map(Into::into) .collect::>(), request.skip_token_checks, - )?; + ); + // Drop indexer before syncing otherwise we get a deadlock + drop(indexer); + // Block for indexer being synced before returning so the user can query + // the broadcast txs right away + ffi::sync_with_validation_interface_queue(); + let txids = txids_result?; Ok(Protobuf(proto::BroadcastTxsResponse { txids: txids.into_iter().map(|txid| txid.to_vec()).collect(), })) } async fn handle_validate_tx( Extension(indexer): Extension, Extension(node): Extension, Protobuf(raw_tx): Protobuf, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( indexer .broadcast(node.as_ref()) .validate_tx(raw_tx.raw_tx)?, )) } async fn handle_raw_tx( Path(txid): Path, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; let txid = txid.parse::().wrap_err(NotTxId(txid))?; Ok(Protobuf(indexer.txs().raw_tx_by_id(&txid)?)) } async fn handle_script_confirmed_txs( Path((script_type, payload)): Path<(String, String)>, Query(query_params): Query>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_script_confirmed_txs( &script_type, &payload, &query_params, &indexer, ) .await?, )) } async fn handle_script_history( Path((script_type, payload)): Path<(String, String)>, Query(query_params): Query>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_script_history( &script_type, &payload, &query_params, &indexer, ) .await?, )) } async fn handle_script_unconfirmed_txs( Path((script_type, payload)): Path<(String, String)>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_script_unconfirmed_txs( &script_type, &payload, &indexer, ) .await?, )) } async fn handle_script_utxos( Path((script_type, payload)): Path<(String, String)>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_script_utxos(&script_type, &payload, &indexer).await?, )) } async fn handle_token_id_confirmed_txs( Path(token_id_hex): Path, Query(query_params): Query>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_token_id_confirmed_txs( &token_id_hex, &query_params, &indexer, ) .await?, )) } async fn handle_token_id_history( Path(token_id_hex): Path, Query(query_params): Query>, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_token_id_history( &token_id_hex, &query_params, &indexer, ) .await?, )) } async fn handle_token_id_unconfirmed_txs( Path(token_id_hex): Path, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_token_id_unconfirmed_txs(&token_id_hex, &indexer) .await?, )) } async fn handle_token_id_utxos( Path(token_id_hex): Path, Extension(indexer): Extension, ) -> Result, ReportError> { let indexer = indexer.read().await; Ok(Protobuf( handlers::handle_token_id_utxos(&token_id_hex, &indexer).await?, )) } async fn handle_pause( Extension(pause_notify): Extension, ) -> Result, ReportError> { pause_notify.pause()?; Ok(Protobuf(proto::Empty {})) } async fn handle_resume( Extension(pause_notify): Extension, ) -> Result, ReportError> { pause_notify.resume()?; Ok(Protobuf(proto::Empty {})) } async fn handle_ws( ws: WebSocketUpgrade, Extension(indexer): Extension, Extension(settings): Extension, ) -> impl IntoResponse { ws.on_upgrade(|ws| handle_subscribe_socket(ws, indexer, settings)) } async fn handle_post_options( ) -> Result, ReportError> { axum::http::Response::builder() .header("Allow", "OPTIONS, HEAD, POST") .body(axum::body::Body::empty()) .map_err(|err| ReportError(err.into())) }