diff --git a/.env.example b/.env.example index 57635205..840818d4 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_NID=Karnot +# Optional : +CELESTIA_DA_AUTH_TOKEN= + # Starknet STARKNET_PUBLIC_KEY= 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/.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 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 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 diff --git a/Cargo.lock b/Cargo.lock index 57c82755..bfccd7aa 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" @@ -2311,6 +2338,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" @@ -2380,6 +2416,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" @@ -2442,6 +2490,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" @@ -3071,7 +3128,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "starknet-crypto 0.6.2", "starknet-curve 0.4.2", @@ -3105,7 +3162,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "starknet-crypto 0.6.2", "starknet-types-core", @@ -3139,6 +3196,135 @@ dependencies = [ "once_cell", ] +[[package]] +name = "celestia-da-client" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "celestia-rpc", + "celestia-types", + "color-eyre", + "da-client-interface", + "dotenv", + "jsonrpsee", + "mockall", + "protobuf", + "reqwest 0.11.27", + "rstest 0.18.2", + "serde", + "serde_json", + "thiserror", + "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" @@ -3167,6 +3353,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" @@ -3363,6 +3561,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" @@ -3482,6 +3689,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" @@ -3617,6 +3837,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" @@ -3729,7 +3969,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", @@ -3893,6 +4133,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" @@ -3980,6 +4243,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" @@ -4035,7 +4310,7 @@ dependencies = [ "scrypt 0.10.0", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "thiserror", "uuid 0.8.2", @@ -4260,6 +4535,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" @@ -4809,6 +5094,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" @@ -5429,6 +5723,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" @@ -5454,7 +5864,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", - "sha2", + "sha2 0.10.8", "signature 2.2.0", ] @@ -5525,7 +5935,7 @@ checksum = "7fb5d4f22241504f7c7b8d2c3a7d7835d7c07117f10bff2a7d96a9ef6ef217c3" dependencies = [ "lambdaworks-math", "serde", - "sha2", + "sha2 0.10.8", "sha3", ] @@ -5576,6 +5986,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" @@ -5624,6 +6045,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" @@ -5928,8 +6364,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", @@ -5945,6 +6381,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" @@ -5981,6 +6463,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" @@ -6052,6 +6544,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" @@ -6222,6 +6725,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" @@ -6288,6 +6797,7 @@ dependencies = [ "bytes", "c-kzg", "cairo-vm 1.0.0-rc3", + "celestia-da-client", "color-eyre", "da-client-interface", "dotenvy", @@ -6361,7 +6871,7 @@ dependencies = [ "rand", "rc2", "sha1", - "sha2", + "sha2 0.10.8", "thiserror", "x509-parser", ] @@ -6374,7 +6884,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -6397,7 +6907,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", @@ -6562,7 +7072,7 @@ dependencies = [ "digest 0.10.7", "hmac", "password-hash", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -6769,7 +7279,7 @@ dependencies = [ "der 0.7.9", "pbkdf2 0.12.2", "scrypt 0.11.0", - "sha2", + "sha2 0.10.8", "spki 0.7.3", ] @@ -6912,6 +7422,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" @@ -6984,6 +7504,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" @@ -7006,6 +7547,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" @@ -7025,6 +7586,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" @@ -7829,7 +8399,7 @@ dependencies = [ "hmac", "pbkdf2 0.11.0", "salsa20", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -7840,7 +8410,7 @@ checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ "pbkdf2 0.12.2", "salsa20", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -8169,6 +8739,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" @@ -8197,6 +8780,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" @@ -8417,6 +9013,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" @@ -8557,7 +9168,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", @@ -8577,7 +9188,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", @@ -8864,6 +9475,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" @@ -9332,6 +9958,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" @@ -9668,6 +10305,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 b715e867..d0915d99 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] @@ -78,6 +79,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/Cargo.toml b/crates/da-clients/celestia/Cargo.toml new file mode 100644 index 00000000..4db79658 --- /dev/null +++ b/crates/da-clients/celestia/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "celestia-da-client" +version.workspace = true +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.0" +jsonrpsee = { version = "0.20.0", features = ["http-client"] } +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"] } +serde_json.workspace = true +thiserror.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..20c79e2d --- /dev/null +++ b/crates/da-clients/celestia/src/config.rs @@ -0,0 +1,39 @@ +use async_trait::async_trait; +use celestia_rpc::Client; +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}; + +#[derive(Clone, PartialEq, Deserialize, Debug)] +pub struct CelestiaDaConfig { + pub http_provider: String, + pub auth_token: Option, + pub nid: String, +} + +#[async_trait] +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_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 } + } +} diff --git a/crates/da-clients/celestia/src/error.rs b/crates/da-clients/celestia/src/error.rs new file mode 100644 index 00000000..36f109f3 --- /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; diff --git a/crates/da-clients/celestia/src/lib.rs b/crates/da-clients/celestia/src/lib.rs new file mode 100644 index 00000000..5cd36919 --- /dev/null +++ b/crates/da-clients/celestia/src/lib.rs @@ -0,0 +1,109 @@ +pub mod config; +pub mod error; + +use async_trait::async_trait; +use color_eyre::Result; +use config::CelestiaDaConfig; + +use celestia_rpc::{BlobClient, Client}; +use celestia_types::blob::GasPrice; +use celestia_types::{nmt::Namespace, Blob}; + +use da_client_interface::{DaClient, DaVerificationStatus}; + +pub struct CelestiaDaClient { + 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 { + // Convert the state_diffs into Blobs + 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.client.blob_submit(blobs?.as_slice(), GasPrice::default()).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 { + // 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 { + //Info: No docs suggest a number, default to 1. + 1 + } + + async fn max_bytes_per_blob(&self) -> u64 { + //Info: https://docs.celestia.org/nodes/mainnet#maximum-bytes + 1973786 + } +} + +/* +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::*; + + #[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 = CelestiaDaConfig::new_from_env(); + let celestia_da_client = config.build_client().await; + + 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_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:"); + + assert_eq!(inclusion_response, DaVerificationStatus::Verified); + } +} diff --git a/crates/da-clients/ethereum/src/config.rs b/crates/da-clients/ethereum/src/config.rs index b50604b2..c9cdeb35 100644 --- a/crates/da-clients/ethereum/src/config.rs +++ b/crates/da-clients/ethereum/src/config.rs @@ -24,6 +24,7 @@ impl DaConfig for EthereumDaConfig { private_key: get_env_var_or_panic("PRIVATE_KEY"), } } + 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/Cargo.toml b/crates/orchestrator/Cargo.toml index 6ca4c43f..6673d67b 100644 --- a/crates/orchestrator/Cargo.toml +++ b/crates/orchestrator/Cargo.toml @@ -24,6 +24,7 @@ bincode = { workspace = true } bytes = "1.6.0" c-kzg = { workspace = true } 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 41ce3824..358e2443 100644 --- a/crates/orchestrator/src/config.rs +++ b/crates/orchestrator/src/config.rs @@ -4,6 +4,7 @@ use crate::data_storage::aws_s3::config::AWSS3Config; use crate::data_storage::aws_s3::AWSS3; use crate::data_storage::{DataStorage, DataStorageConfig}; 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; @@ -154,6 +155,11 @@ 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(); + let client = config.build_client().await; + Box::new(client) + } _ => panic!("Unsupported DA layer"), } }