diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 84f486156..08aa21a9c 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -231,50 +231,51 @@ jobs: fi make CERAMIC_ONE_IMAGE_TAG="${{ needs.build.outputs.image_tag }}" TEST_SELECTOR="$test_selector" HERMETIC_CMD=../bin/hermetic-driver hermetic-tests - run-migration-tests: - name: Run Migration Tests - runs-on: ubuntu-latest - environment: tnet-prod-2024 - needs: - - build-driver - - publish-suite - - generate-matrix #Needed to know the BUILD_TAG - - build - steps: - - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup GKE auth - uses: 'google-github-actions/auth@v1' - with: - credentials_json: ${{ secrets.GKE_SA_KEY }} - - - name: Get GKE credentials - uses: 'google-github-actions/get-gke-credentials@v1' - with: - cluster_name: ${{ vars.GKE_CLUSTER }} - location: ${{ vars.GKE_ZONE }} - - uses: actions/download-artifact@master - with: - name: hermetic-driver - path: ./bin - - - name: Test migration ${{ matrix.networks }} - run: | - set -euxo pipefail - cd tests - export BUILD_TAG=${{ needs.generate-matrix.outputs.build_tag }} - TEST_NETWORK=./migration-networks/basic-go-rust-post.yaml - chmod +x ../bin/hermetic-driver - - make CERAMIC_ONE_IMAGE_TAG="${{ needs.build.outputs.image_tag }}" HERMETIC_CMD=../bin/hermetic-driver migration-tests +# run-migration-tests: +# name: Run Migration Tests +# runs-on: ubuntu-latest +# environment: tnet-prod-2024 +# needs: +# - build-driver +# - publish-suite +# - generate-matrix #Needed to know the BUILD_TAG +# - build +# steps: +# - +# name: Checkout +# uses: actions/checkout@v3 +# - +# name: Setup GKE auth +# uses: 'google-github-actions/auth@v1' +# with: +# credentials_json: ${{ secrets.GKE_SA_KEY }} +# - +# name: Get GKE credentials +# uses: 'google-github-actions/get-gke-credentials@v1' +# with: +# cluster_name: ${{ vars.GKE_CLUSTER }} +# location: ${{ vars.GKE_ZONE }} +# - uses: actions/download-artifact@master +# with: +# name: hermetic-driver +# path: ./bin +# - +# name: Test migration ${{ matrix.networks }} +# run: | +# set -euxo pipefail +# cd tests +# export BUILD_TAG=${{ needs.generate-matrix.outputs.build_tag }} +# TEST_NETWORK=./migration-networks/basic-go-rust-post.yaml +# chmod +x ../bin/hermetic-driver +# +# make CERAMIC_ONE_IMAGE_TAG="${{ needs.build.outputs.image_tag }}" HERMETIC_CMD=../bin/hermetic-driver migration-tests integration-test-results: name: Hermetic Test Results if: ${{ always() }} runs-on: ubuntu-latest - needs: [run-integration-tests, run-migration-tests] +# needs: [run-integration-tests, run-migration-tests] + needs: [run-integration-tests] steps: - run: exit 1 # see https://stackoverflow.com/a/67532120/4907315 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 70712debc..6c99e66df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,6 +15,18 @@ Using the makefile is not necessary during your development cycle, feel free to However running `make` before publishing a PR will provide a good signal if you PR will pass CI. +### Migrations + +If you need to add to the sqlite database schema, you will need to add a migration using the sqlx CLI. + +```sh +cargo install sqlx-cli +# use the name of the migration and the source directory +sqlx migrate add -r "chain_proof" --source ./migrations/sqlite +``` + +After the up and down files are generated, write the apply/revert SQL in the up/down files. This will be applied automatically at startup. + ### Testing Specific Changes The above `make` targets test changes as a whole. diff --git a/Cargo.lock b/Cargo.lock index f0d240e04..bc64e16d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,7 +75,7 @@ dependencies = [ "once_cell", "serde", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -110,9 +110,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f18703431261fdb54ca49eb949aa1bb8fcb436cf7c1283a0fbbc3d3cd9fadd7" +checksum = "056f2c01b2aed86e15b43c47d109bfc8b82553dc34e66452875e51247ec31ab2" dependencies = [ "alloy-consensus", "alloy-core", @@ -129,19 +129,20 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.34" +version = "0.1.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8158b4878c67837e5413721cc44298e6a2d88d39203175ea025e51892a16ba4c" +checksum = "28e2652684758b0d9b389d248b209ed9fd9989ef489a550265fe4bb8454fe7eb" dependencies = [ + "alloy-primitives", "num_enum 0.7.3", - "strum", + "strum 0.27.1", ] [[package]] name = "alloy-consensus" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "089cd553dc0b372831f3ce871a31921ba8a851ddd51f312a89fb987a00fb6e2c" +checksum = "705687d5bfd019fee57cf9e206b27b30a9a9617535d5590a02b171e813208f8e" dependencies = [ "alloy-eips", "alloy-primitives", @@ -155,9 +156,9 @@ dependencies = [ [[package]] name = "alloy-core" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce854562e7cafd5049189d0268d6e5cba05fe6c9cb7c6f8126a79b94800629c" +checksum = "9d8bcce99ad10fe02640cfaec1c6bc809b837c783c1d52906aa5af66e2a196f6" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -168,9 +169,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b499852e1d0e9b8c6db0f24c48998e647c0d5762a01090f955106a7700e4611" +checksum = "eb8e762aefd39a397ff485bc86df673465c4ad3ec8819cc60833a8a3ba5cdc87" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -180,7 +181,7 @@ dependencies = [ "itoa", "serde", "serde_json", - "winnow 0.6.20", + "winnow 0.7.6", ] [[package]] @@ -208,9 +209,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfe755025743aa133536db98904e6e4b5481c5b2ec864ff56b5b516611a8d34" +checksum = "6ffb906284a1e1f63c4607da2068c8197458a352d0b3e9796e67353d72a9be85" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -226,9 +227,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cbb8b3851cf6e8cc81c697352b4120f34bda362aa279e59e670c3660efa9db0" +checksum = "8429cf4554eed9b40feec7f4451113e76596086447550275e3def933faf47ce3" dependencies = [ "alloy-primitives", "alloy-serde", @@ -237,9 +238,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a438d4486b5d525df3b3004188f9d5cd1d65cd30ecc41e5a3ccef6f6342e8af9" +checksum = "fe6beff64ad0aa6ad1019a3db26fef565aefeb011736150ab73ed3366c3cfd1b" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -249,9 +250,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e136f67d5921b150124e8a76573357005a4ae419ddfe4a2a2b96d21e3a67b9c4" +checksum = "f8fa8a1a3c4cbd221f2b8e3693aeb328fca79a757fe556ed08e47bbbc2a70db7" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -263,9 +264,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7050e189311c607064b08383db700787f2ed49b8db4cd9b7e26f6f124729abac" +checksum = "85fa23a6a9d612b52e402c995f2d582c25165ec03ac6edf64c861a76bc5b87cd" dependencies = [ "alloy-consensus", "alloy-eips", @@ -284,9 +285,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a5f401d05d9d721ca18b0498956c8e771285b3ab211d0695c3c6e8b9121ea" +checksum = "801492711d4392b2ccf5fc0bc69e299fa1aab15167d74dcaa9aab96a54f684bd" dependencies = [ "alloy-consensus", "alloy-eips", @@ -297,17 +298,17 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260d3ff3bff0bb84599f032a2f2c6828180b0ea0cd41fdaf44f39cef3ba41861" +checksum = "8c77490fe91a0ce933a1f219029521f20fc28c2c0ca95d53fa4da9c00b8d9d4e" dependencies = [ "alloy-rlp", "bytes 1.7.2", "cfg-if", "const-hex", - "derive_more 1.0.0", - "hashbrown 0.14.5", - "hex-literal", + "derive_more 2.0.1", + "foldhash", + "hashbrown 0.15.2", "indexmap 2.7.1", "itoa", "k256 0.13.4", @@ -324,9 +325,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3b9667c337d9d0fa25cb476f4d8af84aee8a25fbcccf9b1aa6d554306885e4" +checksum = "fcfaa4ffec0af04e3555686b8aacbcdf7d13638133a0672749209069750f78a6" dependencies = [ "alloy-chains", "alloy-consensus", @@ -358,9 +359,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" +checksum = "3d6c1d995bff8d011f7cd6c81820d51825e6e06d6db73914c1630ecf544d83d6" dependencies = [ "alloy-rlp-derive", "arrayvec 0.7.6", @@ -369,9 +370,9 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" +checksum = "a40e1ef334153322fd878d07e86af7a529bcb86b2439525920a88eba87bcf943" dependencies = [ "proc-macro2", "quote", @@ -380,9 +381,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a86e548f0e92e2bcaafb0b3a8f4238384798dca780d69f3f1b1eb7ade2812924" +checksum = "370143ed581aace6e663342d21d209c6b2e34ee6142f7d6675adb518deeaf0dc" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -402,9 +403,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acf60f133ed3308e42ecff81b6ff76be2d4e2a14af2d537413267bcdccd1c49" +checksum = "9ffc534b7919e18f35e3aa1f507b6f3d9d92ec298463a9f6beaac112809d8d06" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -414,9 +415,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2f4ebadbae37cfd66c4912a56b1dde9573c2440533d43b90bf0c1740179ee4" +checksum = "413f4aa3ccf2c3e4234a047c5fa4727916d7daf25a89f9b765df0ba09784fd87" dependencies = [ "alloy-consensus", "alloy-eips", @@ -433,9 +434,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e75aed754756184a2071b0a0f5680b76ae5aaf3faf8006b461811c4c2cac06" +checksum = "9dff0ab1cdd43ca001e324dc27ee0e8606bd2161d6623c63e0e0b8c4dfc13600" dependencies = [ "alloy-primitives", "serde", @@ -444,9 +445,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e204a603220a68d07796d9e12ebf3a6f701c5d26925be3d0d7962901d6e037e" +checksum = "2fd4e0ad79c81a27ca659be5d176ca12399141659fef2bcbfdc848da478f4504" dependencies = [ "alloy-primitives", "async-trait", @@ -458,9 +459,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e7f6e8fe5b443f82b3f1e15abfa191128f71569148428e49449d01f6f49e8b" +checksum = "e10ae8e9a91d328ae954c22542415303919aabe976fe7a92eb06db1b68fd59f2" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -472,9 +473,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b96ce28d2fde09abb6135f410c41fad670a3a770b6776869bd852f1df102e6f" +checksum = "83ad5da86c127751bc607c174d6c9fe9b85ef0889a9ca0c641735d77d4f98f26" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -490,13 +491,14 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "906746396a8296537745711630d9185746c0b50c033d5e9d18b0a6eba3d53f90" +checksum = "ba3d30f0d3f9ba3b7686f3ff1de9ee312647aac705604417a2f40c604f409a9e" dependencies = [ "const-hex", "dunce", "heck 0.5.0", + "macro-string", "proc-macro2", "quote", "syn 2.0.98", @@ -505,19 +507,19 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc85178909a49c8827ffccfc9103a7ce1767ae66a801b69bdc326913870bf8e6" +checksum = "6d162f8524adfdfb0e4bd0505c734c985f3e2474eb022af32eef0d52a4f3935c" dependencies = [ "serde", - "winnow 0.6.20", + "winnow 0.7.6", ] [[package]] name = "alloy-sol-types" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a533ce22525969661b25dfe296c112d35eb6861f188fd284f8bd4bb3842ae" +checksum = "d43d5e60466a440230c07761aa67671d4719d46f43be8ea6e7ed334d8db4a9ab" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -528,9 +530,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c68e829f89855f79d9635800cf8d0c23f7faaecdade1dc446716f27304dd08e" +checksum = "2ac3e97dad3d31770db0fc89bd6a63b789fbae78963086733f960cf32c483904" dependencies = [ "alloy-json-rpc", "base64 0.22.1", @@ -547,9 +549,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b27d8c6bed88f19e9c5da656cb9e5c69882d8ee8a457f0546ff12d89c766d1" +checksum = "b367dcccada5b28987c2296717ee04b9a5637aacd78eacb1726ef211678b5212" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -1467,9 +1469,9 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", @@ -1852,9 +1854,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +checksum = "47c79a94619fade3c0b887670333513a67ac28a6a7e653eb260bf0d4103db38d" dependencies = [ "cc", "glob", @@ -1930,9 +1932,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "bytecount" @@ -2087,9 +2089,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.24" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "jobserver", "libc", @@ -2316,6 +2318,7 @@ dependencies = [ name = "ceramic-event-svc" version = "0.54.2" dependencies = [ + "alloy", "anyhow", "async-trait", "bytes 1.7.2", @@ -2336,19 +2339,23 @@ dependencies = [ "ipld-core", "iroh-bitswap", "itertools 0.13.0", + "lru 0.10.1", "mockall", "multibase 0.9.1", "multihash 0.19.1", "multihash-codetable", "multihash-derive 0.9.0", + "once_cell", "paste", "prettytable-rs", "prometheus-client", "rand 0.8.5", "recon", + "reqwest 0.11.27", "serde", "serde_ipld_dagcbor", "sqlx", + "ssi", "test-log", "thiserror 1.0.64", "tmpdir", @@ -2719,12 +2726,10 @@ dependencies = [ "ed25519-dalek 2.1.1", "ipld-core", "k256 0.13.4", - "lru 0.10.1", "multibase 0.9.1", "multihash-codetable", "once_cell", "p256 0.13.2", - "reqwest 0.11.27", "serde", "serde_ipld_dagcbor", "serde_json", @@ -2960,8 +2965,8 @@ version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum", - "strum_macros", + "strum 0.26.3", + "strum_macros 0.26.4", "unicode-width", ] @@ -3015,9 +3020,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -4147,7 +4152,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", ] [[package]] @@ -4162,6 +4176,18 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", + "unicode-xid", +] + [[package]] name = "did-method-key" version = "0.2.2" @@ -4371,9 +4397,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" dependencies = [ "serde", ] @@ -4597,6 +4623,17 @@ dependencies = [ "bytes 1.7.2", ] +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec 0.7.6", + "auto_impl", + "bytes 1.7.2", +] + [[package]] name = "ff" version = "0.12.1" @@ -5208,7 +5245,6 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", - "serde", ] [[package]] @@ -5220,6 +5256,7 @@ dependencies = [ "allocator-api2", "equivalent", "foldhash", + "serde", ] [[package]] @@ -5289,12 +5326,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hex_fmt" version = "0.3.0" @@ -5897,13 +5928,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.98", ] [[package]] @@ -7624,6 +7655,17 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "match_cfg" version = "0.1.0" @@ -8312,12 +8354,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" @@ -8737,12 +8776,12 @@ checksum = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c" [[package]] name = "pest" -version = "2.7.13" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ "memchr", - "thiserror 1.0.64", + "thiserror 2.0.11", "ucd-trie", ] @@ -9033,7 +9072,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -9246,12 +9285,12 @@ dependencies = [ [[package]] name = "proptest" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ - "bit-set 0.5.3", - "bit-vec 0.6.3", + "bit-set 0.8.0", + "bit-vec 0.8.0", "bitflags 2.6.0", "lazy_static", "num-traits", @@ -9609,6 +9648,17 @@ dependencies = [ "serde", ] +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.24", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -9629,6 +9679,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -9647,6 +9707,15 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -10136,21 +10205,24 @@ dependencies = [ [[package]] name = "ruint" -version = "1.12.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +checksum = "78a46eb779843b2c4f21fac5773e25d6d5b7c8f0922876c91541790d2ca27eef" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes 1.7.2", - "fastrlp", + "fastrlp 0.3.1", + "fastrlp 0.4.0", "num-bigint", + "num-integer", "num-traits", "parity-scale-codec", "primitive-types 0.12.2", "proptest", "rand 0.8.5", + "rand 0.9.0", "rlp", "ruint-macro", "serde", @@ -10172,9 +10244,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-hex" @@ -10528,9 +10600,9 @@ dependencies = [ [[package]] name = "semver-parser" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" dependencies = [ "pest", ] @@ -11785,8 +11857,14 @@ name = "strum" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" dependencies = [ - "strum_macros", + "strum_macros 0.27.1", ] [[package]] @@ -11802,6 +11880,19 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "strum_macros" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.98", +] + [[package]] name = "substrait" version = "0.52.3" @@ -11877,9 +11968,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.5" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab661c8148c2261222a4d641ad5477fd4bea79406a99056096a0b41b35617a5" +checksum = "4560533fbd6914b94a8fb5cc803ed6801c3455668db3b810702c57612bac9412" dependencies = [ "paste", "proc-macro2", @@ -13000,9 +13091,9 @@ checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] @@ -13427,9 +13518,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] @@ -13621,7 +13712,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", ] [[package]] @@ -13635,6 +13735,17 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "zerofrom" version = "0.1.5" diff --git a/Cargo.toml b/Cargo.toml index 1619779f0..ced2b3a8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ members = [ # e.g. anyhow's backtrace feature. ahash = "0.8" +alloy = { version = "0.4", features = ["k256", "provider-http", "rpc-types"] } anyhow = { version = "1" } arrow = { version = "54", features = ["prettyprint"] } arrow-array = "54" diff --git a/event-svc/Cargo.toml b/event-svc/Cargo.toml index 321c641f8..6b1a6b929 100644 --- a/event-svc/Cargo.toml +++ b/event-svc/Cargo.toml @@ -8,6 +8,8 @@ repository.workspace = true publish = false [dependencies] +# will probably need contract and signer-local features for self anchoring +alloy.workspace = true anyhow.workspace = true async-trait.workspace = true bytes.workspace = true @@ -29,10 +31,14 @@ itertools.workspace = true multihash-codetable.workspace = true multihash-derive.workspace = true multihash.workspace = true +lru.workspace = true +once_cell.workspace = true prometheus-client.workspace = true recon.workspace = true +reqwest.workspace = true serde.workspace = true serde_ipld_dagcbor.workspace = true +ssi.workspace = true sqlx.workspace = true thiserror.workspace = true tokio.workspace = true diff --git a/validation/src/blockchain/eth_rpc/http.rs b/event-svc/src/blockchain/eth_rpc/http.rs similarity index 96% rename from validation/src/blockchain/eth_rpc/http.rs rename to event-svc/src/blockchain/eth_rpc/http.rs index 146b47a31..08a26b0a7 100644 --- a/validation/src/blockchain/eth_rpc/http.rs +++ b/event-svc/src/blockchain/eth_rpc/http.rs @@ -5,7 +5,9 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::eth_rpc::{ChainInclusion, ChainInclusionProof, Error}; +use crate::eth_rpc::{ + types::ChainProofMetadata, ChainInclusion, ChainInclusionProof, Error, Timestamp, +}; use alloy::{ hex, primitives::{BlockHash, TxHash}, @@ -60,7 +62,6 @@ const BLOCK_CACHE_SIZE: usize = 50; type Result = std::result::Result; -#[derive(Debug)] /// Http client to interact with EIP chains pub struct HttpEthRpc { chain_id: caip2::ChainId, @@ -195,11 +196,6 @@ fn get_root_cid_from_input(input: &str, tx_type: EthProofType) -> anyhow::Result } } -/// Get the expected transaction hash for a given root CID (this is v1 proof type) -fn expected_tx_hash(cid: Cid) -> anyhow::Result { - Ok(TxHash::from_str(&hex::encode(cid.hash().digest()))?) -} - #[async_trait::async_trait] impl ChainInclusion for HttpEthRpc { fn chain_id(&self) -> &caip2::ChainId { @@ -209,7 +205,7 @@ impl ChainInclusion for HttpEthRpc { /// Get the block chain transaction if it exists with the block timestamp information async fn get_chain_inclusion_proof(&self, input: &AnchorProof) -> Result { // transaction to blockHash, blockNumber, input - let tx_hash = expected_tx_hash(input.tx_hash()) + let tx_hash = crate::blockchain::tx_hash_try_from_cid(input.tx_hash()) .map_err(|e| Error::InvalidArgument(format!("invalid transaction hash: {}", e)))?; let tx_hash_res = match self.eth_transaction_by_hash(tx_hash).await? { Some(tx) => tx, @@ -240,7 +236,8 @@ impl ChainInclusion for HttpEthRpc { trace!(?blk_hash_res, "blockByHash response"); let tx_type = EthProofType::from_str(input.tx_type()) .map_err(|e| Error::InvalidProof(e.to_string()))?; - let root_cid = get_root_cid_from_input(&tx_hash_res.input.to_string(), tx_type) + let tx_input = tx_hash_res.input.to_string(); + let root_cid = get_root_cid_from_input(&tx_input, tx_type) .map_err(|e| Error::InvalidProof(e.to_string()))?; if let Some(threshold) = BLOCK_THRESHHOLDS.get(self.chain_id()) { @@ -253,8 +250,14 @@ impl ChainInclusion for HttpEthRpc { } Ok(ChainInclusionProof { - timestamp: blk_hash_res.header.timestamp, + timestamp: Timestamp::from_unix_ts(blk_hash_res.header.timestamp), + block_hash: block_hash.to_string(), root_cid, + metadata: ChainProofMetadata { + chain_id: self.chain_id.clone(), + tx_hash: tx_hash.to_string(), + tx_input, + }, }) } else { Err(Error::TxNotMined { diff --git a/event-svc/src/blockchain/eth_rpc/mod.rs b/event-svc/src/blockchain/eth_rpc/mod.rs new file mode 100644 index 000000000..a8358032c --- /dev/null +++ b/event-svc/src/blockchain/eth_rpc/mod.rs @@ -0,0 +1,8 @@ +mod http; +mod types; + +pub use http::HttpEthRpc; +pub use types::{ + BlockHash, ChainInclusion, ChainInclusionProof, ChainProofMetadata, Error, EthProofType, + Timestamp, TxHash, +}; diff --git a/validation/src/blockchain/eth_rpc/types.rs b/event-svc/src/blockchain/eth_rpc/types.rs similarity index 85% rename from validation/src/blockchain/eth_rpc/types.rs rename to event-svc/src/blockchain/eth_rpc/types.rs index af4963752..c2d86d65c 100644 --- a/validation/src/blockchain/eth_rpc/types.rs +++ b/event-svc/src/blockchain/eth_rpc/types.rs @@ -92,13 +92,44 @@ impl FromStr for EthProofType { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +/// A timestamp that is able to provide seconds since the unix epoch +pub struct Timestamp(u64); + +impl Timestamp { + /// Create a timestamp from a unix epoch timestamp + pub const fn from_unix_ts(ts: u64) -> Self { + Self(ts) + } + + /// A unix epoch timestamp + pub fn as_unix_ts(&self) -> u64 { + self.0 + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] /// A proof of time derived from state on the blockchain pub struct ChainInclusionProof { /// The timestamp the proof was recorded - pub timestamp: u64, + pub timestamp: Timestamp, + /// The block hash in hex form with '0x' prefix + pub block_hash: String, /// The root CID of the proof pub root_cid: Cid, + /// The metadata about the proof and where it's stored + pub metadata: ChainProofMetadata, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +/// Metadata about the proof and where it's stored +pub struct ChainProofMetadata { + /// Chain ID of the proof + pub chain_id: ssi::caip2::ChainId, + /// The transaction hash in hex form with '0x' prefix + pub tx_hash: String, + /// The transaction input in hex form with '0x' prefix + pub tx_input: String, } #[async_trait::async_trait] diff --git a/event-svc/src/blockchain/mod.rs b/event-svc/src/blockchain/mod.rs new file mode 100644 index 000000000..5e35e113c --- /dev/null +++ b/event-svc/src/blockchain/mod.rs @@ -0,0 +1,12 @@ +use std::str::FromStr as _; + +use alloy::primitives::TxHash; +use ceramic_core::Cid; + +/// The ethereum RPC provider module +pub mod eth_rpc; + +/// Get the expected transaction hash for a given root CID (this is v1 proof type) +pub(crate) fn tx_hash_try_from_cid(cid: Cid) -> anyhow::Result { + Ok(TxHash::from_str(&hex::encode(cid.hash().digest()))?) +} diff --git a/event-svc/src/event/service.rs b/event-svc/src/event/service.rs index d6ca10f02..81729c7fd 100644 --- a/event-svc/src/event/service.rs +++ b/event-svc/src/event/service.rs @@ -12,7 +12,9 @@ use super::{ }; use async_trait::async_trait; use ceramic_core::{EventId, Network, NodeId, SerializeExt}; -use ceramic_pipeline::{ConclusionData, ConclusionEvent, ConclusionInit, ConclusionTime}; +use ceramic_pipeline::{ + concluder::TimeProof, ConclusionData, ConclusionEvent, ConclusionInit, ConclusionTime, +}; use ceramic_sql::sqlite::SqlitePool; use cid::Cid; use futures::stream::BoxStream; @@ -21,8 +23,8 @@ use itertools::Itertools; use recon::ReconItem; use tracing::{trace, warn}; -use crate::event::validator::ChainInclusionProvider; -use crate::store::{EventAccess, EventInsertable, EventRowDelivered}; +use crate::store::{ChainProof, EventAccess, EventInsertable, EventRowDelivered}; +use crate::{blockchain::tx_hash_try_from_cid, event::validator::ChainInclusionProvider}; use crate::{Error, Result}; /// How many events to select at once to see if they've become deliverable when we have downtime @@ -269,6 +271,7 @@ impl EventService { valid, unvalidated, invalid, + proofs, } = self .event_validator .validate_events(validation_requirement, to_validate) @@ -279,6 +282,7 @@ impl EventService { valid, unvalidated, invalid: invalid_events, + proofs, }) } @@ -293,6 +297,7 @@ impl EventService { valid, unvalidated, mut invalid, + proofs, } = self.validate_events(items, validation_req.as_ref()).await?; let to_insert: Vec = valid @@ -307,6 +312,14 @@ impl EventService { self.track_pending(unvalidated); } + // Someday, we may want to have the validation/proof inclusion logic have knowledge of the database and persist/read + // from it directly, rather than only keeping proofs in memory + RPC calls. But for now, it's simpler to persist everything once here + // and then the pipeline is able to read from this table and use the timestamps for conclusion events etc. + let proofs = proofs.into_iter().map(|p| p.into()).collect::>(); + self.event_access + .persist_chain_inclusion_proofs(&proofs) + .await?; + let (new, existed) = self .persist_events(to_insert, deliverable_req, &mut invalid) .await?; @@ -391,11 +404,20 @@ impl EventService { match event { ceramic_event::unvalidated::Event::Time(time_event) => { + let proof = self.get_chain_proof(&time_event).await?; + Ok(ConclusionEvent::Time(ConclusionTime { event_cid, init, previous: vec![*time_event.prev()], order: delivered as u64, + time_proof: TimeProof { + before: proof + .timestamp + .try_into() + .expect("conclusion timestamp overflow"), + chain_id: proof.chain_id, + }, })) } ceramic_event::unvalidated::Event::Signed(signed_event) => { @@ -518,6 +540,24 @@ impl EventService { Ok(()) } } + + /// This is a helper function to get the chain proof for a given event from the database, or throw an error if it + /// wasn't found. + async fn get_chain_proof( + &self, + event: &ceramic_event::unvalidated::TimeEvent, + ) -> Result { + let tx_hash = event.proof().tx_hash(); + let tx_hash = tx_hash_try_from_cid(tx_hash).unwrap().to_string(); + let chain_proof = self + .event_access + .get_chain_proof(event.proof().chain_id(), &tx_hash) + .await + .map_err(|e| { + Error::new_app(anyhow::anyhow!("Failed to discover chain proof: {:?}", e)) + })?; + Ok(chain_proof) + } } // Small wrapper container around the data field to hold other mutable metadata for the @@ -574,6 +614,8 @@ pub enum ValidationError { key: EventId, reason: String, }, + // TODO: Add 'Soft error' -> should not kill recon conversation but should not be persisted. + // e.g. A time event could not be validated because no RPC provider was available. } #[derive(Debug, PartialEq, Eq, Default)] diff --git a/event-svc/src/event/validator/event.rs b/event-svc/src/event/validator/event.rs index d5dfb91d2..7eeb8ffe2 100644 --- a/event-svc/src/event/validator/event.rs +++ b/event-svc/src/event/validator/event.rs @@ -2,23 +2,23 @@ use std::sync::Arc; use ceramic_core::{Cid, EventId, NodeId}; use ceramic_event::unvalidated; -use ceramic_validation::eth_rpc; use ipld_core::ipld::Ipld; use recon::ReconItem; use tokio::try_join; -use crate::event::validator::ChainInclusionProvider; -use crate::store::EventAccess; use crate::{ + blockchain::eth_rpc, + eth_rpc::ChainInclusionProof, event::{ service::{ValidationError, ValidationRequirement}, validator::{ grouped::{GroupedEvents, SignedValidationBatch, TimeValidationBatch}, signed::SignedEventValidator, time::TimeEventValidator, + ChainInclusionProvider, }, }, - store::EventInsertable, + store::{EventAccess, EventInsertable}, Result, }; @@ -31,6 +31,8 @@ pub struct ValidatedEvents { pub unvalidated: Vec, /// Events that failed validation pub invalid: Vec, + /// The proofs for the validated time events that can be stored for future time stamping + pub proofs: Vec, } #[derive(Debug)] @@ -107,6 +109,7 @@ impl ValidatedEvents { valid: Vec::with_capacity(valid), unvalidated: Vec::with_capacity(valid / 4), invalid: Vec::new(), + proofs: Vec::new(), } } @@ -114,6 +117,7 @@ impl ValidatedEvents { self.valid.extend(other.valid); self.invalid.extend(other.invalid); self.unvalidated.extend(other.unvalidated); + self.proofs.extend(other.proofs); } } @@ -124,7 +128,7 @@ pub struct EventValidator { /// It contains the ethereum RPC providers and lives for the live of the [`EventValidator`]. /// The [`SignedEventValidator`] is currently constructed on a per validation request basis /// as it caches and drops events per batch. - time_event_verifier: TimeEventValidator, + time_event_validator: TimeEventValidator, } impl EventValidator { @@ -133,41 +137,30 @@ impl EventValidator { event_access: Arc, ethereum_rpc_providers: Vec, ) -> Result { - let time_event_verifier = TimeEventValidator::new_with_providers(ethereum_rpc_providers); + let time_event_validator = TimeEventValidator::new_with_providers(ethereum_rpc_providers); Ok(Self { event_access, - time_event_verifier, + time_event_validator, }) } /// Validates the events with the given validation requirement - /// If the [`ValidationRequirement`] is None, it just returns every event as valid + /// Regardless of the validation requirement, time events are always validated. + /// If the [`ValidationRequirement`] is None, it just returns every data event as valid. pub(crate) async fn validate_events( &self, validation_req: Option<&ValidationRequirement>, parsed_events: Vec, ) -> Result { - let validation_req = if let Some(req) = validation_req { - req - } else { - // we don't validate so we just return done - return Ok(ValidatedEvents { - valid: parsed_events - .into_iter() - .map(ValidatedEvent::from_unvalidated_unchecked) - .collect(), - unvalidated: Vec::new(), - invalid: Vec::new(), - }); - }; - let mut validated = ValidatedEvents::new_with_expected_valid(parsed_events.len()); - // partition the events by type of validation needed and delegate to validators + + // Partition the events by type of validation needed and delegate to validators let grouped = GroupedEvents::from(parsed_events); let (validated_signed, validated_time) = try_join!( self.validate_signed_events(grouped.signed_batch, validation_req), + // Time events are always validated self.validate_time_events(grouped.time_batch) )?; validated.extend_with(validated_signed); @@ -183,23 +176,33 @@ impl EventValidator { async fn validate_signed_events( &self, events: SignedValidationBatch, - validation_req: &ValidationRequirement, + validation_req: Option<&ValidationRequirement>, ) -> Result { - let opts = if validation_req.check_exp { - ceramic_validation::VerifyJwsOpts::default() + if let Some(req) = validation_req { + let opts = if req.check_exp { + ceramic_validation::VerifyJwsOpts::default() + } else { + ceramic_validation::VerifyJwsOpts { + at_time: ceramic_validation::AtTime::SkipTimeChecks, + ..Default::default() + } + }; + SignedEventValidator::validate_events( + Arc::clone(&self.event_access), + &opts, + events, + req.require_local_init, + ) + .await } else { - ceramic_validation::VerifyJwsOpts { - at_time: ceramic_validation::AtTime::SkipTimeChecks, - ..Default::default() - } - }; - SignedEventValidator::validate_events( - Arc::clone(&self.event_access), - &opts, - events, - validation_req.require_local_init, - ) - .await + // If no validation requirement is specified, we assume all events are valid. + Ok(ValidatedEvents { + valid: events.into(), + unvalidated: Vec::new(), + invalid: Vec::new(), + proofs: Vec::new(), + }) + } } async fn validate_time_events(&self, events: TimeValidationBatch) -> Result { @@ -207,12 +210,12 @@ impl EventValidator { for time_event in events.0 { // TODO: better transient error handling from RPC client match self - .time_event_verifier + .time_event_validator .validate_chain_inclusion(time_event.as_time()) .await { - Ok(_t) => { - // TODO(AES-345): Someday, we will use `t.as_unix_ts()` and care about the actual timestamp, but for now we just consider it valid + Ok(t) => { + validated_events.proofs.push(t); validated_events.valid.push(time_event.into()); } Err(err) => { diff --git a/event-svc/src/event/validator/grouped.rs b/event-svc/src/event/validator/grouped.rs index 846adfd20..7618f456f 100644 --- a/event-svc/src/event/validator/grouped.rs +++ b/event-svc/src/event/validator/grouped.rs @@ -104,11 +104,22 @@ pub struct TimeValidationBatch(pub(crate) Vec