diff --git a/da-indexer/Cargo.lock b/da-indexer/Cargo.lock index 1f9b00088..816a8c88f 100644 --- a/da-indexer/Cargo.lock +++ b/da-indexer/Cargo.lock @@ -116,7 +116,7 @@ dependencies = [ "prettyplease 0.2.20", "proc-macro2", "prost-build 0.11.9", - "prost-reflect", + "prost-reflect 0.12.0", "quote", "serde", "serde_yaml", @@ -960,14 +960,17 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "beef" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -dependencies = [ - "serde", -] [[package]] name = "bigdecimal" @@ -1142,13 +1145,12 @@ dependencies = [ [[package]] name = "blockstore" -version = "0.1.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bff157a9c999bf0a39ca45e0b62076aa27135012cfbf9cc54ad1cf971876f0" +checksum = "7679095248a6dc7555fae81154ed1baef264383c16621ef881a219576c72a9be" dependencies = [ - "async-trait", "cid", - "dashmap", + "dashmap 6.1.0", "multihash", "thiserror", ] @@ -1170,7 +1172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.72", @@ -1331,27 +1333,28 @@ dependencies = [ [[package]] name = "celestia-proto" -version = "0.1.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d93904482a787d8caecb3a348788704fa044df6fb2402f28da5b91a2a5eabb" +checksum = "0ab6f922c6488623dc5f78e602e0cea658d41c40825033ecbd810a83b73636e1" dependencies = [ - "anyhow", "celestia-tendermint-proto", "prost 0.12.6", "prost-build 0.12.6", "prost-types 0.12.6", + "protox", "serde", ] [[package]] name = "celestia-rpc" -version = "0.1.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c948ab3cd9562d256b752d874d573c836ec8b200bba87d1154bbf662d3a00" +checksum = "677fc8e51b4f53987fcd18bb0f3234ebe938155539cb272d5c771e22ce2ed6d1" dependencies = [ "async-trait", "celestia-types", - "http 0.2.12", + "futures", + "http 1.1.0", "jsonrpsee", "serde", "thiserror", @@ -1360,9 +1363,9 @@ dependencies = [ [[package]] name = "celestia-tendermint" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95f93b5cbbd62b6cfde961889bf05d5fe19e70d8500c4465694306ed2695ac23" +checksum = "ce8c92a01145f79a0f3ac7c44a43a9b5ee58e8a4c716b56d98833a3848db1afd" dependencies = [ "bytes", "celestia-tendermint-proto", @@ -1389,9 +1392,9 @@ dependencies = [ [[package]] name = "celestia-tendermint-proto" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f7d49c1ececa30a4587c5fe8a4035b786b78a3253ed0f9636de591b3dc2b37" +checksum = "9a95746c5221a74d7b913a415fdbb9e7c90e1b4d818dbbff59bddc034cfce2ec" dependencies = [ "bytes", "flex-error", @@ -1407,12 +1410,12 @@ dependencies = [ [[package]] name = "celestia-types" -version = "0.1.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3c4c6698257125b315c04236a28cf5156a866211d336ba6ac70cc5f88e24eb" +checksum = "ab143eba97ed0c957769fa16baecac8e88e479b8d7eae9a71bd084bb2ca80eca" dependencies = [ - "base64 0.21.7", - "bech32", + "base64 0.22.1", + "bech32 0.11.0", "blockstore", "bytes", "celestia-proto", @@ -1421,17 +1424,26 @@ dependencies = [ "cid", "const_format", "enum_dispatch", + "leopard-codec", "libp2p-identity", "multiaddr", "multihash", "nmt-rs", + "prost 0.12.6", "ruint", "serde", "serde_repr", "sha2 0.10.8", "thiserror", + "time", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.0" @@ -1569,7 +1581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ "base64 0.21.7", - "bech32", + "bech32 0.9.1", "bs58", "digest 0.10.7", "generic-array", @@ -1588,6 +1600,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1903,7 +1925,7 @@ dependencies = [ "ethers", "futures", "hex", - "http 0.2.12", + "http 1.1.0", "jsonrpsee", "lazy_static", "pretty_assertions", @@ -2021,6 +2043,20 @@ dependencies = [ "parking_lot_core 0.9.10", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -3318,9 +3354,7 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper 0.14.30", - "log", "rustls 0.21.12", - "rustls-native-certs", "tokio", "tokio-rustls 0.24.1", ] @@ -3335,6 +3369,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.1", "hyper-util", + "log", "rustls 0.23.12", "rustls-pki-types", "tokio", @@ -3602,6 +3637,26 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.32" @@ -3633,9 +3688,9 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +checksum = "c5c71d8c1a731cc4227c2f698d377e7848ca12c8a48866fc5e6951c43a4db843" dependencies = [ "jsonrpsee-core", "jsonrpsee-http-client", @@ -3647,19 +3702,22 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +checksum = "548125b159ba1314104f5bb5f38519e03a41862786aa3925cf349aae9cdd546e" dependencies = [ + "base64 0.22.1", "futures-util", - "http 0.2.12", + "http 1.1.0", "jsonrpsee-core", "pin-project", - "rustls-native-certs", + "rustls 0.23.12", + "rustls-pki-types", + "rustls-platform-verifier", "soketto", "thiserror", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.0", "tokio-util", "tracing", "url", @@ -3667,37 +3725,44 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +checksum = "f2882f6f8acb9fdaec7cefc4fd607119a9bd709831df7d7672a1d3b644628280" dependencies = [ - "anyhow", - "async-lock 2.8.0", "async-trait", - "beef", + "bytes", "futures-timer", "futures-util", - "hyper 0.14.30", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "jsonrpsee-types", + "pin-project", "rustc-hash", "serde", "serde_json", "thiserror", "tokio", + "tokio-stream", "tracing", ] [[package]] name = "jsonrpsee-http-client" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" +checksum = "b3638bc4617f96675973253b3a45006933bde93c2fd8a6170b33c777cc389e5b" dependencies = [ "async-trait", - "hyper 0.14.30", - "hyper-rustls 0.24.2", + "base64 0.22.1", + "http-body 1.0.1", + "hyper 1.4.1", + "hyper-rustls 0.27.2", + "hyper-util", "jsonrpsee-core", "jsonrpsee-types", + "rustls 0.23.12", + "rustls-platform-verifier", "serde", "serde_json", "thiserror", @@ -3709,38 +3774,36 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" +checksum = "c06c01ae0007548e73412c08e2285ffe5d723195bf268bce67b1b77c3bb2a14d" dependencies = [ - "heck 0.4.1", - "proc-macro-crate 1.3.1", + "heck 0.5.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "jsonrpsee-types" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +checksum = "a178c60086f24cc35bb82f57c651d0d25d99c4742b4d335de04e97fa1f08a8a1" dependencies = [ - "anyhow", - "beef", + "http 1.1.0", "serde", "serde_json", "thiserror", - "tracing", ] [[package]] name = "jsonrpsee-ws-client" -version = "0.20.3" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" +checksum = "0fe322e0896d0955a3ebdd5bf813571c53fea29edd713bc315b76620b327e86d" dependencies = [ - "http 0.2.12", + "http 1.1.0", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -3848,6 +3911,17 @@ dependencies = [ "spin 0.9.8", ] +[[package]] +name = "leopard-codec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee58dbc414bd23885d7da915e0457618b36d1fc950a6169ef2cb29829d1b1a1d" +dependencies = [ + "bytes", + "lazy_static", + "thiserror", +] + [[package]] name = "libc" version = "0.2.155" @@ -3950,6 +4024,39 @@ dependencies = [ "value-bag", ] +[[package]] +name = "logos" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax 0.8.4", + "syn 2.0.72", +] + +[[package]] +name = "logos-derive" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" +dependencies = [ + "logos-codegen", +] + [[package]] name = "matchers" version = "0.1.0" @@ -3987,6 +4094,29 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "miette" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317f146e2eb7021892722af37cf1b971f0a70c8406f487e24952667616192c64" +dependencies = [ + "cfg-if", + "miette-derive", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "7.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + [[package]] name = "mime" version = "0.3.17" @@ -4115,11 +4245,13 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nmt-rs" -version = "0.1.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e787133eafbd0f386dc4e26828a50f7595d6d7213ea0e8244c1ca6b9a9648c30" +checksum = "e408e823bdc9b4bb525a61b44e846239833a8f9bd86c03a43e4ca314a5497582" dependencies = [ + "borsh", "bytes", + "serde", "sha2 0.10.8", ] @@ -4242,7 +4374,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.72", @@ -4398,7 +4530,7 @@ checksum = "8b3a2a91fdbfdd4d212c0dcc2ab540de2c2bcbbd90be17de7a7daf8822d010c1" dependencies = [ "async-trait", "crossbeam-channel", - "dashmap", + "dashmap 5.5.3", "fnv", "futures-channel", "futures-executor", @@ -4506,7 +4638,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -4923,16 +5055,6 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -5151,6 +5273,19 @@ dependencies = [ "prost-types 0.12.6", ] +[[package]] +name = "prost-reflect" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5eec97d5d34bdd17ad2db2219aabf46b054c6c41bd5529767c9ce55be5898f" +dependencies = [ + "logos", + "miette", + "once_cell", + "prost 0.12.6", + "prost-types 0.12.6", +] + [[package]] name = "prost-types" version = "0.10.1" @@ -5185,6 +5320,33 @@ version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +[[package]] +name = "protox" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac532509cee918d40f38c3e12f8ef9230f215f017d54de7dd975015538a42ce7" +dependencies = [ + "bytes", + "miette", + "prost 0.12.6", + "prost-reflect 0.13.1", + "prost-types 0.12.6", + "protox-parse", + "thiserror", +] + +[[package]] +name = "protox-parse" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6c33f43516fe397e2f930779d720ca12cd057f7da4cd6326a0ef78d69dee96" +dependencies = [ + "logos", + "miette", + "prost-types 0.12.6", + "thiserror", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -5425,7 +5587,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.4", "winreg 0.50.0", ] @@ -5734,9 +5896,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc-hex" @@ -5819,7 +5981,9 @@ version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ + "log", "once_cell", + "ring 0.17.8", "rustls-pki-types", "rustls-webpki 0.102.6", "subtle", @@ -5838,6 +6002,19 @@ dependencies = [ "security-framework", ] +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.2", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -5859,9 +6036,36 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + +[[package]] +name = "rustls-platform-verifier" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.12", + "rustls-native-certs 0.7.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.102.6", + "security-framework", + "security-framework-sys", + "webpki-roots 0.26.7", + "winapi", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" @@ -5932,7 +6136,7 @@ version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -6164,6 +6368,7 @@ dependencies = [ "core-foundation", "core-foundation-sys", "libc", + "num-bigint", "security-framework-sys", ] @@ -6360,19 +6565,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha1" version = "0.10.6" @@ -6507,17 +6699,17 @@ dependencies = [ [[package]] name = "soketto" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "bytes", "futures", "httparse", "log", "rand", - "sha-1", + "sha1", ] [[package]] @@ -6626,7 +6818,7 @@ dependencies = [ "tracing", "url", "uuid 1.10.0", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] @@ -7197,7 +7389,7 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] @@ -7244,17 +7436,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.3.0", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.21.1" @@ -7301,7 +7482,7 @@ dependencies = [ "pin-project", "prost 0.10.4", "prost-derive 0.10.1", - "rustls-native-certs", + "rustls-native-certs 0.6.3", "rustls-pemfile 1.0.4", "tokio", "tokio-rustls 0.23.4", @@ -7649,6 +7830,12 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -7908,6 +8095,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "4.4.2" diff --git a/da-indexer/da-indexer-logic/Cargo.toml b/da-indexer/da-indexer-logic/Cargo.toml index cb9f03340..c371476c9 100644 --- a/da-indexer/da-indexer-logic/Cargo.toml +++ b/da-indexer/da-indexer-logic/Cargo.toml @@ -17,19 +17,19 @@ sea-orm = { version = "0.12.2", features = [ "postgres-array", ] } -celestia-rpc = "0.1.1" -celestia-types = "0.1.1" +celestia-rpc = "0.7.0" +celestia-types = "0.7.0" tokio = { version = "1", features = ["full"] } hex = "0.4.3" lazy_static = "1.4.0" sha3 = "0.10.8" futures = "0.3" -jsonrpsee = { version = "0.20", features = ["client-core", "macros"] } +jsonrpsee = { version = "0.24.7", features = ["client-core", "macros"] } serde = "1.0" serde_with = "3.6.1" serde_json = "1.0.96" async-trait = "0.1" -http = "0.2.9" +http = "1.1.0" tonic = { version = "0.7", features = ["tls", "tls-roots"] } prost = "0.10" ethabi = "18.0" diff --git a/da-indexer/da-indexer-logic/src/celestia/da.rs b/da-indexer/da-indexer-logic/src/celestia/da.rs index 9a1a73a79..3c72dc494 100644 --- a/da-indexer/da-indexer-logic/src/celestia/da.rs +++ b/da-indexer/da-indexer-logic/src/celestia/da.rs @@ -1,6 +1,11 @@ +use crate::celestia::rpc_client::ShareV2Client; +use crate::{ + celestia::{repository::blobs, rpc_client}, + indexer::{Job, DA}, +}; use anyhow::Result; use async_trait::async_trait; -use celestia_rpc::{Client, HeaderClient, ShareClient}; +use celestia_rpc::{Client, HeaderClient}; use celestia_types::{Blob, ExtendedHeader}; use sea_orm::{DatabaseConnection, TransactionTrait}; use std::sync::{ @@ -8,11 +13,6 @@ use std::sync::{ Arc, }; -use crate::{ - celestia::{repository::blobs, rpc_client}, - indexer::{Job, DA}, -}; - use super::{job::CelestiaJob, parser, repository::blocks, settings::IndexerSettings}; pub struct CelestiaDA { @@ -53,12 +53,16 @@ impl CelestiaDA { } async fn get_blobs_by_height(&self, height: u64) -> Result<(ExtendedHeader, Vec)> { + // TODO: it seems possible to avoid this request with new Celestia API let header = self.client.header_get_by_height(height).await?; - let mut blobs = vec![]; + let mut blobs = vec![]; if parser::maybe_contains_blobs(&header.dah) { - let eds = self.client.share_get_eds(&header).await?; - blobs = parser::parse_eds(&eds, header.dah.square_len())?; + let eds = self + .client + .share_get_eds_v2(height, header.header.version.app) + .await?; + blobs = parser::parse_eds(&eds, header.header.version.app)?; } Ok((header, blobs)) diff --git a/da-indexer/da-indexer-logic/src/celestia/parser.rs b/da-indexer/da-indexer-logic/src/celestia/parser.rs index e6cdf5ccb..23cd0a67f 100644 --- a/da-indexer/da-indexer-logic/src/celestia/parser.rs +++ b/da-indexer/da-indexer-logic/src/celestia/parser.rs @@ -1,7 +1,6 @@ -use anyhow::{Error, Result}; +use anyhow::Result; use celestia_types::{ - blob::Blob, consts::appconsts, nmt::Namespace, Commitment, DataAvailabilityHeader, - ExtendedDataSquare, Share, + blob::Blob, nmt::Namespace, AppVersion, DataAvailabilityHeader, ExtendedDataSquare, }; lazy_static! { @@ -17,81 +16,19 @@ lazy_static! { /// Checks if the DataAvailabilityHeader might contain blobs. pub fn maybe_contains_blobs(dah: &DataAvailabilityHeader) -> bool { - dah.row_roots.iter().any(|row| { + dah.row_roots().iter().any(|row| { *PAY_FOR_BLOB_NAMESPACE >= row.min_namespace().into() && *PAY_FOR_BLOB_NAMESPACE <= row.max_namespace().into() }) } /// Extracts blobs from the ExtendedDataSquare. -/// The format described here: https://github.com/celestiaorg/celestia-app/blob/main/specs/src/specs/shares.md -pub fn parse_eds(eds: &ExtendedDataSquare, width: usize) -> Result> { - // sanity check - if width * width != eds.data_square.len() { - return Err(Error::msg("data square length mismatch")); - } +pub fn parse_eds(eds: &ExtendedDataSquare, app_version: u64) -> Result> { + let app_version = AppVersion::from_u64(app_version) + .ok_or_else(|| anyhow::anyhow!("invalid or unsupported app_version: {app_version}"))?; - let mut blobs: Vec = vec![]; - let mut sequence_length = 0; - let mut parsed_length = 0; - - for row in eds.data_square.chunks(width).take(width / 2) { - for share in row.iter().take(width / 2) { - let share = Share::from_raw(share)?; - let ns = share.namespace(); - - if ns == *TAIL_PADDING_NAMESPACE { - break; - } - - if ns.is_reserved_on_celestia() { - continue; - } - - let info_byte = share.info_byte(); - - let mut share_data; - if info_byte.is_sequence_start() { - assert!(parsed_length == sequence_length); - - sequence_length = share.sequence_length().unwrap() as usize; - parsed_length = 0; - - if sequence_length == 0 - && blobs.last().is_some() - && blobs.last().unwrap().namespace == ns - { - // Namespace Padding Share, should be ignored - continue; - } - - blobs.push(Blob { - namespace: ns, - data: vec![0; sequence_length], - share_version: info_byte.version(), - commitment: Commitment([0; 32]), - }); - - // first share: skip info byte and sequence length - share_data = &share.data()[1 + appconsts::SEQUENCE_LEN_BYTES..]; - } else { - // continuation share: skip info byte - share_data = &share.data()[1..]; - } - - let data_length = share_data.len().min(sequence_length - parsed_length); - share_data = &share_data[..data_length]; - - let last_blob = blobs.last_mut().unwrap(); - last_blob.data[parsed_length..(parsed_length + data_length)] - .copy_from_slice(share_data); - parsed_length += data_length; - - if parsed_length == sequence_length { - last_blob.commitment = - Commitment::from_blob(ns, info_byte.version(), &last_blob.data)?; - } - } - } - Ok(blobs) + Blob::reconstruct_all(eds.data_square(), app_version).map_err(|err| { + tracing::error!("failed to parse EDS: {:?}", err); + anyhow::anyhow!(err) + }) } diff --git a/da-indexer/da-indexer-logic/src/celestia/repository/blobs.rs b/da-indexer/da-indexer-logic/src/celestia/repository/blobs.rs index bd25eaf95..7c5dba101 100644 --- a/da-indexer/da-indexer-logic/src/celestia/repository/blobs.rs +++ b/da-indexer/da-indexer-logic/src/celestia/repository/blobs.rs @@ -49,6 +49,7 @@ pub async fn upsert_many( blobs: Vec, ) -> Result<(), anyhow::Error> { let blobs = blobs.into_iter().map(|blob| { + // TODO: do we need to store blob index? let model = Model { id: compute_id(height, &blob.commitment.0), height: height as i64, diff --git a/da-indexer/da-indexer-logic/src/celestia/rpc_client.rs b/da-indexer/da-indexer-logic/src/celestia/rpc_client.rs index 5268a65cf..b2cbf0a29 100644 --- a/da-indexer/da-indexer-logic/src/celestia/rpc_client.rs +++ b/da-indexer/da-indexer-logic/src/celestia/rpc_client.rs @@ -1,6 +1,10 @@ -use celestia_rpc::{Error, Result}; +use std::future::Future; + +use celestia_rpc::Error; +use celestia_types::{AppVersion, ExtendedDataSquare}; use http::{header, HeaderValue}; use jsonrpsee::{ + core::client::{self, ClientT}, http_client::{HeaderMap, HttpClientBuilder}, ws_client::WsClientBuilder, }; @@ -12,7 +16,7 @@ pub async fn new_celestia_client( auth_token: Option<&str>, max_request_size: u32, max_response_size: u32, -) -> Result { +) -> celestia_rpc::Result { let mut headers = HeaderMap::new(); if let Some(token) = auth_token { @@ -42,3 +46,47 @@ pub async fn new_celestia_client( Ok(client) } + +// celestia_rpc::Client doesn't support new version of share.GetEDS method +// so we need to implement it manually +pub mod rpc { + use celestia_types::eds::RawExtendedDataSquare; + use jsonrpsee::proc_macros::rpc; + + #[rpc(client)] + pub trait ShareV2 { + #[method(name = "share.GetEDS")] + async fn share_get_eds_v2( + &self, + height: u64, + ) -> Result; + } +} + +pub trait ShareV2Client: ClientT { + /// GetEDS gets the full EDS identified by the given root. + fn share_get_eds_v2<'a, 'b, 'fut>( + &'a self, + height: u64, + app_version: u64, + ) -> impl Future> + Send + 'fut + where + 'a: 'fut, + 'b: 'fut, + Self: Sized + Sync + 'fut, + { + async move { + let app_version = AppVersion::from_u64(app_version).ok_or_else(|| { + let e = format!("Invalid or unsupported AppVersion: {app_version}"); + client::Error::Custom(e) + })?; + + let raw_eds = rpc::ShareV2Client::share_get_eds_v2(self, height).await?; + + ExtendedDataSquare::from_raw(raw_eds, app_version) + .map_err(|e| client::Error::Custom(e.to_string())) + } + } +} + +impl ShareV2Client for T where T: ClientT {} diff --git a/da-indexer/da-indexer-logic/src/celestia/tests/blobs.rs b/da-indexer/da-indexer-logic/src/celestia/tests/blobs.rs index 60a01371c..c73759d07 100644 --- a/da-indexer/da-indexer-logic/src/celestia/tests/blobs.rs +++ b/da-indexer/da-indexer-logic/src/celestia/tests/blobs.rs @@ -1,4 +1,7 @@ -use celestia_types::{nmt::Namespace, Blob as CelestiaBlob, Commitment}; +use celestia_types::{ + consts::appconsts::subtree_root_threshold, nmt::Namespace, AppVersion, Blob as CelestiaBlob, + Commitment, +}; use crate::celestia::{ repository::{blobs, blocks}, @@ -49,12 +52,19 @@ fn celestia_blob(seed: u32) -> CelestiaBlob { Namespace::new(0, &[&[0_u8; 18], &sha3("namespace", seed)[..10]].concat()).unwrap(); let data = sha3("data", seed).to_vec(); let share_version = 0; - let commitment = Commitment::from_blob(namespace, share_version, &data).unwrap(); + let commitment = Commitment::from_blob( + namespace, + &data, + share_version, + subtree_root_threshold(AppVersion::latest()), + ) + .unwrap(); CelestiaBlob { namespace, data, share_version, commitment, + index: None, } } diff --git a/da-indexer/da-indexer-logic/src/celestia/tests/data/eds_with_blobs.json b/da-indexer/da-indexer-logic/src/celestia/tests/data/eds_with_blobs.json deleted file mode 100644 index 177c0b36a..000000000 --- a/da-indexer/da-indexer-logic/src/celestia/tests/data/eds_with_blobs.json +++ /dev/null @@ -1 +0,0 @@ -{"data_square":["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAAJTwAAACbRAgqkAQqhAQojL2Nvc21vcy5zdGFraW5nLnYxYmV0YTEuTXNnRGVsZWdhdGUSegovY2VsZXN0aWExcGh0N2t6ZnltYTlwcnJycjh1OWY5bGxxaDBjbmZ6eTZ0ZzRzamUSNmNlbGVzdGlhdmFsb3BlcjFxZTh1dWY1eDY5YzUyNmg0bnp4d3Y0bHRmdHI3M3Y3cTVxaHM1OBoPCgR1dGlhEgcyNTAwMDAwEmYKUApGCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQOpNQYApRzfwn5FeOjZ5QJtLLW/6n3xwGVHB3g1QOcNoRIECgIIfxgEEhIKDAoEdXRpYRIEMzQ2MRDUxwoaQIH8VW1Ak0LaKU9036NOfV4ipp/9pqG2slvzNiedGf38Dh+qhbTj/aNAY52k4Fb6Bl5umoSQ2OXlP51nU/iLGjXOCgqjCQqgCQopL2liYy5hcHBsaWNhdGlvbnMudHJhbnNmZXIudjEuTXNnVHJhbnNmZXIS8ggKCHRyYW5zZmVyEgljaGFubmVsLTIaEAoEdXRpYRIIMTUwMDAwMDAiL2NlbGVzdGlhMTZ2YWV4OHJ2YWpscTNmMGdlcWZ4OHBkZzRtcnptcWo=","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAADBjajdlbmoqP29zbW8xcXh5ZHphN2N0emg5Zm43c3E1Z2NmMHJ1bjhjNzh3aDBqajQ3ZjR0NWR3YzUzMDJyMmRucXNwNGh1NjIHCAEQsqD2BkLNB3sid2FzbSI6eyJjb250cmFjdCI6Im9zbW8xcXh5ZHphN2N0emg5Zm43c3E1Z2NmMHJ1bjhjNzh3aDBqajQ3ZjR0NWR3YzUzMDJyMmRucXNwNGh1NiIsIm1zZyI6eyJzd2FwX2FuZF9hY3Rpb24iOnsidXNlcl9zd2FwIjp7InN3YXBfZXhhY3RfYXNzZXRfaW4iOnsic3dhcF92ZW51ZV9uYW1lIjoib3Ntb3Npcy1wb29sbWFuYWdlciIsIm9wZXJhdGlvbnMiOlt7InBvb2wiOiIxMjQ3IiwiZGVub21faW4iOiJpYmMvRDc5RTdEODNBQjM5OUJGRkY5MzQzM0U1NEZBQTQ4MEMxOTEyNDhGQzU1NjkyNEEyQTgzNTFBRTI2MzhCMzg3NyIsImRlbm9tX291dCI6ImliYy80OThBMDc1MUM3OThBMEQ5QTM4OUFBMzY5MTEyM0RBREE1N0RBQTRGRTE2NUQ1Qzc1ODk0NTA1Qjg3NkJBNkU0In0seyJwb29sIjoiMTM=","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAADE5IiwiZGVub21faW4iOiJpYmMvNDk4QTA3NTFDNzk4QTBEOUEzODlBQTM2OTExMjNEQURBNTdEQUE0RkUxNjVENUM3NTg5NDUwNUI4NzZCQTZFNCIsImRlbm9tX291dCI6ImliYy82NEJBNkUzMUZFODg3RDY2QzZGOEYzMUM3QjFBODBDN0NBMTc5MjM5Njc3QjQwODhCQjU1RjVFQTA3REJFMjczIn1dfX0sIm1pbl9hc3NldCI6eyJuYXRpdmUiOnsiZGVub20iOiJpYmMvNjRCQTZFMzFGRTg4N0Q2NkM2RjhGMzFDN0IxQTgwQzdDQTE3OTIzOTY3N0I0MDg4QkI1NUY1RUEwN0RCRTI3MyIsImFtb3VudCI6IjUzMDY5MDI1MDU3NTc2NTk1ODkifX0sInRpbWVvdXRfdGltZXN0YW1wIjoxNzExNTA0MTUwMjQ0NjE3NzQ5LCJwb3N0X3N3YXBfYWN0aW9uIjp7ImliY190cmFuc2ZlciI6eyJpYmNfaW5mbyI6eyJzb3VyY2VfY2hhbm5lbCI6ImNoYW5uZWwtMTIyIiwicmVjZWl2ZXIiOiJpbmoxcXFtcGc0cW1tZnd2ZXR3dXRndGV6bWNhbnBzMnN4bG5nbTk=","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABLzRwYyIsIm1lbW8iOiIiLCJyZWNvdmVyX2FkZHJlc3MiOiJvc21vMTZ2YWV4OHJ2YWpscTNmMGdlcWZ4OHBkZzRtcnptcWowcHJ1ZWxkIn19fSwiYWZmaWxpYXRlcyI6W119fX19EmQKTgpGCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQM1c2VaNOOYCyX0NwJVPNGpk9bUzniEySd6A7F0dqThsxIECgIIfxISCgwKBHV0aWESBDMwMjAQt5sJGkClOz6joxDJnzV+dbLWnKb599lelgMBHHbOjjcjYCwCewWTDORmnTnMqJ7D0nmlk0Vzesoe4DLzI7N7fskun4Oi1AIKpwEKpAEKNy9jb3Ntb3MuZGlzdHJpYnV0aW9uLnYxYmV0YTEuTXNnV2l0aGRyYXdEZWxlZ2F0b3JSZXdhcmQSaQovY2VsZXN0aWExdHAyZWdyajI5dnFyazlqMHBkZnlkbnN6Z2Fqenc3M3hoMDZtNzASNmNlbGVzdGlhdmFsb3BlcjF1cWo1dWw3anRwc2trOXN0ZTltZnY2anZoMHkzdzM0dnRwejNndxJmClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1Yks=","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","AAAAAAAAAAAAAAAAAAAAAAAAAAAADhBcVuNN75cBAAAAqQDAAPd0rLVpn72DsmTOOBCbAAAAAACReNrayaHMeP3FOsZvcz6xvjxsP9ue9c5fJnu1i4qyS78w8i580GNZ+KWbIS8tPjbqs8rc360ltfK2fXyMP+QbcSL+A3+QkfyBP+yoIijo4B/+AzVQEkkL/4E/7AehXPYHduwP6vjBJPuDf8wP/oEZCASTIg0xf7CHoXpGBBuCGEbBKBgFo2AUjIIRDwAAAAD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","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","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","//////////////////////////////////////4BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","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"],"codec":"Leopard"} \ No newline at end of file diff --git a/da-indexer/da-indexer-logic/src/celestia/tests/data/eds_without_blobs.json b/da-indexer/da-indexer-logic/src/celestia/tests/data/eds_without_blobs.json deleted file mode 100644 index 035aebfa2..000000000 --- a/da-indexer/da-indexer-logic/src/celestia/tests/data/eds_without_blobs.json +++ /dev/null @@ -1 +0,0 @@ -{"data_square":["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAABSQAAACbHAgqXAQqUAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBJ0Ci9jZWxlc3RpYTFtM2V5OHVoY2ZmMjVscGxkOWZxMjQ1dHc1ZnA3cGZqcDlwNXhncxIvY2VsZXN0aWExMzBkanI1M2w2amttZGUwNHdzZzNhbDJhMDV0ODRoY3J3djgzcWUaEAoEdXRpYRIIMzM5MDAwMDASaQpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohAnMnqrPT/07v0vAALFq2OtyoCBk0ZAbRwlt7VJiUXiKdEgQKAggBGPvuBBITCg0KBHV0aWESBTI1MDAwEJChDxpA1vO8Y7lp3fCtgtXKuPUeHXc9VYu2We6dptTTetwMcOhZWPeoRbiitXstvHaMOKjgcs8yqfS5WE0OqiDWoFFORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAABSQAAACbHAgqXAQqUAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBJ0Ci9jZWxlc3RpYTFtM2V5OHVoY2ZmMjVscGxkOWZxMjQ1dHc1ZnA3cGZqcDlwNXhncxIvY2VsZXN0aWExMzBkanI1M2w2amttZGUwNHdzZzNhbDJhMDV0ODRoY3J3djgzcWUaEAoEdXRpYRIIMzM5MDAwMDASaQpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohAnMnqrPT/07v0vAALFq2OtyoCBk0ZAbRwlt7VJiUXiKdEgQKAggBGPvuBBITCg0KBHV0aWESBTI1MDAwEJChDxpA1vO8Y7lp3fCtgtXKuPUeHXc9VYu2We6dptTTetwMcOhZWPeoRbiitXstvHaMOKjgcs8yqfS5WE0OqiDWoFFORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAABSQAAACbHAgqXAQqUAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBJ0Ci9jZWxlc3RpYTFtM2V5OHVoY2ZmMjVscGxkOWZxMjQ1dHc1ZnA3cGZqcDlwNXhncxIvY2VsZXN0aWExMzBkanI1M2w2amttZGUwNHdzZzNhbDJhMDV0ODRoY3J3djgzcWUaEAoEdXRpYRIIMzM5MDAwMDASaQpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohAnMnqrPT/07v0vAALFq2OtyoCBk0ZAbRwlt7VJiUXiKdEgQKAggBGPvuBBITCg0KBHV0aWESBTI1MDAwEJChDxpA1vO8Y7lp3fCtgtXKuPUeHXc9VYu2We6dptTTetwMcOhZWPeoRbiitXstvHaMOKjgcs8yqfS5WE0OqiDWoFFORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAABSQAAACbHAgqXAQqUAQocL2Nvc21vcy5iYW5rLnYxYmV0YTEuTXNnU2VuZBJ0Ci9jZWxlc3RpYTFtM2V5OHVoY2ZmMjVscGxkOWZxMjQ1dHc1ZnA3cGZqcDlwNXhncxIvY2VsZXN0aWExMzBkanI1M2w2amttZGUwNHdzZzNhbDJhMDV0ODRoY3J3djgzcWUaEAoEdXRpYRIIMzM5MDAwMDASaQpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohAnMnqrPT/07v0vAALFq2OtyoCBk0ZAbRwlt7VJiUXiKdEgQKAggBGPvuBBITCg0KBHV0aWESBTI1MDAwEJChDxpA1vO8Y7lp3fCtgtXKuPUeHXc9VYu2We6dptTTetwMcOhZWPeoRbiitXstvHaMOKjgcs8yqfS5WE0OqiDWoFFORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="],"codec":"Leopard"} \ No newline at end of file diff --git a/da-indexer/da-indexer-logic/src/celestia/tests/mod.rs b/da-indexer/da-indexer-logic/src/celestia/tests/mod.rs index 797ff86f5..7e5f1cd65 100644 --- a/da-indexer/da-indexer-logic/src/celestia/tests/mod.rs +++ b/da-indexer/da-indexer-logic/src/celestia/tests/mod.rs @@ -1,7 +1,6 @@ pub mod blobs; pub mod blocks; pub mod l2_router; -pub mod parser; use blockscout_service_launcher::test_database::TestDbGuard; diff --git a/da-indexer/da-indexer-logic/src/celestia/tests/parser.rs b/da-indexer/da-indexer-logic/src/celestia/tests/parser.rs deleted file mode 100644 index a85b3101c..000000000 --- a/da-indexer/da-indexer-logic/src/celestia/tests/parser.rs +++ /dev/null @@ -1,45 +0,0 @@ -use base64::prelude::*; -use celestia_types::{Blob, ExtendedDataSquare}; -use serde::Deserialize; - -use crate::celestia::parser::parse_eds; - -#[tokio::test] -pub async fn parse_eds_with_blobs() { - let eds = include_bytes!("data/eds_with_blobs.json"); - let mut deserializer = serde_json::Deserializer::from_slice(eds); - let eds = ExtendedDataSquare::deserialize(&mut deserializer).unwrap(); - let blobs = parse_eds(&eds, eds.square_len()).unwrap(); - assert!(blobs.len() == 2); - check_blob( - &blobs[0], - "0000000000000000000000000000000000000000000b912881caa28249", - "ALn3qnfThjUNBlTjNofbal8AAAAAAE942tqxhPHKOr/57y8zzfM8uYH3oEjTDLvZqYkGtb/3zT2V5zdr7wMOy5nrl8kKfpwhv6dR480TyTQBBxYBBgaGOgZHHgZGBroAAAAAAP//AQ==", - "2tIUeVtju66yqNLxBGdTL+E6E/KnjvrP0Rt83xFhmd0=", - ); - - check_blob( - &blobs[1], - "0000000000000000000000000000000000000000000e105c56e34def97", - "AMAA93SstWmfvYOyZM44EJsAAAAAAJF42trJocx4/cU6xm9zPrG+PGw/2571zl8me7WLirJLvzDyLnzQY1n4pZshLy0+NuqzytzfrSW18rZ9fIw/5BtxIv4Df5CR/IE/7KgiKOjgH/4DNVASSQv/gT/sB6Fc9gd27A/q+MEk+4N/zA/+gRkIBJMiDTF/sIehekYEG4IYRsEoGAWjYBSMghEPAAAAAP//AQ==", - "iY0byb3PZYoo2jc6zFz49/WkY/8MXV7rOl3Ob36HE+A=", - ); -} - -#[tokio::test] -pub async fn parse_eds_without_blobs() { - let eds = include_bytes!("data/eds_without_blobs.json"); - let mut deserializer = serde_json::Deserializer::from_slice(eds); - let eds = ExtendedDataSquare::deserialize(&mut deserializer).unwrap(); - let blobs = parse_eds(&eds, eds.square_len()).unwrap(); - assert!(blobs.is_empty()); -} - -fn check_blob(blob: &Blob, namespace: &str, data: &str, commitment: &str) { - assert_eq!(blob.namespace.as_bytes(), hex::decode(namespace).unwrap()); - assert_eq!(blob.data, BASE64_STANDARD.decode(data).unwrap()); - assert_eq!( - blob.commitment.0[..], - BASE64_STANDARD.decode(commitment).unwrap() - ); -}