From 76e685553f8016874adb285647b4bbb89b593ecb Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Wed, 17 Jul 2024 17:28:19 +0530 Subject: [PATCH 01/22] update: skeleton code for celestia DA --- Cargo.lock | 670 ++++++++++++++++++++++- Cargo.toml | 1 + crates/da-clients/celestia/Cargo.toml | 35 ++ crates/da-clients/celestia/src/config.rs | 58 ++ crates/da-clients/celestia/src/error.rs | 11 + crates/da-clients/celestia/src/lib.rs | 124 +++++ 6 files changed, 877 insertions(+), 22 deletions(-) create mode 100644 crates/da-clients/celestia/Cargo.toml create mode 100644 crates/da-clients/celestia/src/config.rs create mode 100644 crates/da-clients/celestia/src/error.rs create mode 100644 crates/da-clients/celestia/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 189f55c9..daa7052b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,7 +129,7 @@ dependencies = [ "alloy-eips 0.1.0", "alloy-primitives 0.6.4", "alloy-rlp", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -250,7 +250,7 @@ dependencies = [ "derive_more", "once_cell", "serde", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -1217,6 +1217,12 @@ dependencies = [ "rand", ] +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + [[package]] name = "arrayvec" version = "0.7.4" @@ -1699,7 +1705,7 @@ dependencies = [ "once_cell", "percent-encoding", "regex-lite", - "sha2", + "sha2 0.10.8", "tracing", "url", ] @@ -1815,7 +1821,7 @@ dependencies = [ "p256", "percent-encoding", "ring", - "sha2", + "sha2 0.10.8", "subtle", "time", "tracing", @@ -1850,7 +1856,7 @@ dependencies = [ "md-5", "pin-project-lite", "sha1", - "sha2", + "sha2 0.10.8", "tracing", ] @@ -2132,6 +2138,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a17bd29f7c70f32e9387f4d4acfa5ea7b7749ef784fb78cf382df97069337b8c" +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base16ct" version = "0.1.1" @@ -2212,6 +2224,21 @@ dependencies = [ "redis", ] +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + [[package]] name = "bigdecimal" version = "0.3.1" @@ -2302,6 +2329,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -2371,6 +2407,18 @@ dependencies = [ "piper", ] +[[package]] +name = "blockstore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "358358b19add120a5afc3dd1c8e9161d6d06c44dfec2ef8da58b7fe5c369c90d" +dependencies = [ + "cid", + "dashmap", + "multihash", + "thiserror", +] + [[package]] name = "blst" version = "0.3.12" @@ -2433,6 +2481,15 @@ dependencies = [ "serde_with 3.8.1", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bson" version = "2.11.0" @@ -3062,7 +3119,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "starknet-crypto 0.6.2", "starknet-curve 0.4.2", @@ -3096,7 +3153,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "starknet-crypto 0.6.2", "starknet-types-core", @@ -3130,6 +3187,133 @@ dependencies = [ "once_cell", ] +[[package]] +name = "celestia-da-client" +version = "0.1.0" +dependencies = [ + "alloy 0.1.0", + "async-trait", + "c-kzg", + "celestia-rpc", + "celestia-types", + "color-eyre", + "da-client-interface", + "dotenv", + "mockall", + "reqwest 0.12.5", + "rstest 0.18.2", + "serde", + "starknet", + "tokio", + "tokio-test", + "url", + "utils", +] + +[[package]] +name = "celestia-proto" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f22a6baf972f7277acfd5c4ff9b894df7db5b0aaecdb57b9b77b5679fff323e" +dependencies = [ + "anyhow", + "celestia-tendermint-proto", + "prost", + "prost-build", + "prost-types", + "serde", +] + +[[package]] +name = "celestia-rpc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c891b0371a6ae5a37650f1806221185cad25a1e19a11031707b6239ac720f0df" +dependencies = [ + "async-trait", + "celestia-types", + "http 0.2.12", + "jsonrpsee", + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "celestia-tendermint" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95f93b5cbbd62b6cfde961889bf05d5fe19e70d8500c4465694306ed2695ac23" +dependencies = [ + "bytes", + "celestia-tendermint-proto", + "digest 0.10.7", + "ed25519", + "ed25519-consensus", + "flex-error", + "futures", + "num-traits 0.2.19", + "once_cell", + "prost", + "prost-types", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature 2.2.0", + "subtle", + "subtle-encoding", + "time", + "zeroize", +] + +[[package]] +name = "celestia-tendermint-proto" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f7d49c1ececa30a4587c5fe8a4035b786b78a3253ed0f9636de591b3dc2b37" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits 0.2.19", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "celestia-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e20dce9a482131ec8a3c69c2cbe9b57bd838b26757952094e35397acb170b427" +dependencies = [ + "base64 0.21.7", + "bech32", + "blockstore", + "bytes", + "celestia-proto", + "celestia-tendermint", + "celestia-tendermint-proto", + "cid", + "const_format", + "enum_dispatch", + "leopard-codec", + "libp2p-identity", + "multiaddr", + "multihash", + "nmt-rs", + "ruint", + "serde", + "serde_repr", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "cexpr" version = "0.6.0" @@ -3158,6 +3342,18 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "cid" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" +dependencies = [ + "core2", + "multibase", + "multihash", + "unsigned-varint 0.8.0", +] + [[package]] name = "cipher" version = "0.4.4" @@ -3354,6 +3550,15 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.12" @@ -3473,6 +3678,19 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle-ng", + "zeroize", +] + [[package]] name = "da-client-interface" version = "0.1.0" @@ -3608,6 +3826,26 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "data-encoding-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + [[package]] name = "der" version = "0.6.1" @@ -3720,7 +3958,7 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", @@ -3884,6 +4122,29 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core", + "sha2 0.9.9", + "zeroize", +] + [[package]] name = "either" version = "1.12.0" @@ -3971,6 +4232,18 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "env_filter" version = "0.1.0" @@ -4026,7 +4299,7 @@ dependencies = [ "scrypt 0.10.0", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "thiserror", "uuid 0.8.2", @@ -4251,6 +4524,16 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] + [[package]] name = "flume" version = "0.11.0" @@ -4800,6 +5083,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -5420,6 +5712,122 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpsee" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-types", + "jsonrpsee-ws-client", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +dependencies = [ + "futures-util", + "http 0.2.12", + "jsonrpsee-core", + "pin-project", + "rustls-native-certs 0.6.3", + "soketto", + "thiserror", + "tokio", + "tokio-rustls 0.24.1", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +dependencies = [ + "anyhow", + "async-lock 2.8.0", + "async-trait", + "beef", + "futures-timer", + "futures-util", + "hyper 0.14.29", + "jsonrpsee-types", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" +dependencies = [ + "async-trait", + "hyper 0.14.29", + "hyper-rustls 0.24.2", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" +dependencies = [ + "http 0.2.12", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + [[package]] name = "jsonwebtoken" version = "9.3.0" @@ -5445,7 +5853,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", - "sha2", + "sha2 0.10.8", "signature 2.2.0", ] @@ -5516,7 +5924,7 @@ checksum = "7fb5d4f22241504f7c7b8d2c3a7d7835d7c07117f10bff2a7d96a9ef6ef217c3" dependencies = [ "lambdaworks-math", "serde", - "sha2", + "sha2 0.10.8", "sha3", ] @@ -5567,6 +5975,17 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[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 = "levenshtein" version = "1.0.5" @@ -5615,6 +6034,21 @@ dependencies = [ "libc", ] +[[package]] +name = "libp2p-identity" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" +dependencies = [ + "bs58", + "hkdf", + "multihash", + "quick-protobuf", + "sha2 0.10.8", + "thiserror", + "tracing", +] + [[package]] name = "libredox" version = "0.1.3" @@ -5919,8 +6353,8 @@ dependencies = [ "serde", "serde_bytes", "serde_with 1.14.0", - "sha-1", - "sha2", + "sha-1 0.10.1", + "sha2 0.10.8", "socket2 0.4.10", "stringprep", "strsim 0.10.0", @@ -5936,6 +6370,52 @@ dependencies = [ "webpki-roots 0.25.4", ] +[[package]] +name = "multiaddr" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "libp2p-identity", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint 0.7.2", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" +dependencies = [ + "core2", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + [[package]] name = "native-tls" version = "0.2.12" @@ -5972,6 +6452,16 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nmt-rs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e787133eafbd0f386dc4e26828a50f7595d6d7213ea0e8244c1ca6b9a9648c30" +dependencies = [ + "bytes", + "sha2 0.10.8", +] + [[package]] name = "nom" version = "7.1.3" @@ -6043,6 +6533,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -6213,6 +6714,12 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl" version = "0.10.64" @@ -6349,7 +6856,7 @@ dependencies = [ "rand", "rc2", "sha1", - "sha2", + "sha2 0.10.8", "thiserror", "x509-parser", ] @@ -6362,7 +6869,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -6385,7 +6892,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -6550,7 +7057,7 @@ dependencies = [ "digest 0.10.7", "hmac", "password-hash", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -6757,7 +7264,7 @@ dependencies = [ "der 0.7.9", "pbkdf2 0.12.2", "scrypt 0.11.0", - "sha2", + "sha2 0.10.8", "spki 0.7.3", ] @@ -6900,6 +7407,16 @@ 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" @@ -6972,6 +7489,27 @@ dependencies = [ "prost-derive", ] +[[package]] +name = "prost-build" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" +dependencies = [ + "bytes", + "heck 0.5.0", + "itertools 0.12.1", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.66", + "tempfile", +] + [[package]] name = "prost-derive" version = "0.12.6" @@ -7013,6 +7551,15 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + [[package]] name = "quote" version = "1.0.36" @@ -7817,7 +8364,7 @@ dependencies = [ "hmac", "pbkdf2 0.11.0", "salsa20", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -7828,7 +8375,7 @@ checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ "pbkdf2 0.12.2", "salsa20", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -8156,6 +8703,19 @@ dependencies = [ "starknet", ] +[[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 = "sha-1" version = "0.10.1" @@ -8184,6 +8744,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.8" @@ -8404,6 +8977,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "httparse", + "log", + "rand", + "sha-1 0.9.8", +] + [[package]] name = "spin" version = "0.5.2" @@ -8544,7 +9132,7 @@ dependencies = [ "num-integer", "num-traits 0.2.19", "rfc6979 0.4.0", - "sha2", + "sha2 0.10.8", "starknet-crypto-codegen", "starknet-curve 0.3.0", "starknet-ff", @@ -8564,7 +9152,7 @@ dependencies = [ "num-integer", "num-traits 0.2.19", "rfc6979 0.4.0", - "sha2", + "sha2 0.10.8", "starknet-crypto-codegen", "starknet-curve 0.4.2", "starknet-ff", @@ -8851,6 +9439,21 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "svix-ksuid" version = "0.8.0" @@ -9319,6 +9922,17 @@ 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.2.6", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.21.1" @@ -9655,6 +10269,18 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 55821146..40676022 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "crates/settlement-clients/ethereum", "crates/settlement-clients/starknet", "e2e-tests", + "crates/da-clients/celestia", ] [workspace.package] diff --git a/crates/da-clients/celestia/Cargo.toml b/crates/da-clients/celestia/Cargo.toml new file mode 100644 index 00000000..a925e9f6 --- /dev/null +++ b/crates/da-clients/celestia/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "celestia-da-client" +version.workspace = true +edition.workspace = true +authors.workspace = true + +[dependencies] +alloy = { git = "https://github.com/alloy-rs/alloy", rev = "68952c0", features = [ + "consensus", + "providers", + "rpc-client", + "transport-http", + "network", + "eips", + "signers", + "signer-wallet", +] } +async-trait = { workspace = true } +c-kzg = "1.0.0" +celestia-rpc = "0.2.0" +celestia-types = "0.2.0" +color-eyre = { workspace = true } +da-client-interface = { workspace = true } +dotenv = "0.15" +mockall = "0.12.1" +reqwest = { version = "0.12.3" } +rstest = { workspace = true } +serde = { version = "1.0.196", default-features = false, features = ["derive"] } +starknet = { workspace = true } +tokio = { workspace = true } +url = { workspace = true } +utils = { workspace = true } + +[dev-dependencies] +tokio-test = "*" diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs new file mode 100644 index 00000000..0d1d1dd2 --- /dev/null +++ b/crates/da-clients/celestia/src/config.rs @@ -0,0 +1,58 @@ +use std::fs::File; +use std::path::PathBuf; + +use serde::Deserialize; + +use crate::DaMode; + +pub const DEFAULT_CELESTIA_NODE: &str = "127.0.0.1:8000"; +pub const DEFAULT_AUTH_TOKEN: &str = ""; +pub const DEFAULT_NID: &str = "Karnot"; + +#[derive(Clone, PartialEq, Deserialize, Debug)] +pub struct CelestiaConfig { + #[serde(default = "default_http")] + pub http_provider: String, + #[serde(default = "default_auth_token")] + pub auth_token: String, + #[serde(default = "default_nid")] + pub nid: String, + #[serde(default)] + pub auth_token: Option, + #[serde(default)] + pub mode: DaMode, +} + +impl TryFrom<&PathBuf> for CelestiaConfig { + type Error = String; + + fn try_from(path: &PathBuf) -> Result { + let file = File::open(path).map_err(|e| format!("error opening da config: {e}"))?; + serde_json::from_reader(file).map_err(|e| format!("error parsing da config: {e}")) + } +} + +fn default_http() -> String { + format!("http://{DEFAULT_CELESTIA_NODE}") +} + +fn default_auth_token() -> String { + format!("http://{DEFAULT_AUTH_TOKEN}") +} + + +fn default_nid() -> String { + DEFAULT_NID.to_string() +} + +impl Default for CelestiaConfig { + fn default() -> Self { + Self { + http_provider: default_http(), + auth_token: default_auth_token(), + nid: default_nid(), + mode: DaMode::default(), + auth_token: None, + } + } +} \ No newline at end of file diff --git a/crates/da-clients/celestia/src/error.rs b/crates/da-clients/celestia/src/error.rs new file mode 100644 index 00000000..f9718629 --- /dev/null +++ b/crates/da-clients/celestia/src/error.rs @@ -0,0 +1,11 @@ +#[derive(thiserror::Error, Debug)] +pub enum CelestiaDaError { + #[error("Data availability error occurred: {0}")] + Generic(String), + #[error("Data availability client error: {0}")] + Client(String), + #[error("Invalid data availability chain: {0}")] + InvalidChain(String), +} + +pub type DataAvailabilityResult = Result; \ No newline at end of file diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs new file mode 100644 index 00000000..1528c2c8 --- /dev/null +++ b/crates/da-clients/celestia/src/lib.rs @@ -0,0 +1,124 @@ +pub mod config; +pub mod error; + +use anyhow::Result; +use async_trait::async_trait; +use error::CelestiaDaError; + +use celestia_rpc::{BlobClient, Client, HeaderClient, ShareClient}; +use celestia_types::blob::GasPrice; +use celestia_types::{nmt::Namespace, Blob, ExtendedDataSquare}; + +use da_client_interface::{DaClient, DaVerificationStatus}; +use crate::{DaClient, DaMode}; + +#[derive(Clone, Debug)] +pub struct CelestiaDaClient { + celestia_client: Client, + nid: Namespace, + mode: DaMode, +} + +#[automock] +#[async_trait] +impl DaClient for CelestiaDaClient { + async fn publish_state_diff(&self, state_diff: Vec>, to: &[u8; 32]) -> Result { + // Convert the state_diffs into Blobs + let blobs = state_diff.iter().map(|&blob_data| Blob::new(self.nid, blob_data)).collect(); + // Submit the blobs to celestia + let height = self.celestia_client.blob_submit(blobs, GasPrice::default()).await.expect("Failed submitting blobs"); + // Return back the height of the block that will contain the blob. + Ok(height.to_string()) + } + + async fn verify_inclusion(&self, external_id: &str) -> Result { + + // TODO: check if feasible and needed ? we can send blob.commitment as a part of external id and use it to call get_blob rather than get_all for more precise answer. + + // External Id : Height of Block the blob is submitted to. + // 2 ways to check : + // Is the current block ahead of the block that we have, if it is does my block contain the blob. + // Call the blob_get_all function of the client + + let height: String = external_id.parse().unwrap(); + let height_id: u64 = match s.parse::() { + Ok(n) => n, + Err(e) => { + println!("Failed to convert string to u64: {}", e); + return; + } + }; + + let retrieved_blobs = self.celestia_client.blob_get_all(height_id, self.nid).await + .expect("Failed to retrieve blobs"); + + // TODO: Assumption: Given that we are sending only 1 nid, we'll get an array of 1 object back. + + match retrieved_blobs[0].validate() { + Ok => Ok(DaVerificationStatus::Verified), + Err(e) => Ok(DaVerificationStatus::Rejected(format!("Verification failed", e.to_string()))), + } + + } + + async fn max_blob_per_txn(&self) -> u64 { + //Info: No docs suggest a number. + 1 + } + + async fn max_bytes_per_blob(&self) -> u64 { + //Info: https://github.com/celestiaorg/celestia-node/issues/3356 + 1974272 + } +} + +impl CelestiaClient { + async fn publish_data(&self, blob: &Blob) -> Result { + self.http_client + .blob_submit(&[blob.clone()], SubmitOptions::default()) + .await + .map_err(|e| anyhow::anyhow!("could not submit blob {e}")) + } + + fn get_blob_from_state_diff(&self, state_diff: Vec) -> CelestiaTypesResult { + let state_diff_bytes: Vec = state_diff + .iter() + .flat_map(|item| { + let mut bytes = [0_u8; 32]; + item.to_big_endian(&mut bytes); + bytes.to_vec() + }) + .collect(); + + Blob::new(self.nid, state_diff_bytes) + } + + async fn verify_blob_was_included(&self, submitted_height: u64, blob: Blob) -> Result<()> { + let received_blob = self.http_client.blob_get(submitted_height, self.nid, blob.commitment).await.unwrap(); + received_blob.validate()?; + Ok(()) + } +} + +impl TryFrom for CelestiaClient { + type Error = anyhow::Error; + + fn try_from(conf: config::CelestiaConfig) -> Result { + // Borrowed the below code from https://github.com/eigerco/lumina/blob/ccc5b9bfeac632cccd32d35ecb7b7d51d71fbb87/rpc/src/client.rs#L41. + // Directly calling the function wasn't possible as the function is async. Since + // we only need to initiate the http provider and not the ws provider, we don't need async + + let client = Client::new(&conf.http_provider, Some(&conf.auth_token)) + .await + // TODO: user Celestia DA Errors + .expect("Failed creating rpc client"); + + // Convert the input string to bytes + let bytes = conf.nid.as_bytes(); + + // Create a new Namespace from these bytes + let nid = Namespace::new_v0(bytes).map_err(|e| anyhow::anyhow!("could not init namespace: {e}"))?; + + Ok(Self { client, nid, mode: conf.mode }) + } +} \ No newline at end of file From 64a1372e6dc2d6d531be53339e0523f95ac3878f Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Thu, 18 Jul 2024 14:17:16 +0530 Subject: [PATCH 02/22] update: Cleanup: deps + error logs --- Cargo.lock | 3 --- crates/da-clients/celestia/Cargo.toml | 12 ------------ crates/da-clients/celestia/src/lib.rs | 12 ++++++------ 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index daa7052b..f623849c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3191,9 +3191,7 @@ dependencies = [ name = "celestia-da-client" version = "0.1.0" dependencies = [ - "alloy 0.1.0", "async-trait", - "c-kzg", "celestia-rpc", "celestia-types", "color-eyre", @@ -3203,7 +3201,6 @@ dependencies = [ "reqwest 0.12.5", "rstest 0.18.2", "serde", - "starknet", "tokio", "tokio-test", "url", diff --git a/crates/da-clients/celestia/Cargo.toml b/crates/da-clients/celestia/Cargo.toml index a925e9f6..3e016351 100644 --- a/crates/da-clients/celestia/Cargo.toml +++ b/crates/da-clients/celestia/Cargo.toml @@ -5,18 +5,7 @@ edition.workspace = true authors.workspace = true [dependencies] -alloy = { git = "https://github.com/alloy-rs/alloy", rev = "68952c0", features = [ - "consensus", - "providers", - "rpc-client", - "transport-http", - "network", - "eips", - "signers", - "signer-wallet", -] } async-trait = { workspace = true } -c-kzg = "1.0.0" celestia-rpc = "0.2.0" celestia-types = "0.2.0" color-eyre = { workspace = true } @@ -26,7 +15,6 @@ mockall = "0.12.1" reqwest = { version = "0.12.3" } rstest = { workspace = true } serde = { version = "1.0.196", default-features = false, features = ["derive"] } -starknet = { workspace = true } tokio = { workspace = true } url = { workspace = true } utils = { workspace = true } diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 1528c2c8..f2a71862 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -44,13 +44,13 @@ impl DaClient for CelestiaDaClient { let height_id: u64 = match s.parse::() { Ok(n) => n, Err(e) => { - println!("Failed to convert string to u64: {}", e); - return; + // TODO: check ifthis returns + CelestiaDaError::Generic((format!("Failed to convert string to u64: {e}"))); } }; let retrieved_blobs = self.celestia_client.blob_get_all(height_id, self.nid).await - .expect("Failed to retrieve blobs"); + .expect(CelestiaDaError::Generic((format!("could not init namespace")))); // TODO: Assumption: Given that we are sending only 1 nid, we'll get an array of 1 object back. @@ -77,7 +77,7 @@ impl CelestiaClient { self.http_client .blob_submit(&[blob.clone()], SubmitOptions::default()) .await - .map_err(|e| anyhow::anyhow!("could not submit blob {e}")) + .map_err(|e| CelestiaDaError::Client(format!("Celestia RPC error: {e}"))) } fn get_blob_from_state_diff(&self, state_diff: Vec) -> CelestiaTypesResult { @@ -111,13 +111,13 @@ impl TryFrom for CelestiaClient { let client = Client::new(&conf.http_provider, Some(&conf.auth_token)) .await // TODO: user Celestia DA Errors - .expect("Failed creating rpc client"); + .expect(CelestiaDaError::Client((format!("Failed creating rpc client")))); // Convert the input string to bytes let bytes = conf.nid.as_bytes(); // Create a new Namespace from these bytes - let nid = Namespace::new_v0(bytes).map_err(|e| anyhow::anyhow!("could not init namespace: {e}"))?; + let nid = Namespace::new_v0(bytes).map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))); Ok(Self { client, nid, mode: conf.mode }) } From 3c4bc457bdeaa8e4efa12511a0c9c574eb1ed30a Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Thu, 18 Jul 2024 18:02:00 +0530 Subject: [PATCH 03/22] fix: Build Celestia Da Client --- Cargo.lock | 7 +- crates/da-clients/celestia/Cargo.toml | 11 ++- crates/da-clients/celestia/src/config.rs | 21 ++--- crates/da-clients/celestia/src/lib.rs | 100 +++++++++-------------- 4 files changed, 59 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f623849c..d20ab9d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3191,16 +3191,19 @@ dependencies = [ name = "celestia-da-client" version = "0.1.0" dependencies = [ + "anyhow", "async-trait", "celestia-rpc", "celestia-types", "color-eyre", "da-client-interface", - "dotenv", + "jsonrpsee", "mockall", - "reqwest 0.12.5", + "reqwest 0.11.27", "rstest 0.18.2", "serde", + "serde_json", + "thiserror", "tokio", "tokio-test", "url", diff --git a/crates/da-clients/celestia/Cargo.toml b/crates/da-clients/celestia/Cargo.toml index 3e016351..0ee2489b 100644 --- a/crates/da-clients/celestia/Cargo.toml +++ b/crates/da-clients/celestia/Cargo.toml @@ -5,16 +5,23 @@ edition.workspace = true authors.workspace = true [dependencies] +anyhow = "1.0.86" async-trait = { workspace = true } celestia-rpc = "0.2.0" celestia-types = "0.2.0" color-eyre = { workspace = true } da-client-interface = { workspace = true } -dotenv = "0.15" +jsonrpsee = { version = "0.20.0", features = [ + "http-client", + "ws-client", + "macros", +] } mockall = "0.12.1" -reqwest = { version = "0.12.3" } +reqwest = { version = "0.11.18", features = ["blocking", "json"] } rstest = { workspace = true } serde = { version = "1.0.196", default-features = false, features = ["derive"] } +serde_json.workspace = true +thiserror.workspace = true tokio = { workspace = true } url = { workspace = true } utils = { workspace = true } diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index 0d1d1dd2..a250a8f6 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -3,8 +3,6 @@ use std::path::PathBuf; use serde::Deserialize; -use crate::DaMode; - pub const DEFAULT_CELESTIA_NODE: &str = "127.0.0.1:8000"; pub const DEFAULT_AUTH_TOKEN: &str = ""; pub const DEFAULT_NID: &str = "Karnot"; @@ -13,14 +11,10 @@ pub const DEFAULT_NID: &str = "Karnot"; pub struct CelestiaConfig { #[serde(default = "default_http")] pub http_provider: String, - #[serde(default = "default_auth_token")] - pub auth_token: String, - #[serde(default = "default_nid")] - pub nid: String, #[serde(default)] pub auth_token: Option, - #[serde(default)] - pub mode: DaMode, + #[serde(default = "default_nid")] + pub nid: String, } impl TryFrom<&PathBuf> for CelestiaConfig { @@ -36,9 +30,10 @@ fn default_http() -> String { format!("http://{DEFAULT_CELESTIA_NODE}") } -fn default_auth_token() -> String { - format!("http://{DEFAULT_AUTH_TOKEN}") -} +// TODO: Auth currently not supported, surpassing from celestia-node using --rpc.skip_auth +// fn default_auth_token() -> String { +// format!("http://{DEFAULT_AUTH_TOKEN}") +// } fn default_nid() -> String { @@ -49,10 +44,8 @@ impl Default for CelestiaConfig { fn default() -> Self { Self { http_provider: default_http(), - auth_token: default_auth_token(), - nid: default_nid(), - mode: DaMode::default(), auth_token: None, + nid: default_nid(), } } } \ No newline at end of file diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index f2a71862..a4da5c67 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -1,38 +1,38 @@ pub mod config; pub mod error; -use anyhow::Result; +use color_eyre::Result; use async_trait::async_trait; use error::CelestiaDaError; +use jsonrpsee::http_client::{HeaderMap, HeaderValue, HttpClient, HttpClientBuilder}; +use reqwest::header; -use celestia_rpc::{BlobClient, Client, HeaderClient, ShareClient}; +use celestia_rpc::BlobClient; use celestia_types::blob::GasPrice; -use celestia_types::{nmt::Namespace, Blob, ExtendedDataSquare}; +use celestia_types::{nmt::Namespace, Blob}; use da_client_interface::{DaClient, DaVerificationStatus}; -use crate::{DaClient, DaMode}; #[derive(Clone, Debug)] pub struct CelestiaDaClient { - celestia_client: Client, + celestia_client: HttpClient, nid: Namespace, - mode: DaMode, } -#[automock] #[async_trait] impl DaClient for CelestiaDaClient { async fn publish_state_diff(&self, state_diff: Vec>, to: &[u8; 32]) -> Result { // Convert the state_diffs into Blobs - let blobs = state_diff.iter().map(|&blob_data| Blob::new(self.nid, blob_data)).collect(); + let blobs : Result, _> = state_diff.into_iter().map(|blob_data| Blob::new(self.nid, blob_data)).collect(); + // Submit the blobs to celestia - let height = self.celestia_client.blob_submit(blobs, GasPrice::default()).await.expect("Failed submitting blobs"); - // Return back the height of the block that will contain the blob. + let height = self.celestia_client.blob_submit(blobs?.as_slice(), GasPrice::default()).await.expect("Failed submitting blobs"); + + // // Return back the height of the block that will contain the blob. Ok(height.to_string()) } async fn verify_inclusion(&self, external_id: &str) -> Result { - // TODO: check if feasible and needed ? we can send blob.commitment as a part of external id and use it to call get_blob rather than get_all for more precise answer. // External Id : Height of Block the blob is submitted to. @@ -40,23 +40,20 @@ impl DaClient for CelestiaDaClient { // Is the current block ahead of the block that we have, if it is does my block contain the blob. // Call the blob_get_all function of the client - let height: String = external_id.parse().unwrap(); - let height_id: u64 = match s.parse::() { - Ok(n) => n, - Err(e) => { - // TODO: check ifthis returns - CelestiaDaError::Generic((format!("Failed to convert string to u64: {e}"))); - } - }; + let height_id = external_id.parse()?; + let retrieved_blobs = self.celestia_client.blob_get_all(height_id, &[self.nid]).await; - let retrieved_blobs = self.celestia_client.blob_get_all(height_id, self.nid).await - .expect(CelestiaDaError::Generic((format!("could not init namespace")))); - - // TODO: Assumption: Given that we are sending only 1 nid, we'll get an array of 1 object back. + //TODO: Assumption: Given that we are sending only 1 nid, we'll get an array of 1 object back. - match retrieved_blobs[0].validate() { - Ok => Ok(DaVerificationStatus::Verified), - Err(e) => Ok(DaVerificationStatus::Rejected(format!("Verification failed", e.to_string()))), + match retrieved_blobs { + Ok(blobs) => { + if blobs.len() == 1 { + Ok(DaVerificationStatus::Verified) + } else { + Ok(DaVerificationStatus::Rejected(format!("Expected 1 blob, but got {}", blobs.len()))) + } + } + Err(e) => Ok(DaVerificationStatus::Rejected(format!("Error occurred: {}", e))), } } @@ -72,53 +69,32 @@ impl DaClient for CelestiaDaClient { } } -impl CelestiaClient { - async fn publish_data(&self, blob: &Blob) -> Result { - self.http_client - .blob_submit(&[blob.clone()], SubmitOptions::default()) - .await - .map_err(|e| CelestiaDaError::Client(format!("Celestia RPC error: {e}"))) - } - - fn get_blob_from_state_diff(&self, state_diff: Vec) -> CelestiaTypesResult { - let state_diff_bytes: Vec = state_diff - .iter() - .flat_map(|item| { - let mut bytes = [0_u8; 32]; - item.to_big_endian(&mut bytes); - bytes.to_vec() - }) - .collect(); - - Blob::new(self.nid, state_diff_bytes) - } - - async fn verify_blob_was_included(&self, submitted_height: u64, blob: Blob) -> Result<()> { - let received_blob = self.http_client.blob_get(submitted_height, self.nid, blob.commitment).await.unwrap(); - received_blob.validate()?; - Ok(()) - } -} - -impl TryFrom for CelestiaClient { +impl TryFrom for CelestiaDaClient { type Error = anyhow::Error; - fn try_from(conf: config::CelestiaConfig) -> Result { // Borrowed the below code from https://github.com/eigerco/lumina/blob/ccc5b9bfeac632cccd32d35ecb7b7d51d71fbb87/rpc/src/client.rs#L41. // Directly calling the function wasn't possible as the function is async. Since // we only need to initiate the http provider and not the ws provider, we don't need async - let client = Client::new(&conf.http_provider, Some(&conf.auth_token)) - .await - // TODO: user Celestia DA Errors - .expect(CelestiaDaError::Client((format!("Failed creating rpc client")))); + let mut headers = HeaderMap::new(); + + // checking if Auth is available + if let Some(auth_token) = conf.auth_token { + let val = HeaderValue::from_str(&format!("Bearer {}", auth_token))?; + headers.insert(header::AUTHORIZATION, val); + } + + let http_client = HttpClientBuilder::default() + .set_headers(headers) + .build(conf.http_provider.as_str()) + .map_err(|e| CelestiaDaError::Client(format!("could not init http client: {e}")))?; // Convert the input string to bytes let bytes = conf.nid.as_bytes(); // Create a new Namespace from these bytes - let nid = Namespace::new_v0(bytes).map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))); + let nid = Namespace::new_v0(bytes).map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))).unwrap(); - Ok(Self { client, nid, mode: conf.mode }) + Ok(Self { celestia_client: http_client, nid }) } } \ No newline at end of file From e90c8e02db4bd96923ad929dd79c301ab9e18e0f Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Thu, 18 Jul 2024 18:45:29 +0530 Subject: [PATCH 04/22] update: tests skeletons setup --- crates/da-clients/celestia/src/config.rs | 4 +- crates/da-clients/celestia/src/lib.rs | 67 ++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index a250a8f6..1ba0cdc9 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use serde::Deserialize; -pub const DEFAULT_CELESTIA_NODE: &str = "127.0.0.1:8000"; +pub const DEFAULT_CELESTIA_NODE: &str = "http://127.0.0.1:8000"; pub const DEFAULT_AUTH_TOKEN: &str = ""; pub const DEFAULT_NID: &str = "Karnot"; @@ -27,7 +27,7 @@ impl TryFrom<&PathBuf> for CelestiaConfig { } fn default_http() -> String { - format!("http://{DEFAULT_CELESTIA_NODE}") + format!("{DEFAULT_CELESTIA_NODE}") } // TODO: Auth currently not supported, surpassing from celestia-node using --rpc.skip_auth diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index a4da5c67..36071402 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -97,4 +97,71 @@ impl TryFrom for CelestiaDaClient { Ok(Self { celestia_client: http_client, nid }) } +} + + + + +#[cfg(test)] +mod tests { + + use config::{CelestiaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; + + use super::*; + + // async fn test_celestia_da_client(){ + // let config = CelestiaConfig { + // http_provider: DEFAULT_CELESTIA_NODE.to_string(), + // auth_token: None, + // nid: DEFAULT_NID.to_string(), + // }; + // // Instantiate CelestiaDaClient + // let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + + // celestia_da_client.publish_state_diff(state_diff, to); + + + // } + + // async fn test_verify_inclusion(){ + + + // } + + + #[tokio::test] + async fn test_max_blob_per_txn(){ + let expected_value:u64 = 1; + + println!("{}",DEFAULT_CELESTIA_NODE); + + let config = CelestiaConfig { + http_provider: DEFAULT_CELESTIA_NODE.to_string(), + auth_token: None, + nid: DEFAULT_NID.to_string(), + }; + // Instantiate CelestiaDaClient + let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + + let max_blobs_per_txn = celestia_da_client.max_blob_per_txn().await; + assert_eq!(max_blobs_per_txn, expected_value); + } + + #[tokio::test] + async fn test_max_bytes_per_blob(){ + let expected_value:u64 = 1974272; + + let config = CelestiaConfig { + http_provider: DEFAULT_CELESTIA_NODE.to_string(), + auth_token: None, + nid: DEFAULT_NID.to_string(), + }; + // Instantiate CelestiaDaClient + let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + + let max_bytes_per_blob = celestia_da_client.max_bytes_per_blob().await; + assert_eq!(max_bytes_per_blob,expected_value); + } + + } \ No newline at end of file From 3253ff65c2f46aa3a29590f6e70f0f7d43003c22 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 08:45:02 +0530 Subject: [PATCH 05/22] update: tests for CelestiaDaClient --- crates/da-clients/celestia/src/lib.rs | 66 ++++++++++++++++++--------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 36071402..2158933e 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -26,7 +26,7 @@ impl DaClient for CelestiaDaClient { let blobs : Result, _> = state_diff.into_iter().map(|blob_data| Blob::new(self.nid, blob_data)).collect(); // Submit the blobs to celestia - let height = self.celestia_client.blob_submit(blobs?.as_slice(), GasPrice::default()).await.expect("Failed submitting blobs"); + let height = self.celestia_client.blob_submit(blobs?.as_slice(), GasPrice::from(0.1)).await.expect("Failed submitting blobs"); // // Return back the height of the block that will contain the blob. Ok(height.to_string()) @@ -59,7 +59,7 @@ impl DaClient for CelestiaDaClient { } async fn max_blob_per_txn(&self) -> u64 { - //Info: No docs suggest a number. + //Info: No docs suggest a number, default to 1. 1 } @@ -100,41 +100,65 @@ impl TryFrom for CelestiaDaClient { } - - #[cfg(test)] mod tests { use config::{CelestiaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; - use super::*; - // async fn test_celestia_da_client(){ - // let config = CelestiaConfig { - // http_provider: DEFAULT_CELESTIA_NODE.to_string(), - // auth_token: None, - // nid: DEFAULT_NID.to_string(), - // }; - // // Instantiate CelestiaDaClient - // let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); - - // celestia_da_client.publish_state_diff(state_diff, to); + #[tokio::test] + async fn test_celestia_publish_state_diff_and_verify_inclusion(){ + let config = CelestiaConfig { + http_provider: DEFAULT_CELESTIA_NODE.to_string(), + auth_token: None, + nid: DEFAULT_NID.to_string(), + }; + // Instantiate CelestiaDaClient + let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + let s = "Hello World!"; + let bytes: Vec = s.bytes().collect(); + let state_diff = vec![bytes]; + + let to: [u8; 32] = [ + 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, + 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, + 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff, + ]; + + let height_response = celestia_da_client.publish_state_diff(state_diff, &to).await; + + let height_id = match height_response { + Ok(variable) => variable, + Err(error) => panic!("Problem reading: {error:?}"), + }; - // } + let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await; - // async fn test_verify_inclusion(){ + let inclusion = match inclusion_response { + Ok(variable) => variable, + Err(error) => panic!("Problem reading: {error:?}"), + }; + assert_eq!(inclusion,DaVerificationStatus::Verified); - // } + match inclusion { + DaVerificationStatus::Pending => println!("Verification Status is Pending"), + DaVerificationStatus::Verified => println!("Verification Status is Verified"), + DaVerificationStatus::Rejected(msg) => println!("Verification Status is Rejected: {}", msg), + } + } #[tokio::test] async fn test_max_blob_per_txn(){ let expected_value:u64 = 1; - println!("{}",DEFAULT_CELESTIA_NODE); - let config = CelestiaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), auth_token: None, @@ -162,6 +186,4 @@ mod tests { let max_bytes_per_blob = celestia_da_client.max_bytes_per_blob().await; assert_eq!(max_bytes_per_blob,expected_value); } - - } \ No newline at end of file From 82477ee9879bafdf7f2cba9c6c9b371fb95868f3 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 08:53:41 +0530 Subject: [PATCH 06/22] update: added ignore test cases on celestiaDaClient tests --- crates/da-clients/celestia/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 2158933e..4da8275b 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -19,6 +19,7 @@ pub struct CelestiaDaClient { nid: Namespace, } + #[async_trait] impl DaClient for CelestiaDaClient { async fn publish_state_diff(&self, state_diff: Vec>, to: &[u8; 32]) -> Result { @@ -107,6 +108,7 @@ mod tests { use super::*; #[tokio::test] + #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion(){ let config = CelestiaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), @@ -156,6 +158,7 @@ mod tests { #[tokio::test] + #[ignore = "Can't run without manual intervention, setup celestia-node."] async fn test_max_blob_per_txn(){ let expected_value:u64 = 1; @@ -172,6 +175,7 @@ mod tests { } #[tokio::test] + #[ignore = "Can't run without manual intervention, setup celestia-node."] async fn test_max_bytes_per_blob(){ let expected_value:u64 = 1974272; From b1b71cd94d5a85f7caca2ba58a930bb44b86bd10 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 09:35:32 +0530 Subject: [PATCH 07/22] update: cargo fmt and clippy fixes --- crates/da-clients/celestia/src/config.rs | 11 ++--- crates/da-clients/celestia/src/error.rs | 2 +- crates/da-clients/celestia/src/lib.rs | 59 +++++++++++------------- 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index 1ba0cdc9..a91f9ec1 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -27,7 +27,7 @@ impl TryFrom<&PathBuf> for CelestiaConfig { } fn default_http() -> String { - format!("{DEFAULT_CELESTIA_NODE}") + DEFAULT_CELESTIA_NODE.to_string() } // TODO: Auth currently not supported, surpassing from celestia-node using --rpc.skip_auth @@ -35,17 +35,12 @@ fn default_http() -> String { // format!("http://{DEFAULT_AUTH_TOKEN}") // } - fn default_nid() -> String { DEFAULT_NID.to_string() } impl Default for CelestiaConfig { fn default() -> Self { - Self { - http_provider: default_http(), - auth_token: None, - nid: default_nid(), - } + Self { http_provider: default_http(), auth_token: None, nid: default_nid() } } -} \ No newline at end of file +} diff --git a/crates/da-clients/celestia/src/error.rs b/crates/da-clients/celestia/src/error.rs index f9718629..36f109f3 100644 --- a/crates/da-clients/celestia/src/error.rs +++ b/crates/da-clients/celestia/src/error.rs @@ -8,4 +8,4 @@ pub enum CelestiaDaError { InvalidChain(String), } -pub type DataAvailabilityResult = Result; \ No newline at end of file +pub type DataAvailabilityResult = Result; diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 4da8275b..afc8b11b 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -1,8 +1,8 @@ pub mod config; pub mod error; -use color_eyre::Result; use async_trait::async_trait; +use color_eyre::Result; use error::CelestiaDaError; use jsonrpsee::http_client::{HeaderMap, HeaderValue, HttpClient, HttpClientBuilder}; use reqwest::header; @@ -19,16 +19,20 @@ pub struct CelestiaDaClient { nid: Namespace, } - #[async_trait] impl DaClient for CelestiaDaClient { async fn publish_state_diff(&self, state_diff: Vec>, to: &[u8; 32]) -> Result { // Convert the state_diffs into Blobs - let blobs : Result, _> = state_diff.into_iter().map(|blob_data| Blob::new(self.nid, blob_data)).collect(); - + let blobs: Result, _> = + state_diff.into_iter().map(|blob_data| Blob::new(self.nid, blob_data)).collect(); + // Submit the blobs to celestia - let height = self.celestia_client.blob_submit(blobs?.as_slice(), GasPrice::from(0.1)).await.expect("Failed submitting blobs"); - + let height = self + .celestia_client + .blob_submit(blobs?.as_slice(), GasPrice::from(0.1)) + .await + .expect("Failed submitting blobs"); + // // Return back the height of the block that will contain the blob. Ok(height.to_string()) } @@ -37,7 +41,7 @@ impl DaClient for CelestiaDaClient { // TODO: check if feasible and needed ? we can send blob.commitment as a part of external id and use it to call get_blob rather than get_all for more precise answer. // External Id : Height of Block the blob is submitted to. - // 2 ways to check : + // 2 ways to check : // Is the current block ahead of the block that we have, if it is does my block contain the blob. // Call the blob_get_all function of the client @@ -56,11 +60,10 @@ impl DaClient for CelestiaDaClient { } Err(e) => Ok(DaVerificationStatus::Rejected(format!("Error occurred: {}", e))), } - } async fn max_blob_per_txn(&self) -> u64 { - //Info: No docs suggest a number, default to 1. + //Info: No docs suggest a number, default to 1. 1 } @@ -78,7 +81,7 @@ impl TryFrom for CelestiaDaClient { // we only need to initiate the http provider and not the ws provider, we don't need async let mut headers = HeaderMap::new(); - + // checking if Auth is available if let Some(auth_token) = conf.auth_token { let val = HeaderValue::from_str(&format!("Bearer {}", auth_token))?; @@ -94,22 +97,23 @@ impl TryFrom for CelestiaDaClient { let bytes = conf.nid.as_bytes(); // Create a new Namespace from these bytes - let nid = Namespace::new_v0(bytes).map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))).unwrap(); + let nid = Namespace::new_v0(bytes) + .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) + .unwrap(); Ok(Self { celestia_client: http_client, nid }) } } - #[cfg(test)] mod tests { - use config::{CelestiaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; use super::*; + use config::{CelestiaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; #[tokio::test] #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] - async fn test_celestia_publish_state_diff_and_verify_inclusion(){ + async fn test_celestia_publish_state_diff_and_verify_inclusion() { let config = CelestiaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), auth_token: None, @@ -120,17 +124,11 @@ mod tests { let s = "Hello World!"; let bytes: Vec = s.bytes().collect(); - let state_diff = vec![bytes]; + let state_diff = vec![bytes]; let to: [u8; 32] = [ - 0x01, 0x23, 0x45, 0x67, - 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, - 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, - 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, - 0xcc, 0xdd, 0xee, 0xff, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, + 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, ]; let height_response = celestia_da_client.publish_state_diff(state_diff, &to).await; @@ -147,7 +145,7 @@ mod tests { Err(error) => panic!("Problem reading: {error:?}"), }; - assert_eq!(inclusion,DaVerificationStatus::Verified); + assert_eq!(inclusion, DaVerificationStatus::Verified); match inclusion { DaVerificationStatus::Pending => println!("Verification Status is Pending"), @@ -156,11 +154,10 @@ mod tests { } } - #[tokio::test] #[ignore = "Can't run without manual intervention, setup celestia-node."] - async fn test_max_blob_per_txn(){ - let expected_value:u64 = 1; + async fn test_max_blob_per_txn() { + let expected_value: u64 = 1; let config = CelestiaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), @@ -176,8 +173,8 @@ mod tests { #[tokio::test] #[ignore = "Can't run without manual intervention, setup celestia-node."] - async fn test_max_bytes_per_blob(){ - let expected_value:u64 = 1974272; + async fn test_max_bytes_per_blob() { + let expected_value: u64 = 1974272; let config = CelestiaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), @@ -188,6 +185,6 @@ mod tests { let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); let max_bytes_per_blob = celestia_da_client.max_bytes_per_blob().await; - assert_eq!(max_bytes_per_blob,expected_value); + assert_eq!(max_bytes_per_blob, expected_value); } -} \ No newline at end of file +} From 4822fc5bc30010d60496ebe1733cd635db591b48 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 09:55:13 +0530 Subject: [PATCH 08/22] update: added protobuf to cargo.toml --- Cargo.lock | 21 +++++++++++++++++++++ crates/da-clients/celestia/Cargo.toml | 1 + 2 files changed, 22 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index d20ab9d1..3f265e37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3199,6 +3199,7 @@ dependencies = [ "da-client-interface", "jsonrpsee", "mockall", + "protobuf", "reqwest 0.11.27", "rstest 0.18.2", "serde", @@ -7532,6 +7533,26 @@ dependencies = [ "prost", ] +[[package]] +name = "protobuf" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df67496db1a89596beaced1579212e9b7c53c22dca1d9745de00ead76573d514" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-support" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e2d30ab1878b2e72d1e2fc23ff5517799c9929e2cf81a8516f9f4dcf2b9cf3" +dependencies = [ + "thiserror", +] + [[package]] name = "prover-client-interface" version = "0.1.0" diff --git a/crates/da-clients/celestia/Cargo.toml b/crates/da-clients/celestia/Cargo.toml index 0ee2489b..9aa7c677 100644 --- a/crates/da-clients/celestia/Cargo.toml +++ b/crates/da-clients/celestia/Cargo.toml @@ -17,6 +17,7 @@ jsonrpsee = { version = "0.20.0", features = [ "macros", ] } mockall = "0.12.1" +protobuf = "3.5.0" reqwest = { version = "0.11.18", features = ["blocking", "json"] } rstest = { workspace = true } serde = { version = "1.0.196", default-features = false, features = ["derive"] } From 21a2752d9937626d8283250b7997201be3b09a13 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 12:08:13 +0530 Subject: [PATCH 09/22] update: adding celestia as da on orchestrator --- Cargo.lock | 1 + Cargo.toml | 1 + crates/da-clients/celestia/src/config.rs | 17 ++++++++++++++--- crates/da-clients/celestia/src/lib.rs | 12 ++++++------ crates/orchestrator/Cargo.toml | 1 + crates/orchestrator/src/config.rs | 6 ++++++ 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f265e37..56a93b60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6784,6 +6784,7 @@ dependencies = [ "axum-macros", "bytes", "cairo-vm 1.0.0-rc3", + "celestia-da-client", "color-eyre", "da-client-interface", "dotenvy", diff --git a/Cargo.toml b/Cargo.toml index 40676022..d7395510 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ madara-prover-rpc-client = { git = "https://github.com/Moonsong-Labs/madara-prov # Project da-client-interface = { path = "crates/da-clients/da-client-interface" } ethereum-da-client = { path = "crates/da-clients/ethereum" } +celestia-da-client = { path = "crates/da-clients/celestia" } settlement-client-interface = { path = "crates/settlement-clients/settlement-client-interface" } ethereum-settlement-client = { path = "crates/settlement-clients/ethereum" } diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index a91f9ec1..1233d36e 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -1,5 +1,7 @@ +use da_client_interface::DaConfig; use std::fs::File; use std::path::PathBuf; +use utils::env_utils::get_env_var_or_panic; use serde::Deserialize; @@ -8,7 +10,7 @@ pub const DEFAULT_AUTH_TOKEN: &str = ""; pub const DEFAULT_NID: &str = "Karnot"; #[derive(Clone, PartialEq, Deserialize, Debug)] -pub struct CelestiaConfig { +pub struct CelestiaDaConfig { #[serde(default = "default_http")] pub http_provider: String, #[serde(default)] @@ -17,7 +19,7 @@ pub struct CelestiaConfig { pub nid: String, } -impl TryFrom<&PathBuf> for CelestiaConfig { +impl TryFrom<&PathBuf> for CelestiaDaConfig { type Error = String; fn try_from(path: &PathBuf) -> Result { @@ -39,8 +41,17 @@ fn default_nid() -> String { DEFAULT_NID.to_string() } -impl Default for CelestiaConfig { +impl Default for CelestiaDaConfig { fn default() -> Self { Self { http_provider: default_http(), auth_token: None, nid: default_nid() } } } +impl DaConfig for CelestiaDaConfig { + fn new_from_env() -> Self { + Self { + http_provider: get_env_var_or_panic("CELESTIA_DA_RPC_URL"), + auth_token: Some(get_env_var_or_panic("CELESTIA_DA_AUTH_TOKEN")), + nid: get_env_var_or_panic("CELESTIA_DA_NID"), + } + } +} diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index afc8b11b..12da15a7 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -73,9 +73,9 @@ impl DaClient for CelestiaDaClient { } } -impl TryFrom for CelestiaDaClient { +impl TryFrom for CelestiaDaClient { type Error = anyhow::Error; - fn try_from(conf: config::CelestiaConfig) -> Result { + fn try_from(conf: config::CelestiaDaConfig) -> Result { // Borrowed the below code from https://github.com/eigerco/lumina/blob/ccc5b9bfeac632cccd32d35ecb7b7d51d71fbb87/rpc/src/client.rs#L41. // Directly calling the function wasn't possible as the function is async. Since // we only need to initiate the http provider and not the ws provider, we don't need async @@ -109,12 +109,12 @@ impl TryFrom for CelestiaDaClient { mod tests { use super::*; - use config::{CelestiaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; + use config::{CelestiaDaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; #[tokio::test] #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion() { - let config = CelestiaConfig { + let config = CelestiaDaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), auth_token: None, nid: DEFAULT_NID.to_string(), @@ -159,7 +159,7 @@ mod tests { async fn test_max_blob_per_txn() { let expected_value: u64 = 1; - let config = CelestiaConfig { + let config = CelestiaDaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), auth_token: None, nid: DEFAULT_NID.to_string(), @@ -176,7 +176,7 @@ mod tests { async fn test_max_bytes_per_blob() { let expected_value: u64 = 1974272; - let config = CelestiaConfig { + let config = CelestiaDaConfig { http_provider: DEFAULT_CELESTIA_NODE.to_string(), auth_token: None, nid: DEFAULT_NID.to_string(), diff --git a/crates/orchestrator/Cargo.toml b/crates/orchestrator/Cargo.toml index b622df3f..4efbab7c 100644 --- a/crates/orchestrator/Cargo.toml +++ b/crates/orchestrator/Cargo.toml @@ -21,6 +21,7 @@ axum = { workspace = true, features = ["macros"] } axum-macros = { workspace = true } bytes = "1.6.0" cairo-vm = { workspace = true } +celestia-da-client.workspace = true color-eyre = { workspace = true } da-client-interface = { workspace = true } dotenvy = { workspace = true } diff --git a/crates/orchestrator/src/config.rs b/crates/orchestrator/src/config.rs index a2d82858..17f18962 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -4,6 +4,8 @@ use arc_swap::{ArcSwap, Guard}; use da_client_interface::{DaClient, DaConfig}; use dotenvy::dotenv; use ethereum_da_client::config::EthereumDaConfig; +use celestia_da_client::config::CelestiaDaConfig; +use celestia_da_client::CelestiaDaClient; use ethereum_settlement_client::EthereumSettlementClient; use prover_client_interface::ProverClient; use settlement_client_interface::SettlementClient; @@ -140,6 +142,10 @@ async fn build_da_client() -> Box { let config = EthereumDaConfig::new_from_env(); Box::new(config.build_client().await) } + "celestia" => { + let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); + Box::new(CelestiaDaClient::try_from(config).unwrap()) + } _ => panic!("Unsupported DA layer"), } } From 3cf151b7e61c97bd2a698979c71e8a5a89f86dd5 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 12:18:38 +0530 Subject: [PATCH 10/22] fix: GasPrice to Default in blob_submit --- crates/da-clients/celestia/Cargo.toml | 6 +----- crates/da-clients/celestia/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/da-clients/celestia/Cargo.toml b/crates/da-clients/celestia/Cargo.toml index 9aa7c677..d566d447 100644 --- a/crates/da-clients/celestia/Cargo.toml +++ b/crates/da-clients/celestia/Cargo.toml @@ -11,11 +11,7 @@ celestia-rpc = "0.2.0" celestia-types = "0.2.0" color-eyre = { workspace = true } da-client-interface = { workspace = true } -jsonrpsee = { version = "0.20.0", features = [ - "http-client", - "ws-client", - "macros", -] } +jsonrpsee = { version = "0.20.0", features = ["http-client"] } mockall = "0.12.1" protobuf = "3.5.0" reqwest = { version = "0.11.18", features = ["blocking", "json"] } diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 12da15a7..1f2abb50 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -29,7 +29,7 @@ impl DaClient for CelestiaDaClient { // Submit the blobs to celestia let height = self .celestia_client - .blob_submit(blobs?.as_slice(), GasPrice::from(0.1)) + .blob_submit(blobs?.as_slice(), GasPrice::default()) .await .expect("Failed submitting blobs"); From f93de6a65c2c37432285b0d16a3575b2bbff1061 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 15:41:45 +0530 Subject: [PATCH 11/22] PR Corrections: Celestia Da Client --- crates/da-clients/celestia/src/config.rs | 26 ----- crates/da-clients/celestia/src/lib.rs | 121 +++++++---------------- 2 files changed, 36 insertions(+), 111 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index 1233d36e..826f6f78 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -2,20 +2,12 @@ use da_client_interface::DaConfig; use std::fs::File; use std::path::PathBuf; use utils::env_utils::get_env_var_or_panic; - use serde::Deserialize; -pub const DEFAULT_CELESTIA_NODE: &str = "http://127.0.0.1:8000"; -pub const DEFAULT_AUTH_TOKEN: &str = ""; -pub const DEFAULT_NID: &str = "Karnot"; - #[derive(Clone, PartialEq, Deserialize, Debug)] pub struct CelestiaDaConfig { - #[serde(default = "default_http")] pub http_provider: String, - #[serde(default)] pub auth_token: Option, - #[serde(default = "default_nid")] pub nid: String, } @@ -28,24 +20,6 @@ impl TryFrom<&PathBuf> for CelestiaDaConfig { } } -fn default_http() -> String { - DEFAULT_CELESTIA_NODE.to_string() -} - -// TODO: Auth currently not supported, surpassing from celestia-node using --rpc.skip_auth -// fn default_auth_token() -> String { -// format!("http://{DEFAULT_AUTH_TOKEN}") -// } - -fn default_nid() -> String { - DEFAULT_NID.to_string() -} - -impl Default for CelestiaDaConfig { - fn default() -> Self { - Self { http_provider: default_http(), auth_token: None, nid: default_nid() } - } -} impl DaConfig for CelestiaDaConfig { fn new_from_env() -> Self { Self { diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 1f2abb50..8cedd1b1 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -30,36 +30,21 @@ impl DaClient for CelestiaDaClient { let height = self .celestia_client .blob_submit(blobs?.as_slice(), GasPrice::default()) - .await - .expect("Failed submitting blobs"); + .await?; // // Return back the height of the block that will contain the blob. Ok(height.to_string()) } async fn verify_inclusion(&self, external_id: &str) -> Result { - // TODO: check if feasible and needed ? we can send blob.commitment as a part of external id and use it to call get_blob rather than get_all for more precise answer. - - // External Id : Height of Block the blob is submitted to. - // 2 ways to check : - // Is the current block ahead of the block that we have, if it is does my block contain the blob. - // Call the blob_get_all function of the client - - let height_id = external_id.parse()?; - let retrieved_blobs = self.celestia_client.blob_get_all(height_id, &[self.nid]).await; - - //TODO: Assumption: Given that we are sending only 1 nid, we'll get an array of 1 object back. - - match retrieved_blobs { - Ok(blobs) => { - if blobs.len() == 1 { - Ok(DaVerificationStatus::Verified) - } else { - Ok(DaVerificationStatus::Rejected(format!("Expected 1 blob, but got {}", blobs.len()))) - } - } - Err(e) => Ok(DaVerificationStatus::Rejected(format!("Error occurred: {}", e))), - } + // https://node-rpc-docs.celestia.org/?version=v0.13.7#blob.Submit + // Our Oberservation: + // 1) Submit sends Blobs and reports the height in which they were included. + // 2) It takes submit 1-15 seconds (under right network conditions) depending on the nearest block. + // Assumption : + // blob.Submit is a blocking call that returns only when the BLOCK HAS BEEN INCLUDED. + + Ok(DaVerificationStatus::Verified) } async fn max_blob_per_txn(&self) -> u64 { @@ -68,8 +53,8 @@ impl DaClient for CelestiaDaClient { } async fn max_bytes_per_blob(&self) -> u64 { - //Info: https://github.com/celestiaorg/celestia-node/issues/3356 - 1974272 + //Info: https://docs.celestia.org/nodes/mainnet#maximum-bytes + 1973786 } } @@ -105,21 +90,36 @@ impl TryFrom for CelestiaDaClient { } } +/* +celestia-node - Steps : +1. Run celestia-node, preferred impl https://docs.celestia.org/nodes/docker-images. +2. Ensure to safely note down the account information provided to use later on. +3. Ensure to manually fund the account, see https://docs.celestia.org/nodes/arabica-devnet#arabica-devnet-faucet. +4. Ensure that the account is detected by celestia-node, see https://docs.celestia.org/developers/celestia-node-key#docker-and-cel-key. +5. Remove the #ignores to run the tests. + +Shortcut method to run Celestia as DA : + - define $NETWORK, $RPC_URL, $NODE_TYPE, see https://docs.celestia.org/nodes/docker-images#quick-start. + - skips Auth, setup from https://node-rpc-docs.celestia.org/?version=v0.13.7#node.AuthNew. + - exposes 26658 for RPC communication: https://docs.celestia.org/nodes/celestia-node-troubleshooting#ports, binds it to 8000 of host. + ```bash + docker run --expose 26658 -p 8000:26658 -e NODE_TYPE=$NODE_TYPE -e P2P_NETWORK=$NETWORK -v $HOME/:/home/celestia ghcr.io/celestiaorg/celestia-node:v0.14.0 celestia light start --core.ip $RPC_URL --p2p.network $NETWORK --rpc.port 26658 --rpc.addr 0.0.0.0 --rpc.skip-auth + ``` + - [only for testnet/devnet] Then copy paste all files from `.celestia-light-/keys` to `.celestia-light/keys`, check if account is getting detected, see https://docs.celestia.org/developers/celestia-node-key#using-the-cel-key-utility. + */ + #[cfg(test)] mod tests { + use config::CelestiaDaConfig; + use da_client_interface::DaConfig; + use super::*; - use config::{CelestiaDaConfig, DEFAULT_CELESTIA_NODE, DEFAULT_NID}; #[tokio::test] #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion() { - let config = CelestiaDaConfig { - http_provider: DEFAULT_CELESTIA_NODE.to_string(), - auth_token: None, - nid: DEFAULT_NID.to_string(), - }; - // Instantiate CelestiaDaClient + let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); let s = "Hello World!"; @@ -131,60 +131,11 @@ mod tests { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, ]; - let height_response = celestia_da_client.publish_state_diff(state_diff, &to).await; - - let height_id = match height_response { - Ok(variable) => variable, - Err(error) => panic!("Problem reading: {error:?}"), - }; - - let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await; - - let inclusion = match inclusion_response { - Ok(variable) => variable, - Err(error) => panic!("Problem reading: {error:?}"), - }; - - assert_eq!(inclusion, DaVerificationStatus::Verified); - - match inclusion { - DaVerificationStatus::Pending => println!("Verification Status is Pending"), - DaVerificationStatus::Verified => println!("Verification Status is Verified"), - DaVerificationStatus::Rejected(msg) => println!("Verification Status is Rejected: {}", msg), - } - } - - #[tokio::test] - #[ignore = "Can't run without manual intervention, setup celestia-node."] - async fn test_max_blob_per_txn() { - let expected_value: u64 = 1; - - let config = CelestiaDaConfig { - http_provider: DEFAULT_CELESTIA_NODE.to_string(), - auth_token: None, - nid: DEFAULT_NID.to_string(), - }; - // Instantiate CelestiaDaClient - let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + let height_id = celestia_da_client.publish_state_diff(state_diff, &to).await.expect("Problem reading:"); - let max_blobs_per_txn = celestia_da_client.max_blob_per_txn().await; - assert_eq!(max_blobs_per_txn, expected_value); - } + let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await.expect("Problem reading:"); - #[tokio::test] - #[ignore = "Can't run without manual intervention, setup celestia-node."] - async fn test_max_bytes_per_blob() { - let expected_value: u64 = 1974272; - - let config = CelestiaDaConfig { - http_provider: DEFAULT_CELESTIA_NODE.to_string(), - auth_token: None, - nid: DEFAULT_NID.to_string(), - }; - // Instantiate CelestiaDaClient - let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + assert_eq!(inclusion_response, DaVerificationStatus::Verified); - let max_bytes_per_blob = celestia_da_client.max_bytes_per_blob().await; - assert_eq!(max_bytes_per_blob, expected_value); } } From 3bd0a1a4cf0891f5c882de13a2453c13201cb028 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Fri, 19 Jul 2024 16:06:45 +0530 Subject: [PATCH 12/22] update: add env support for Celestia DA client --- .env.example | 6 ++++++ Cargo.lock | 1 + crates/da-clients/celestia/Cargo.toml | 1 + crates/da-clients/celestia/src/config.rs | 5 +++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 57635205..8561f780 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,12 @@ ETHEREUM_RPC_URL= MEMORY_PAGES_CONTRACT_ADDRESS= STARKNET_SOLIDITY_CORE_CONTRACT_ADDRESS= +# Celestia DA Client +CELESTIA_DA_RPC_URL=http://localhost:8000 +# CELESTIA_DA_AUTH_TOKEN +CELESTIA_DA_NID=Karnot + + # Starknet STARKNET_PUBLIC_KEY= diff --git a/Cargo.lock b/Cargo.lock index 56a93b60..ab6d436a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3197,6 +3197,7 @@ dependencies = [ "celestia-types", "color-eyre", "da-client-interface", + "dotenv", "jsonrpsee", "mockall", "protobuf", diff --git a/crates/da-clients/celestia/Cargo.toml b/crates/da-clients/celestia/Cargo.toml index d566d447..4db79658 100644 --- a/crates/da-clients/celestia/Cargo.toml +++ b/crates/da-clients/celestia/Cargo.toml @@ -11,6 +11,7 @@ celestia-rpc = "0.2.0" celestia-types = "0.2.0" color-eyre = { workspace = true } da-client-interface = { workspace = true } +dotenv = "0.15.0" jsonrpsee = { version = "0.20.0", features = ["http-client"] } mockall = "0.12.1" protobuf = "3.5.0" diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index 826f6f78..2afc5369 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::path::PathBuf; use utils::env_utils::get_env_var_or_panic; use serde::Deserialize; - +use dotenv::dotenv; #[derive(Clone, PartialEq, Deserialize, Debug)] pub struct CelestiaDaConfig { pub http_provider: String, @@ -22,10 +22,11 @@ impl TryFrom<&PathBuf> for CelestiaDaConfig { impl DaConfig for CelestiaDaConfig { fn new_from_env() -> Self { + dotenv().ok(); Self { http_provider: get_env_var_or_panic("CELESTIA_DA_RPC_URL"), auth_token: Some(get_env_var_or_panic("CELESTIA_DA_AUTH_TOKEN")), nid: get_env_var_or_panic("CELESTIA_DA_NID"), } } -} +} \ No newline at end of file From b1223cd2f8cad9dff41b3db139be06d42ea81cf4 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Sat, 20 Jul 2024 12:17:56 +0530 Subject: [PATCH 13/22] chore: proto added to build workflow --- .github/workflows/rust-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml index f7cb3e08..170cebfe 100644 --- a/.github/workflows/rust-build.yml +++ b/.github/workflows/rust-build.yml @@ -17,6 +17,8 @@ jobs: - uses: Swatinem/rust-cache@v2 + - uses: arduino/setup-protoc@v3 + - name: Build the project run: | cargo build --release --workspace From 4f6c4ddd628d7ded2e9f89721d1653b1da69a651 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Sat, 20 Jul 2024 15:21:04 +0530 Subject: [PATCH 14/22] update: build_da_client impl with basic builder --- crates/da-clients/celestia/src/config.rs | 27 +++++------ crates/da-clients/celestia/src/lib.rs | 61 +++++++++++------------- crates/da-clients/ethereum/src/config.rs | 4 ++ crates/orchestrator/src/config.rs | 12 ++++- 4 files changed, 56 insertions(+), 48 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index 2afc5369..a1dec798 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -1,9 +1,10 @@ use da_client_interface::DaConfig; -use std::fs::File; -use std::path::PathBuf; -use utils::env_utils::get_env_var_or_panic; +use async_trait::async_trait; use serde::Deserialize; use dotenv::dotenv; +use celestia_rpc::Client; +use utils::env_utils::{get_env_car_optional_or_panic, get_env_var_or_panic}; + #[derive(Clone, PartialEq, Deserialize, Debug)] pub struct CelestiaDaConfig { pub http_provider: String, @@ -11,22 +12,20 @@ pub struct CelestiaDaConfig { pub nid: String, } -impl TryFrom<&PathBuf> for CelestiaDaConfig { - type Error = String; - fn try_from(path: &PathBuf) -> Result { - let file = File::open(path).map_err(|e| format!("error opening da config: {e}"))?; - serde_json::from_reader(file).map_err(|e| format!("error parsing da config: {e}")) - } -} - -impl DaConfig for CelestiaDaConfig { +#[async_trait] +impl DaConfig for CelestiaDaConfig { + // TODO: Possibility to merge these two ? fn new_from_env() -> Self { dotenv().ok(); Self { http_provider: get_env_var_or_panic("CELESTIA_DA_RPC_URL"), - auth_token: Some(get_env_var_or_panic("CELESTIA_DA_AUTH_TOKEN")), + auth_token: get_env_car_optional_or_panic("CELESTIA_DA_AUTH_TOKEN"), nid: get_env_var_or_panic("CELESTIA_DA_NID"), + } } -} \ No newline at end of file + async fn build_da_client(&self) -> Client{ + Client::new(&self.http_provider, self.auth_token.as_deref()).await.expect("Failed to create Client: ") + } +} \ No newline at end of file diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 8cedd1b1..35a27d86 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -3,22 +3,25 @@ pub mod error; use async_trait::async_trait; use color_eyre::Result; +use config::CelestiaDaConfig; use error::CelestiaDaError; -use jsonrpsee::http_client::{HeaderMap, HeaderValue, HttpClient, HttpClientBuilder}; -use reqwest::header; -use celestia_rpc::BlobClient; +use celestia_rpc::{BlobClient, Client}; use celestia_types::blob::GasPrice; use celestia_types::{nmt::Namespace, Blob}; use da_client_interface::{DaClient, DaVerificationStatus}; -#[derive(Clone, Debug)] pub struct CelestiaDaClient { - celestia_client: HttpClient, + client: Client, nid: Namespace, } +pub struct CelestiaDaConfigAndClient { + pub config : CelestiaDaConfig, + pub client : Client +} + #[async_trait] impl DaClient for CelestiaDaClient { async fn publish_state_diff(&self, state_diff: Vec>, to: &[u8; 32]) -> Result { @@ -28,10 +31,11 @@ impl DaClient for CelestiaDaClient { // Submit the blobs to celestia let height = self - .celestia_client + .client .blob_submit(blobs?.as_slice(), GasPrice::default()) .await?; + println!("{}",height); // // Return back the height of the block that will contain the blob. Ok(height.to_string()) } @@ -58,35 +62,21 @@ impl DaClient for CelestiaDaClient { } } -impl TryFrom for CelestiaDaClient { - type Error = anyhow::Error; - fn try_from(conf: config::CelestiaDaConfig) -> Result { - // Borrowed the below code from https://github.com/eigerco/lumina/blob/ccc5b9bfeac632cccd32d35ecb7b7d51d71fbb87/rpc/src/client.rs#L41. - // Directly calling the function wasn't possible as the function is async. Since - // we only need to initiate the http provider and not the ws provider, we don't need async - - let mut headers = HeaderMap::new(); - // checking if Auth is available - if let Some(auth_token) = conf.auth_token { - let val = HeaderValue::from_str(&format!("Bearer {}", auth_token))?; - headers.insert(header::AUTHORIZATION, val); - } - let http_client = HttpClientBuilder::default() - .set_headers(headers) - .build(conf.http_provider.as_str()) - .map_err(|e| CelestiaDaError::Client(format!("could not init http client: {e}")))?; - - // Convert the input string to bytes - let bytes = conf.nid.as_bytes(); +impl TryFrom for CelestiaDaClient { + type Error = anyhow::Error; + fn try_from(config_and_client: CelestiaDaConfigAndClient) -> Result { + let bytes = config_and_client.config.nid.as_bytes(); - // Create a new Namespace from these bytes let nid = Namespace::new_v0(bytes) - .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) - .unwrap(); + .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) + .unwrap(); - Ok(Self { celestia_client: http_client, nid }) + Ok(Self { + client : config_and_client.client, + nid + }) } } @@ -117,10 +107,17 @@ mod tests { use super::*; #[tokio::test] - #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] + // #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion() { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); - let celestia_da_client = CelestiaDaClient::try_from(config).unwrap(); + let client = config.build_da_client().await; + + let conf_client = CelestiaDaConfigAndClient{ + config, + client + }; + + let celestia_da_client = CelestiaDaClient::try_from(conf_client).unwrap(); let s = "Hello World!"; let bytes: Vec = s.bytes().collect(); diff --git a/crates/da-clients/ethereum/src/config.rs b/crates/da-clients/ethereum/src/config.rs index c5d9b4fb..1d00955a 100644 --- a/crates/da-clients/ethereum/src/config.rs +++ b/crates/da-clients/ethereum/src/config.rs @@ -8,6 +8,7 @@ use c_kzg::KzgSettings; use da_client_interface::DaConfig; use url::Url; use utils::env_utils::get_env_var_or_panic; +use async_trait::async_trait; use crate::EthereumDaClient; @@ -26,6 +27,9 @@ impl DaConfig for EthereumDaConfig { memory_pages_contract: get_env_var_or_panic("MEMORY_PAGES_CONTRACT_ADDRESS"), private_key: get_env_var_or_panic("PRIVATE_KEY"), } + } + async fn build_da_client(&self) -> String{ + "Create Ethereum Client here".to_string() } async fn build_client(&self) -> EthereumDaClient { let client = diff --git a/crates/orchestrator/src/config.rs b/crates/orchestrator/src/config.rs index 17f18962..03d864c9 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -5,7 +5,7 @@ use da_client_interface::{DaClient, DaConfig}; use dotenvy::dotenv; use ethereum_da_client::config::EthereumDaConfig; use celestia_da_client::config::CelestiaDaConfig; -use celestia_da_client::CelestiaDaClient; +use celestia_da_client::{CelestiaDaClient, CelestiaDaConfigAndClient}; use ethereum_settlement_client::EthereumSettlementClient; use prover_client_interface::ProverClient; use settlement_client_interface::SettlementClient; @@ -144,7 +144,15 @@ async fn build_da_client() -> Box { } "celestia" => { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); - Box::new(CelestiaDaClient::try_from(config).unwrap()) + let client = config.build_da_client().await; + + let conf_client = CelestiaDaConfigAndClient{ + config, + client + }; + + // TODO: might want to move away from unwrap ? + Box::new(CelestiaDaClient::try_from(conf_client).unwrap()) } _ => panic!("Unsupported DA layer"), } From af569ed4420d7d6eaafeea3c2a7c32ab0bd1ce17 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Sat, 20 Jul 2024 15:22:07 +0530 Subject: [PATCH 15/22] update: build_Da_client impl without tryFrom --- crates/da-clients/celestia/src/config.rs | 21 +++++++++++++----- crates/da-clients/celestia/src/lib.rs | 28 +----------------------- crates/orchestrator/src/config.rs | 9 +------- 3 files changed, 18 insertions(+), 40 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index a1dec798..cef00a82 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -4,6 +4,9 @@ use serde::Deserialize; use dotenv::dotenv; use celestia_rpc::Client; use utils::env_utils::{get_env_car_optional_or_panic, get_env_var_or_panic}; +use celestia_types::nmt::Namespace; + +use crate::{error::CelestiaDaError, CelestiaDaClient}; #[derive(Clone, PartialEq, Deserialize, Debug)] pub struct CelestiaDaConfig { @@ -14,18 +17,26 @@ pub struct CelestiaDaConfig { #[async_trait] -impl DaConfig for CelestiaDaConfig { - // TODO: Possibility to merge these two ? +impl DaConfig for CelestiaDaConfig { fn new_from_env() -> Self { dotenv().ok(); Self { http_provider: get_env_var_or_panic("CELESTIA_DA_RPC_URL"), auth_token: get_env_car_optional_or_panic("CELESTIA_DA_AUTH_TOKEN"), nid: get_env_var_or_panic("CELESTIA_DA_NID"), - } } - async fn build_da_client(&self) -> Client{ - Client::new(&self.http_provider, self.auth_token.as_deref()).await.expect("Failed to create Client: ") + async fn build_da_client(&self) -> CelestiaDaClient{ + let bytes = self.nid.as_bytes(); + + let nid = Namespace::new_v0(bytes) + .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) + .unwrap(); + let celestia_da_client = Client::new(&self.http_provider, self.auth_token.as_deref()).await.expect("Failed to create Client: "); + + CelestiaDaClient { + client : celestia_da_client, + nid + } } } \ No newline at end of file diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 35a27d86..9f531c29 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -4,7 +4,6 @@ pub mod error; use async_trait::async_trait; use color_eyre::Result; use config::CelestiaDaConfig; -use error::CelestiaDaError; use celestia_rpc::{BlobClient, Client}; use celestia_types::blob::GasPrice; @@ -62,24 +61,6 @@ impl DaClient for CelestiaDaClient { } } - - -impl TryFrom for CelestiaDaClient { - type Error = anyhow::Error; - fn try_from(config_and_client: CelestiaDaConfigAndClient) -> Result { - let bytes = config_and_client.config.nid.as_bytes(); - - let nid = Namespace::new_v0(bytes) - .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) - .unwrap(); - - Ok(Self { - client : config_and_client.client, - nid - }) - } -} - /* celestia-node - Steps : 1. Run celestia-node, preferred impl https://docs.celestia.org/nodes/docker-images. @@ -110,14 +91,7 @@ mod tests { // #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion() { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); - let client = config.build_da_client().await; - - let conf_client = CelestiaDaConfigAndClient{ - config, - client - }; - - let celestia_da_client = CelestiaDaClient::try_from(conf_client).unwrap(); + let celestia_da_client = config.build_da_client().await; let s = "Hello World!"; let bytes: Vec = s.bytes().collect(); diff --git a/crates/orchestrator/src/config.rs b/crates/orchestrator/src/config.rs index 03d864c9..0717ec92 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -145,14 +145,7 @@ async fn build_da_client() -> Box { "celestia" => { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); let client = config.build_da_client().await; - - let conf_client = CelestiaDaConfigAndClient{ - config, - client - }; - - // TODO: might want to move away from unwrap ? - Box::new(CelestiaDaClient::try_from(conf_client).unwrap()) + Box::new(client) } _ => panic!("Unsupported DA layer"), } From 2d0188d3cc6e0b3461a264098406b32600d976ea Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Sat, 20 Jul 2024 15:25:52 +0530 Subject: [PATCH 16/22] update: adding build_client to celestia DA --- crates/da-clients/celestia/src/config.rs | 2 +- crates/da-clients/celestia/src/lib.rs | 2 +- crates/da-clients/ethereum/src/config.rs | 5 +---- crates/orchestrator/src/config.rs | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index cef00a82..2669a797 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -26,7 +26,7 @@ impl DaConfig for CelestiaDaConfig { nid: get_env_var_or_panic("CELESTIA_DA_NID"), } } - async fn build_da_client(&self) -> CelestiaDaClient{ + async fn build_client(&self) -> CelestiaDaClient{ let bytes = self.nid.as_bytes(); let nid = Namespace::new_v0(bytes) diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 9f531c29..8ea1a4dc 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -91,7 +91,7 @@ mod tests { // #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion() { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); - let celestia_da_client = config.build_da_client().await; + let celestia_da_client = config.build_client().await; let s = "Hello World!"; let bytes: Vec = s.bytes().collect(); diff --git a/crates/da-clients/ethereum/src/config.rs b/crates/da-clients/ethereum/src/config.rs index 1d00955a..45e16d51 100644 --- a/crates/da-clients/ethereum/src/config.rs +++ b/crates/da-clients/ethereum/src/config.rs @@ -8,7 +8,6 @@ use c_kzg::KzgSettings; use da_client_interface::DaConfig; use url::Url; use utils::env_utils::get_env_var_or_panic; -use async_trait::async_trait; use crate::EthereumDaClient; @@ -27,10 +26,8 @@ impl DaConfig for EthereumDaConfig { memory_pages_contract: get_env_var_or_panic("MEMORY_PAGES_CONTRACT_ADDRESS"), private_key: get_env_var_or_panic("PRIVATE_KEY"), } - } - async fn build_da_client(&self) -> String{ - "Create Ethereum Client here".to_string() } + async fn build_client(&self) -> EthereumDaClient { let client = RpcClient::new_http(Url::from_str(self.rpc_url.as_str()).expect("Failed to parse ETHEREUM_RPC_URL")); diff --git a/crates/orchestrator/src/config.rs b/crates/orchestrator/src/config.rs index 0717ec92..8b8d5086 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -144,7 +144,7 @@ async fn build_da_client() -> Box { } "celestia" => { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); - let client = config.build_da_client().await; + let client = config.build_client().await; Box::new(client) } _ => panic!("Unsupported DA layer"), From d3dfe9daf6ee3d46870d95969c4959ee7b24b4b7 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Sat, 20 Jul 2024 15:28:08 +0530 Subject: [PATCH 17/22] fixes: formatting build --- crates/da-clients/celestia/src/config.rs | 25 ++++++++++----------- crates/da-clients/celestia/src/lib.rs | 28 ++++++++++-------------- crates/orchestrator/src/config.rs | 3 +-- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/crates/da-clients/celestia/src/config.rs b/crates/da-clients/celestia/src/config.rs index 2669a797..20c79e2d 100644 --- a/crates/da-clients/celestia/src/config.rs +++ b/crates/da-clients/celestia/src/config.rs @@ -1,10 +1,10 @@ -use da_client_interface::DaConfig; use async_trait::async_trait; -use serde::Deserialize; -use dotenv::dotenv; use celestia_rpc::Client; -use utils::env_utils::{get_env_car_optional_or_panic, get_env_var_or_panic}; use celestia_types::nmt::Namespace; +use da_client_interface::DaConfig; +use dotenv::dotenv; +use serde::Deserialize; +use utils::env_utils::{get_env_car_optional_or_panic, get_env_var_or_panic}; use crate::{error::CelestiaDaError, CelestiaDaClient}; @@ -15,7 +15,6 @@ pub struct CelestiaDaConfig { pub nid: String, } - #[async_trait] impl DaConfig for CelestiaDaConfig { fn new_from_env() -> Self { @@ -26,17 +25,15 @@ impl DaConfig for CelestiaDaConfig { nid: get_env_var_or_panic("CELESTIA_DA_NID"), } } - async fn build_client(&self) -> CelestiaDaClient{ + async fn build_client(&self) -> CelestiaDaClient { let bytes = self.nid.as_bytes(); let nid = Namespace::new_v0(bytes) - .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) - .unwrap(); - let celestia_da_client = Client::new(&self.http_provider, self.auth_token.as_deref()).await.expect("Failed to create Client: "); + .map_err(|e| CelestiaDaError::Generic(format!("could not init namespace: {e}"))) + .unwrap(); + let celestia_da_client = + Client::new(&self.http_provider, self.auth_token.as_deref()).await.expect("Failed to create Client: "); - CelestiaDaClient { - client : celestia_da_client, - nid - } + CelestiaDaClient { client: celestia_da_client, nid } } -} \ No newline at end of file +} diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 8ea1a4dc..c6c56840 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -17,8 +17,8 @@ pub struct CelestiaDaClient { } pub struct CelestiaDaConfigAndClient { - pub config : CelestiaDaConfig, - pub client : Client + pub config: CelestiaDaConfig, + pub client: Client, } #[async_trait] @@ -29,23 +29,20 @@ impl DaClient for CelestiaDaClient { state_diff.into_iter().map(|blob_data| Blob::new(self.nid, blob_data)).collect(); // Submit the blobs to celestia - let height = self - .client - .blob_submit(blobs?.as_slice(), GasPrice::default()) - .await?; + let height = self.client.blob_submit(blobs?.as_slice(), GasPrice::default()).await?; - println!("{}",height); + println!("{}", height); // // Return back the height of the block that will contain the blob. Ok(height.to_string()) } async fn verify_inclusion(&self, external_id: &str) -> Result { // https://node-rpc-docs.celestia.org/?version=v0.13.7#blob.Submit - // Our Oberservation: - // 1) Submit sends Blobs and reports the height in which they were included. - // 2) It takes submit 1-15 seconds (under right network conditions) depending on the nearest block. + // Our Oberservation: + // 1) Submit sends Blobs and reports the height in which they were included. + // 2) It takes submit 1-15 seconds (under right network conditions) depending on the nearest block. // Assumption : - // blob.Submit is a blocking call that returns only when the BLOCK HAS BEEN INCLUDED. + // blob.Submit is a blocking call that returns only when the BLOCK HAS BEEN INCLUDED. Ok(DaVerificationStatus::Verified) } @@ -56,24 +53,24 @@ impl DaClient for CelestiaDaClient { } async fn max_bytes_per_blob(&self) -> u64 { - //Info: https://docs.celestia.org/nodes/mainnet#maximum-bytes + //Info: https://docs.celestia.org/nodes/mainnet#maximum-bytes 1973786 } } /* -celestia-node - Steps : +celestia-node - Steps : 1. Run celestia-node, preferred impl https://docs.celestia.org/nodes/docker-images. 2. Ensure to safely note down the account information provided to use later on. 3. Ensure to manually fund the account, see https://docs.celestia.org/nodes/arabica-devnet#arabica-devnet-faucet. 4. Ensure that the account is detected by celestia-node, see https://docs.celestia.org/developers/celestia-node-key#docker-and-cel-key. 5. Remove the #ignores to run the tests. -Shortcut method to run Celestia as DA : +Shortcut method to run Celestia as DA : - define $NETWORK, $RPC_URL, $NODE_TYPE, see https://docs.celestia.org/nodes/docker-images#quick-start. - skips Auth, setup from https://node-rpc-docs.celestia.org/?version=v0.13.7#node.AuthNew. - exposes 26658 for RPC communication: https://docs.celestia.org/nodes/celestia-node-troubleshooting#ports, binds it to 8000 of host. - ```bash + ```bash docker run --expose 26658 -p 8000:26658 -e NODE_TYPE=$NODE_TYPE -e P2P_NETWORK=$NETWORK -v $HOME/:/home/celestia ghcr.io/celestiaorg/celestia-node:v0.14.0 celestia light start --core.ip $RPC_URL --p2p.network $NETWORK --rpc.port 26658 --rpc.addr 0.0.0.0 --rpc.skip-auth ``` - [only for testnet/devnet] Then copy paste all files from `.celestia-light-/keys` to `.celestia-light/keys`, check if account is getting detected, see https://docs.celestia.org/developers/celestia-node-key#using-the-cel-key-utility. @@ -107,6 +104,5 @@ mod tests { let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await.expect("Problem reading:"); assert_eq!(inclusion_response, DaVerificationStatus::Verified); - } } diff --git a/crates/orchestrator/src/config.rs b/crates/orchestrator/src/config.rs index 8b8d5086..e634f551 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -1,11 +1,10 @@ use std::sync::Arc; use arc_swap::{ArcSwap, Guard}; +use celestia_da_client::config::CelestiaDaConfig; use da_client_interface::{DaClient, DaConfig}; use dotenvy::dotenv; use ethereum_da_client::config::EthereumDaConfig; -use celestia_da_client::config::CelestiaDaConfig; -use celestia_da_client::{CelestiaDaClient, CelestiaDaConfigAndClient}; use ethereum_settlement_client::EthereumSettlementClient; use prover_client_interface::ProverClient; use settlement_client_interface::SettlementClient; From 2ec62d2dc9e27dc8240845396db0362d59bd1468 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Sat, 20 Jul 2024 15:35:56 +0530 Subject: [PATCH 18/22] Update linters-cargo.yml Adding protobuffs dependency --- .github/workflows/linters-cargo.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linters-cargo.yml b/.github/workflows/linters-cargo.yml index 96172230..c207664f 100644 --- a/.github/workflows/linters-cargo.yml +++ b/.github/workflows/linters-cargo.yml @@ -10,6 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - uses: arduino/setup-protoc@v3 # selecting a toolchain either by action or manual `rustup` calls should happen # before the plugin, as the cache uses the current rustc version as its cache key From b7e26a9a4f7575a74784c8c92eb95e4b967146f3 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Mon, 22 Jul 2024 17:53:29 +0530 Subject: [PATCH 19/22] chore: cleanup --- .env.example | 4 ++-- crates/da-clients/celestia/src/lib.rs | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 8561f780..840818d4 100644 --- a/.env.example +++ b/.env.example @@ -13,9 +13,9 @@ STARKNET_SOLIDITY_CORE_CONTRACT_ADDRESS= # Celestia DA Client CELESTIA_DA_RPC_URL=http://localhost:8000 -# CELESTIA_DA_AUTH_TOKEN CELESTIA_DA_NID=Karnot - +# Optional : +CELESTIA_DA_AUTH_TOKEN= # Starknet diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index c6c56840..f3903c37 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -31,7 +31,6 @@ impl DaClient for CelestiaDaClient { // Submit the blobs to celestia let height = self.client.blob_submit(blobs?.as_slice(), GasPrice::default()).await?; - println!("{}", height); // // Return back the height of the block that will contain the blob. Ok(height.to_string()) } @@ -85,7 +84,7 @@ mod tests { use super::*; #[tokio::test] - // #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] + #[ignore = "Can't run without manual intervention, setup celestia-node and fund address."] async fn test_celestia_publish_state_diff_and_verify_inclusion() { let config: CelestiaDaConfig = CelestiaDaConfig::new_from_env(); let celestia_da_client = config.build_client().await; @@ -99,9 +98,9 @@ mod tests { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, ]; - let height_id = celestia_da_client.publish_state_diff(state_diff, &to).await.expect("Problem reading:"); + let height_id = celestia_da_client.publish_state_diff(state_diff, &to).await.expect("Failed to publish state diff:"); - let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await.expect("Problem reading:"); + let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await.expect("Failed to verify inclusion:"); assert_eq!(inclusion_response, DaVerificationStatus::Verified); } From 8342b02e131a624f044ae60f73d26172a17888d5 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Tue, 30 Jul 2024 12:03:37 +0530 Subject: [PATCH 20/22] update: added protoc to CI + linting fix --- .github/workflows/coverage.yml | 1 + crates/da-clients/celestia/src/lib.rs | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 29f80c5a..363947ca 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -12,6 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 + - uses: arduino/setup-protoc@v3 # selecting a toolchain either by action or manual `rustup` calls should happen # before the plugin, as the cache uses the current rustc version as its cache key diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index f3903c37..41c1106c 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -98,9 +98,11 @@ mod tests { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, ]; - let height_id = celestia_da_client.publish_state_diff(state_diff, &to).await.expect("Failed to publish state diff:"); + let height_id = + celestia_da_client.publish_state_diff(state_diff, &to).await.expect("Failed to publish state diff:"); - let inclusion_response = celestia_da_client.verify_inclusion(&height_id).await.expect("Failed to verify inclusion:"); + let inclusion_response = + celestia_da_client.verify_inclusion(&height_id).await.expect("Failed to verify inclusion:"); assert_eq!(inclusion_response, DaVerificationStatus::Verified); } From df2596ef8e7ce8af8f7fba41040a45955dfa406d Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Tue, 30 Jul 2024 12:05:01 +0530 Subject: [PATCH 21/22] docs: changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40fd1c8d..3ead1e32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - Function to calculate the kzg proof of x_0. - Tests for updating the state. - Function to update the state and publish blob on ethereum in state update job. +- Celestia as DA client. ## Changed From dbba591813ae8a409049e0dbcb02ac6609404b7a Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Tue, 30 Jul 2024 12:09:50 +0530 Subject: [PATCH 22/22] chore: linting --- crates/da-clients/celestia/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs index 41c1106c..5cd36919 100644 --- a/crates/da-clients/celestia/src/lib.rs +++ b/crates/da-clients/celestia/src/lib.rs @@ -23,7 +23,7 @@ pub struct CelestiaDaConfigAndClient { #[async_trait] impl DaClient for CelestiaDaClient { - async fn publish_state_diff(&self, state_diff: Vec>, to: &[u8; 32]) -> Result { + async fn publish_state_diff(&self, state_diff: Vec>, _to: &[u8; 32]) -> Result { // Convert the state_diffs into Blobs let blobs: Result, _> = state_diff.into_iter().map(|blob_data| Blob::new(self.nid, blob_data)).collect(); @@ -35,7 +35,7 @@ impl DaClient for CelestiaDaClient { Ok(height.to_string()) } - async fn verify_inclusion(&self, external_id: &str) -> Result { + async fn verify_inclusion(&self, _external_id: &str) -> Result { // https://node-rpc-docs.celestia.org/?version=v0.13.7#blob.Submit // Our Oberservation: // 1) Submit sends Blobs and reports the height in which they were included.