diff --git a/.cargo/config b/.cargo/config deleted file mode 100644 index d60af81d9..000000000 --- a/.cargo/config +++ /dev/null @@ -1,11 +0,0 @@ -[target.aarch64-unknown-linux-gnu] -linker = "aarch64-linux-gnu-gcc" - -[target.x86_64-unknown-linux-gnu] -linker = "x86_64-linux-gnu-gcc" - -[net] -git-fetch-with-cli = true # use the `git` executable for git operations - -[source.crates-io] -registry = "git://github.com/rust-lang/crates.io-index.git" diff --git a/Cargo.lock b/Cargo.lock index 99791d30a..3e4791b0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,7 +18,7 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936697e9caf938eb2905036100edf8e1269da8291f8a02f5fe7b37073784eec0" dependencies = [ - "no-std-net", + "no-std-net 0.5.0", "psl", "psl-types", ] @@ -38,7 +38,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.28.0", + "gimli 0.28.1", ] [[package]] @@ -47,25 +47,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array 0.14.7", -] - -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", -] - [[package]] name = "aead" version = "0.5.2" @@ -78,105 +59,48 @@ dependencies = [ [[package]] name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher 0.2.5", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if", - "cipher 0.3.0", - "cpufeatures", - "opaque-debug 0.3.0", -] - -[[package]] -name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher 0.4.4", "cpufeatures", ] -[[package]] -name = "aes-gcm" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" -dependencies = [ - "aead 0.4.3", - "aes 0.7.5", - "cipher 0.3.0", - "ctr 0.8.0", - "ghash 0.4.4", - "subtle", -] - [[package]] name = "aes-gcm" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "aead 0.5.2", - "aes 0.8.3", + "aead", + "aes", "cipher 0.4.4", - "ctr 0.9.2", - "ghash 0.5.0", - "subtle", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug 0.3.0", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" -dependencies = [ - "cipher 0.2.5", - "opaque-debug 0.3.0", + "ctr", + "ghash", + "subtle 2.5.0", ] [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" dependencies = [ "cfg-if", - "getrandom 0.2.10", + "getrandom 0.2.12", "once_cell", "serde", "version_check", @@ -192,6 +116,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -224,9 +154,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" dependencies = [ "anstyle", "anstyle-parse", @@ -238,58 +168,57 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "api" version = "0.7.5" dependencies = [ + "anyhow", "assert_fs", "async-graphql", "async-graphql-poem", - "async-stl-client", "async-stream", "async-trait", - "base64 0.21.5", + "base64 0.21.7", "cached", "cfg-if", - "chronicle-protocol", "chronicle-signing", "chronicle-telemetry", "chrono", @@ -299,7 +228,6 @@ dependencies = [ "diesel", "diesel_migrations", "futures", - "glob", "hex", "insta", "iref", @@ -309,31 +237,28 @@ dependencies = [ "metrics", "metrics-exporter-prometheus", "opa", - "opa-tp-protocol", "opentelemetry 0.19.0", "parking_lot 0.12.1", "poem", - "portpicker", - "prost 0.10.4", - "protobuf", + "protocol-substrate", + "protocol-substrate-chronicle", + "protocol-substrate-opa", "r2d2", "rand 0.8.5", "rand_core 0.6.4", "reqwest", - "sawtooth-sdk", - "sawtooth_tp", + "rust-embed", "serde", "serde_derive", "serde_json", "tempfile", "thiserror", - "tmq", "tokio", "tokio-stream", "tracing", "url", "user-error", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] @@ -347,12 +272,12 @@ dependencies = [ [[package]] name = "aquamarine" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +checksum = "d1da02abba9f9063d786eab1509833ebb2fac0f966862ca59439c76b9c566760" dependencies = [ "include_dir", - "itertools 0.10.5", + "itertools", "proc-macro-error", "proc-macro2", "quote", @@ -360,22 +285,145 @@ dependencies = [ ] [[package]] -name = "arbitrary" -version = "1.3.2" +name = "ark-bls12-377" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "fb00293ba84f51ce3bd026bd0de55899c4e68f0a39a5728cebae3a73ffdc0a4f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] [[package]] -name = "arc-swap" -version = "1.6.0" +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "array-bytes" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] name = "array-bytes" -version = "6.1.0" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" +checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" [[package]] name = "arrayref" @@ -383,6 +431,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + [[package]] name = "arrayvec" version = "0.5.2" @@ -401,29 +458,13 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" -[[package]] -name = "asn1-rs" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" -dependencies = [ - "asn1-rs-derive 0.1.0", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror", - "time", -] - [[package]] name = "asn1-rs" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "asn1-rs-derive 0.4.0", + "asn1-rs-derive", "asn1-rs-impl", "displaydoc", "nom", @@ -433,18 +474,6 @@ dependencies = [ "time", ] -[[package]] -name = "asn1-rs-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] - [[package]] name = "asn1-rs-derive" version = "0.4.0" @@ -480,14 +509,14 @@ dependencies = [ [[package]] name = "assert_fs" -version = "1.0.13" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f070617a68e5c2ed5d06ee8dd620ee18fb72b99f6c094bed34cf8ab07c875b48" +checksum = "2cd762e110c8ed629b11b6cde59458cc1c71de78ebbcc30099fc8e0403a2a2ec" dependencies = [ "anstyle", "doc-comment", "globwalk", - "predicates 3.0.4", + "predicates 3.1.0", "predicates-core", "predicates-tree", "tempfile", @@ -500,8 +529,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.1.0", + "event-listener-strategy 0.5.0", "futures-core", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.1", + "futures-lite 2.2.0", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", ] [[package]] @@ -538,7 +606,7 @@ dependencies = [ "static_assertions", "tempfile", "thiserror", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] @@ -550,7 +618,7 @@ dependencies = [ "Inflector", "async-graphql-parser", "darling 0.14.4", - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -600,70 +668,103 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", - "polling", + "polling 2.8.0", "rustix 0.37.27", "slab", "socket2 0.4.10", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.2.0", + "parking", + "polling 3.5.0", + "rustix 0.38.31", + "slab", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-lock" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener", + "event-listener 2.5.3", ] [[package]] -name = "async-recursion" -version = "1.0.5" +name = "async-lock" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite 0.2.13", ] [[package]] -name = "async-stl-client" -version = "0.7.5" -source = "git+https://github.com/btpworks/async-stl-sdk#52c6766757f14e7a3dc4ccdb760d09f7c72875e6" +name = "async-net" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" dependencies = [ - "anyhow", - "async-trait", - "derivative", - "futures", - "glob", - "hex", - "k256 0.11.6", - "lazy_static", - "lru", - "pin-project-lite 0.2.13", - "pinvec", - "pow_of_2", - "prost 0.10.4", - "prost-build 0.10.4", - "rand 0.8.5", - "rand_core 0.6.4", - "serde", - "serde_json", - "thiserror", - "tmq", - "tokio", - "tokio-stream", - "tracing", - "uuid 1.5.0", - "zmq", + "async-io 1.13.0", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.31", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.3.1", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.31", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", ] [[package]] @@ -685,24 +786,24 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "async-task" -version = "4.5.0" +version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -724,6 +825,12 @@ dependencies = [ "pin-project-lite 0.2.13", ] +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + [[package]] name = "atomic-waker" version = "1.1.2" @@ -803,7 +910,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.32.1", + "object 0.32.2", "rustc-demangle", ] @@ -825,6 +932,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + [[package]] name = "base64" version = "0.13.1" @@ -833,9 +946,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -873,13 +986,22 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.15", + "prettyplease 0.2.16", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.38", + "syn 2.0.49", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", ] [[package]] @@ -897,6 +1019,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + [[package]] name = "bitflags" version = "1.3.2" @@ -905,9 +1033,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -921,6 +1049,18 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + [[package]] name = "blake2" version = "0.10.6" @@ -930,6 +1070,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq 0.1.5", +] + [[package]] name = "blake2b_simd" version = "1.0.2" @@ -938,7 +1088,7 @@ checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq", + "constant_time_eq 0.3.0", ] [[package]] @@ -949,7 +1099,7 @@ checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq", + "constant_time_eq 0.3.0", ] [[package]] @@ -962,7 +1112,7 @@ dependencies = [ "arrayvec 0.7.4", "cc", "cfg-if", - "constant_time_eq", + "constant_time_eq 0.3.0", ] [[package]] @@ -971,7 +1121,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5", + "block-padding", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -995,16 +1145,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-modes" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" -dependencies = [ - "block-padding 0.2.1", - "cipher 0.2.5", -] - [[package]] name = "block-padding" version = "0.1.5" @@ -1014,24 +1154,18 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "blocking" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel", - "async-lock", + "async-channel 2.2.0", + "async-lock 3.3.0", "async-task", "fastrand 2.0.1", "futures-io", - "futures-lite", + "futures-lite 2.2.0", "piper", "tracing", ] @@ -1076,9 +1210,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" dependencies = [ "memchr", "serde", @@ -1095,9 +1229,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "byte-slice-cast" @@ -1119,9 +1253,9 @@ checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" [[package]] name = "byteorder" @@ -1149,6 +1283,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "c2-chacha" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27dae93fe7b1e0424dc57179ac396908c26b035a87234809f5c4dfd1b47dc80" +dependencies = [ + "cipher 0.2.5", + "ppv-lite86", +] + [[package]] name = "cached" version = "0.42.0" @@ -1183,9 +1327,9 @@ dependencies = [ [[package]] name = "cached_proc_macro_types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "camino" @@ -1204,9 +1348,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" [[package]] name = "cargo-platform" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" dependencies = [ "serde", ] @@ -1219,7 +1363,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.20", + "semver 1.0.22", "serde", "serde_json", "thiserror", @@ -1241,17 +1385,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ccm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" -dependencies = [ - "aead 0.3.2", - "cipher 0.2.5", - "subtle", -] - [[package]] name = "cexpr" version = "0.6.0" @@ -1263,9 +1396,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.5" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" +checksum = "fa50868b64a9a6fda9d593ce778849ea8715cd2a3d2cc17ffdb4a2f2f2f1961d" dependencies = [ "smallvec", ] @@ -1282,27 +1415,36 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + [[package]] name = "chacha20" -version = "0.8.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher 0.3.0", + "cipher 0.4.4", "cpufeatures", - "zeroize", ] [[package]] name = "chacha20poly1305" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead 0.4.3", + "aead", "chacha20", - "cipher 0.3.0", + "cipher 0.4.4", "poly1305", "zeroize", ] @@ -1315,9 +1457,8 @@ dependencies = [ "api", "assert_fs", "async-graphql", - "async-stl-client", + "async-trait", "cfg-if", - "chronicle-protocol", "chronicle-signing", "chronicle-telemetry", "chrono", @@ -1328,21 +1469,25 @@ dependencies = [ "const_format", "diesel", "dotenvy", + "embedded-substrate", "futures", "genco", "hex", "insta", - "iref", + "iri-string", "is-terminal", "jsonschema", + "mockito 0.30.0", "opa", - "opa-tp-protocol", "opentelemetry 0.19.0", "percent-encoding", + "protocol-abstract", + "protocol-substrate", + "protocol-substrate-chronicle", + "protocol-substrate-opa", "question", "rand 0.8.5", "rand_core 0.6.4", - "sawtooth-sdk", "serde", "serde_derive", "serde_json", @@ -1353,10 +1498,10 @@ dependencies = [ "tokio", "toml 0.7.8", "tracing", - "tracing-log", + "tracing-log 0.1.4", "url", "user-error", - "uuid 1.5.0", + "uuid 1.6.1", "valico", ] @@ -1380,55 +1525,23 @@ dependencies = [ name = "chronicle-example" version = "0.7.5" dependencies = [ - "async-stl-client", "chronicle", - "chronicle-protocol", "chronicle-signing", "chronicle-telemetry", - "futures", - "hex", - "insta", - "opa-tp-protocol", - "tempfile", - "tracing", - "tracing-log", - "uuid 1.5.0", -] - -[[package]] -name = "chronicle-protocol" -version = "0.7.5" -dependencies = [ - "async-stl-client", - "async-trait", - "bytes", - "chronicle-signing", - "chrono", + "chronicle-test-infrastructure", "common", - "custom_error", - "derivative", + "embedded-substrate", "futures", - "glob", "hex", - "k256 0.11.6", - "lazy_static", - "opa-tp-protocol", - "openssl", - "prost 0.10.4", - "prost-build 0.10.4", - "prost-types 0.11.9", - "rand 0.8.5", - "rand_core 0.6.4", - "serde", - "serde_derive", - "serde_json", + "insta", + "protocol-substrate", + "protocol-substrate-chronicle", + "protocol-substrate-opa", "tempfile", - "thiserror", "tokio", "tracing", - "url", - "uuid 1.5.0", - "zmq", + "tracing-log 0.1.4", + "uuid 1.6.1", ] [[package]] @@ -1473,16 +1586,42 @@ dependencies = [ "console-subscriber", "tracing", "tracing-elastic-apm", - "tracing-log", - "tracing-subscriber 0.3.17", + "tracing-log 0.1.4", + "tracing-subscriber 0.3.18", "url", ] +[[package]] +name = "chronicle-test-infrastructure" +version = "0.1.0" +dependencies = [ + "api", + "assert_fs", + "chronicle", + "chronicle-signing", + "chronicle-telemetry", + "chrono", + "common", + "diesel", + "embedded-substrate", + "insta", + "lazy_static", + "protocol-abstract", + "protocol-substrate", + "protocol-substrate-chronicle", + "r2d2", + "serde_json", + "tempfile", + "testcontainers", + "tokio", + "uuid 1.6.1", +] + [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1490,14 +1629,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -1506,15 +1645,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -1542,15 +1681,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "cipher" version = "0.4.4" @@ -1559,13 +1689,14 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -1584,31 +1715,31 @@ dependencies = [ "clap_lex 0.2.4", "indexmap 1.9.3", "once_cell", - "strsim", + "strsim 0.10.0", "termcolor", "textwrap", ] [[package]] name = "clap" -version = "4.4.7" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", - "clap_derive 4.4.7", + "clap_derive 4.5.0", ] [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", - "strsim", + "clap_lex 0.7.0", + "strsim 0.11.0", ] [[package]] @@ -1635,14 +1766,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -1656,18 +1787,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - -[[package]] -name = "cmake" -version = "0.1.50" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "codespan-reporting" @@ -1687,20 +1809,19 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "colored_json" -version = "3.3.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4948aed0a773db233baf8997302da553ad285be28464c36584944a66ab107db2" +checksum = "74cb9ce6b86f6e54bfa9518df2eeeef65d424ec7244d083ed97229185e366a91" dependencies = [ "is-terminal", "serde", @@ -1743,23 +1864,30 @@ dependencies = [ "locspan", "macro-attr-2018", "mime", - "mockito", + "mockito 1.2.0", "newtype-derive-2018", + "opa", "parity-scale-codec", "proptest", "rdf-types", + "reqwest", + "rust-embed", + "scale-decode", + "scale-encode", "scale-info", "serde", "serde_derive", "serde_json", - "sp-std", + "sp-core 25.0.0", + "sp-std 11.0.0", "tempfile", "testcontainers", "thiserror", "thiserror-no-std", "tokio", "tracing", - "uuid 1.5.0", + "url", + "uuid 1.6.1", ] [[package]] @@ -1770,24 +1898,24 @@ checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -1796,8 +1924,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", + "prost", + "prost-types", "tonic", "tracing-core", ] @@ -1814,7 +1942,7 @@ dependencies = [ "futures", "hdrhistogram", "humantime", - "prost-types 0.11.9", + "prost-types", "serde", "serde_json", "thread_local", @@ -1823,14 +1951,14 @@ dependencies = [ "tonic", "tracing", "tracing-core", - "tracing-subscriber 0.3.17", + "tracing-subscriber 0.3.18", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-random" @@ -1847,7 +1975,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", "once_cell", "tiny-keccak", ] @@ -1872,23 +2000,41 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "constant_time_eq" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +[[package]] +name = "constcat" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" + [[package]] name = "contextual" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05ca71f324d19e85a2e976be04b5ecbb193253794a75adfe2e5044c8bef03f6a" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1896,9 +2042,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -1920,9 +2066,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -1933,16 +2079,7 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1277fbfa94bc82c8ec4af2ded3e639d49ca5f7f3c7eeab2c66accd135ece4e70" dependencies = [ - "cranelift-entity 0.95.1", -] - -[[package]] -name = "cranelift-bforest" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aae6f552c4c0ccfb30b9559b77bc985a387d998e1736cbbe6b14c903f3656cf" -dependencies = [ - "cranelift-entity 0.97.2", + "cranelift-entity", ] [[package]] @@ -1952,36 +2089,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e8c31ad3b2270e9aeec38723888fe1b0ace3bea2b06b3f749ccf46661d3220" dependencies = [ "bumpalo", - "cranelift-bforest 0.95.1", - "cranelift-codegen-meta 0.95.1", - "cranelift-codegen-shared 0.95.1", - "cranelift-entity 0.95.1", - "cranelift-isle 0.95.1", - "gimli 0.27.3", - "hashbrown 0.13.2", - "log", - "regalloc2 0.6.1", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-codegen" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95551de96900cefae691ce895ff2abc691ae3a0b97911a76b45faf99e432937b" -dependencies = [ - "bumpalo", - "cranelift-bforest 0.97.2", - "cranelift-codegen-meta 0.97.2", - "cranelift-codegen-shared 0.97.2", - "cranelift-control", - "cranelift-entity 0.97.2", - "cranelift-isle 0.97.2", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-entity", + "cranelift-isle", "gimli 0.27.3", "hashbrown 0.13.2", "log", - "regalloc2 0.9.3", + "regalloc2", "smallvec", "target-lexicon", ] @@ -1992,16 +2108,7 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ac5ac30d62b2d66f12651f6b606dbdfd9c2cfd0908de6b387560a277c5c9da" dependencies = [ - "cranelift-codegen-shared 0.95.1", -] - -[[package]] -name = "cranelift-codegen-meta" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a3ad7b2bb03de3383f258b00ca29d80234bebd5130cb6ef3bae37ada5baab0" -dependencies = [ - "cranelift-codegen-shared 0.97.2", + "cranelift-codegen-shared", ] [[package]] @@ -2011,57 +2118,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd82b8b376247834b59ed9bdc0ddeb50f517452827d4a11bccf5937b213748b8" [[package]] -name = "cranelift-codegen-shared" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915918fee4142c85fb04bafe0bcd697e2fd6c15a260301ea6f8d2ea332a30e86" - -[[package]] -name = "cranelift-control" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e447d548cd7f4fcb87fbd10edbd66a4f77966d17785ed50a08c8f3835483c8" -dependencies = [ - "arbitrary", -] - -[[package]] -name = "cranelift-entity" -version = "0.95.1" +name = "cranelift-entity" +version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40099d38061b37e505e63f89bab52199037a72b931ad4868d9089ff7268660b0" dependencies = [ "serde", ] -[[package]] -name = "cranelift-entity" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d8ab3352a1e5966968d7ab424bd3de8e6b58314760745c3817c2eec3fa2f918" -dependencies = [ - "serde", -] - [[package]] name = "cranelift-frontend" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a25d9d0a0ae3079c463c34115ec59507b4707175454f0eee0891e83e30e82d" dependencies = [ - "cranelift-codegen 0.95.1", - "log", - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cranelift-frontend" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bffa38431f7554aa1594f122263b87c9e04abc55c9f42b81d37342ac44f79f0" -dependencies = [ - "cranelift-codegen 0.97.2", + "cranelift-codegen", "log", "smallvec", "target-lexicon", @@ -2073,30 +2144,13 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80de6a7d0486e4acbd5f9f87ec49912bf4c8fb6aea00087b989685460d4469ba" -[[package]] -name = "cranelift-isle" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84cef66a71c77938148b72bf006892c89d6be9274a08f7e669ff15a56145d701" - [[package]] name = "cranelift-native" version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb6b03e0e03801c4b3fd8ce0758a94750c07a44e7944cc0ffbf0d3f2e7c79b00" dependencies = [ - "cranelift-codegen 0.95.1", - "libc", - "target-lexicon", -] - -[[package]] -name = "cranelift-native" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33c7e5eb446e162d2d10b17fe68e1f091020cc2e4e38b5501c21099600b0a1b" -dependencies = [ - "cranelift-codegen 0.97.2", + "cranelift-codegen", "libc", "target-lexicon", ] @@ -2107,52 +2161,21 @@ version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff3220489a3d928ad91e59dd7aeaa8b3de18afb554a6211213673a71c90737ac" dependencies = [ - "cranelift-codegen 0.95.1", - "cranelift-entity 0.95.1", - "cranelift-frontend 0.95.1", - "itertools 0.10.5", - "log", - "smallvec", - "wasmparser 0.102.0", - "wasmtime-types 8.0.1", -] - -[[package]] -name = "cranelift-wasm" -version = "0.97.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f7b64fa6a8c5b980eb6a17ef22089e15cb9f779f1ed3bd3072beab0686c09" -dependencies = [ - "cranelift-codegen 0.97.2", - "cranelift-entity 0.97.2", - "cranelift-frontend 0.97.2", - "itertools 0.10.5", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools", "log", "smallvec", - "wasmparser 0.107.0", - "wasmtime-types 10.0.2", -] - -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", + "wasmparser", + "wasmtime-types", ] -[[package]] -name = "crc-catalog" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -2166,11 +2189,11 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.7", + "clap 4.5.1", "criterion-plot", "futures", "is-terminal", - "itertools 0.10.5", + "itertools", "num-traits", "once_cell", "oorandom", @@ -2192,52 +2215,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools 0.10.5", + "itertools", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-queue" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", + "crossbeam-utils", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crunchy" version = "0.2.2" @@ -2252,19 +2275,19 @@ checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", - "subtle", + "subtle 2.5.0", "zeroize", ] [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", - "subtle", + "subtle 2.5.0", "zeroize", ] @@ -2281,31 +2304,32 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.8.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" dependencies = [ - "generic-array 0.14.7", - "subtle", + "generic-array 0.12.4", + "subtle 1.0.0", ] [[package]] name = "crypto-mac" -version = "0.11.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.7", - "subtle", + "subtle 2.5.0", ] [[package]] -name = "ctr" -version = "0.8.0" +name = "crypto-mac" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ - "cipher 0.3.0", + "generic-array 0.14.7", + "subtle 2.5.0", ] [[package]] @@ -2317,16 +2341,6 @@ dependencies = [ "cipher 0.4.4", ] -[[package]] -name = "ctrlc" -version = "3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" -dependencies = [ - "nix 0.27.1", - "windows-sys 0.48.0", -] - [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -2336,7 +2350,7 @@ dependencies = [ "byteorder", "digest 0.8.1", "rand_core 0.5.1", - "subtle", + "subtle 2.5.0", "zeroize", ] @@ -2349,15 +2363,15 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle", + "subtle 2.5.0", "zeroize", ] [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -2366,7 +2380,7 @@ dependencies = [ "fiat-crypto", "platforms", "rustc_version", - "subtle", + "subtle 2.5.0", "zeroize", ] @@ -2378,7 +2392,20 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", +] + +[[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 0.6.4", + "subtle-ng", + "zeroize", ] [[package]] @@ -2389,9 +2416,9 @@ checksum = "4f8a51dd197fa6ba5b4dc98a990a43cc13693c23eb0089ebb0fcc1f04152bca6" [[package]] name = "cxx" -version = "1.0.110" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7129e341034ecb940c9072817cd9007974ea696844fc4dd582dc1653a7fbe2e8" +checksum = "8aff472b83efd22bfc0176aa8ba34617dd5c17364670eb201a5f06d339b8abf7" dependencies = [ "cc", "cxxbridge-flags", @@ -2401,9 +2428,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.110" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a24f3f5f8eed71936f21e570436f024f5c2e25628f7496aa7ccd03b90109d5" +checksum = "bcf6e7a52c19013a9a0ec421c7d9c2d1125faf333551227e0a017288d71b47c3" dependencies = [ "cc", "codespan-reporting", @@ -2411,24 +2438,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "cxxbridge-flags" -version = "1.0.110" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fdd177fc61050d63f67f5bd6351fac6ab5526694ea8e359cd9cd3b75857f44" +checksum = "589e83d02fc1d4fb78f5ad56ca08835341e23499d086d2821315869426d618dc" [[package]] name = "cxxbridge-macro" -version = "1.0.110" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "587663dd5fb3d10932c8aecfe7c844db1bcf0aee93eeab08fac13dc1212c2e7f" +checksum = "e2cb1fd8ffae4230c7cfbbaf3698dbeaf750fa8c5dadf7ed897df581b9b572a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -2451,6 +2478,16 @@ dependencies = [ "darling_macro 0.14.4", ] +[[package]] +name = "darling" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c376d08ea6aa96aafe61237c7200d1241cb177b7d3a542d791f2d118e9cbb955" +dependencies = [ + "darling_core 0.20.6", + "darling_macro 0.20.6", +] + [[package]] name = "darling_core" version = "0.13.4" @@ -2461,7 +2498,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -2475,10 +2512,24 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] +[[package]] +name = "darling_core" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33043dcd19068b8192064c704b3f83eb464f91f1ff527b44a4e2b08d9cdb8855" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.49", +] + [[package]] name = "darling_macro" version = "0.13.4" @@ -2501,17 +2552,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_macro" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" +dependencies = [ + "darling_core 0.20.6", + "quote", + "syn 2.0.49", +] + [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "data-encoding-macro" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2519,23 +2581,14 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" dependencies = [ "data-encoding", "syn 1.0.109", ] -[[package]] -name = "debugid" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" -dependencies = [ - "uuid 1.5.0", -] - [[package]] name = "decoded-char" version = "0.1.1" @@ -2563,27 +2616,13 @@ dependencies = [ "zeroize", ] -[[package]] -name = "der-parser" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" -dependencies = [ - "asn1-rs 0.3.1", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - [[package]] name = "der-parser" version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", "displaydoc", "nom", "num-bigint", @@ -2593,9 +2632,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] @@ -2622,34 +2661,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_builder" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" -dependencies = [ - "derive_builder_macro 0.11.2", -] - [[package]] name = "derive_builder" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" dependencies = [ - "derive_builder_macro 0.12.0", -] - -[[package]] -name = "derive_builder_core" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" -dependencies = [ - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", + "derive_builder_macro", ] [[package]] @@ -2664,23 +2682,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_builder_macro" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" -dependencies = [ - "derive_builder_core 0.11.2", - "syn 1.0.109", -] - [[package]] name = "derive_builder_macro" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" dependencies = [ - "derive_builder_core 0.12.0", + "derive_builder_core", "syn 1.0.109", ] @@ -2690,25 +2698,27 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ + "convert_case", "proc-macro2", "quote", + "rustc_version", "syn 1.0.109", ] [[package]] name = "diesel" -version = "2.1.3" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2268a214a6f118fce1838edba3d1561cf0e78d8de785475957a580a7f8c69d33" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "byteorder", "chrono", "diesel_derives", "itoa", "pq-sys", "r2d2", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] @@ -2720,7 +2730,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -2740,9 +2750,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.38", + "syn 2.0.49", ] +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + [[package]] name = "difflib" version = "0.4.0" @@ -2776,7 +2792,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle", + "subtle 2.5.0", ] [[package]] @@ -2838,7 +2854,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -2849,18 +2865,18 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "docify" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4235e9b248e2ba4b92007fe9c646f3adf0ffde16dc74713eacc92b8bc58d8d2f" +checksum = "7cc4fd38aaa9fb98ac70794c82a00360d1e165a87fbf96a8a91f9dfc602aaee2" dependencies = [ "docify_macros", ] [[package]] name = "docify_macros" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47020e12d7c7505670d1363dd53d6c23724f71a90a3ae32ff8eba40de8404626" +checksum = "63fa215f3a0d40fb2a221b3aa90d8e1fbb8379785a990cb60d62ac71ebdc6460" dependencies = [ "common-path", "derive-syn-parse", @@ -2868,9 +2884,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.38", + "syn 2.0.49", "termcolor", - "toml 0.7.8", + "toml 0.8.2", "walkdir", ] @@ -2886,6 +2902,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "dtoa" version = "1.0.9" @@ -2915,9 +2937,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "ecdsa" @@ -2934,16 +2956,25 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.8", "digest 0.10.7", - "elliptic-curve 0.13.6", + "elliptic-curve 0.13.8", "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", ] [[package]] @@ -2953,20 +2984,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8 0.10.2", - "signature 2.1.0", + "signature 2.2.0", ] [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519", + "curve25519-dalek 4.1.2", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", "sha2 0.10.8", + "subtle 2.5.0", "zeroize", ] @@ -2986,9 +3030,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" @@ -3003,24 +3047,23 @@ dependencies = [ "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "hkdf", "pem-rfc7468", "pkcs8 0.9.0", "rand_core 0.6.4", "sec1 0.3.0", "serdect", - "subtle", + "subtle 2.5.0", "zeroize", ] [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.3", + "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", "generic-array 0.14.7", @@ -3028,10 +3071,31 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", - "subtle", + "subtle 2.5.0", "zeroize", ] +[[package]] +name = "embedded-substrate" +version = "0.1.0" +dependencies = [ + "anyhow", + "lazy_static", + "node-chronicle", + "portpicker", + "protocol-abstract", + "protocol-substrate", + "protocol-substrate-chronicle", + "sc-cli", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "subxt", + "tempfile", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -3061,9 +3125,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -3086,20 +3150,14 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] -[[package]] -name = "error-chain" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" - [[package]] name = "event-listener" version = "2.5.3" @@ -3107,25 +3165,78 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] -name = "exit-future" -version = "0.2.0" +name = "event-listener" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ - "futures", + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", ] [[package]] -name = "expander" -version = "2.0.0" +name = "event-listener" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f86a749cf851891866c10515ef6c299b5c69661465e9c3bbe7e07a2b77fb0f7" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ - "blake2", - "fs-err", - "proc-macro2", - "quote", - "syn 2.0.38", + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "event-listener" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ad6fd685ce13acd6d9541a30f6db6567a7a24c9ffd4ba2955d29e3f22c8b27" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.1.0", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "exit-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" +dependencies = [ + "futures", +] + +[[package]] +name = "expander" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f86a749cf851891866c10515ef6c299b5c69661465e9c3bbe7e07a2b77fb0f7" +dependencies = [ + "blake2 0.10.6", + "fs-err", + "proc-macro2", + "quote", + "syn 2.0.49", ] [[package]] @@ -3190,7 +3301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", - "subtle", + "subtle 2.5.0", ] [[package]] @@ -3200,14 +3311,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", - "subtle", + "subtle 2.5.0", ] [[package]] name = "fiat-crypto" -version = "0.2.2" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "file-per-thread-logger" @@ -3221,14 +3332,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -3308,18 +3419,18 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" -version = "10.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6d54d3a638f0279210c924f4a44e6548bf6345670f5af059a874a5006af4eca" +checksum = "1c2d0a4310dcf0e5cce78e35e60dc2fda80ef61c8f8fc382e685dfc24fcf5db9" dependencies = [ "parity-scale-codec", ] [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -3342,9 +3453,9 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01af5751a0e4492dc979c57586976403e7ab63641add1a9fd804cad4169f4f6" +checksum = "3dd4946d63eab00d899f08a7e74e965cc6785c2298efaea6a2752905f4810407" dependencies = [ "frame-support", "frame-support-procedural", @@ -3356,33 +3467,33 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", - "sp-runtime-interface", - "sp-std", - "sp-storage", + "sp-application-crypto 27.0.0", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-runtime-interface 21.0.0", + "sp-std 12.0.0", + "sp-storage 17.0.0", "static_assertions", ] [[package]] name = "frame-benchmarking-cli" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4493341076535acb0bdb591e0e97b32cfacb8515dd74e66156f199d187cec004" +checksum = "67e51c371bff90ba44767a79e72a036d7d648cee621cd2fe9f693e8c1d62941e" dependencies = [ "Inflector", - "array-bytes", + "array-bytes 6.2.2", "chrono", - "clap 4.4.7", + "clap 4.5.1", "comfy-table", "frame-benchmarking", "frame-support", "frame-system", "gethostname", "handlebars", - "itertools 0.10.5", + "itertools", "lazy_static", "linked-hash-map", "log", @@ -3400,26 +3511,26 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 25.0.0", "sp-database", - "sp-externalities", + "sp-externalities 0.23.0", "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-state-machine", - "sp-storage", - "sp-trie", - "sp-wasm-interface", + "sp-io 27.0.0", + "sp-keystore 0.31.0", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", + "sp-storage 17.0.0", + "sp-trie 26.0.0", + "sp-wasm-interface 18.0.0", "thiserror", "thousands", ] [[package]] name = "frame-executive" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da12a8c223d6991bd7f9aae542d3d7c9fadde3a81b6f16c2550b808f3b21ecd5" +checksum = "2dda2c20ea3267ee20c9a5482f320236510c4ade6aec1dd930cb57dc5651c64f" dependencies = [ "frame-support", "frame-system", @@ -3427,11 +3538,22 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", + "sp-tracing 14.0.0", +] + +[[package]] +name = "frame-metadata" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", ] [[package]] @@ -3448,21 +3570,20 @@ dependencies = [ [[package]] name = "frame-remote-externalities" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b26379217d223364e6715ed12cdfdc9f368c6afcb15fd8771e387ab7b0265f" +checksum = "a30013df51f4d4e58472c4fecdbfeb141234ece5f6355e5b3a3e51d3f87d452d" dependencies = [ - "async-recursion", "futures", "indicatif", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "parity-scale-codec", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-state-machine", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", "spinners", "substrate-rpc-client", "tokio", @@ -3471,18 +3592,18 @@ dependencies = [ [[package]] name = "frame-support" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0dc5640279221fbd316a3a652963c1cb9d51630ea3f62a08a5ad7fa402f23a4" +checksum = "023504bbdd0e8d1ebe3d9d289b009337cdb9a24c5e74615ffd7b188aa1664c2d" dependencies = [ "aquamarine", "bitflags 1.3.2", "docify", "environmental", - "frame-metadata", + "frame-metadata 16.0.0", "frame-support-procedural", "impl-trait-for-tuples", - "k256 0.13.1", + "k256 0.13.3", "log", "macro_magic", "parity-scale-codec", @@ -3492,72 +3613,73 @@ dependencies = [ "serde_json", "smallvec", "sp-api", - "sp-arithmetic", - "sp-core", + "sp-arithmetic 20.0.0", + "sp-core 25.0.0", "sp-core-hashing-proc-macro", - "sp-debug-derive", + "sp-debug-derive 12.0.0", "sp-genesis-builder", "sp-inherents", - "sp-io", + "sp-io 27.0.0", "sp-metadata-ir", - "sp-runtime", + "sp-runtime 28.0.0", "sp-staking", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-weights", + "sp-state-machine 0.32.0", + "sp-std 12.0.0", + "sp-tracing 14.0.0", + "sp-weights 24.0.0", "static_assertions", "tt-call", ] [[package]] name = "frame-support-procedural" -version = "19.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22719c65353a0010a084cb2040e2e6569aff34562e59119cb66ddd7ecfa588c" +checksum = "1d6bc383298353ff2790ac1a301262c21ac196dbc26ef67a2213c46524a06dd1" dependencies = [ "Inflector", "cfg-expr", "derive-syn-parse", "expander", "frame-support-procedural-tools", - "itertools 0.10.5", + "itertools", "macro_magic", "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.38", + "sp-core-hashing 13.0.0", + "syn 2.0.49", ] [[package]] name = "frame-support-procedural-tools" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e046ecdc04dd66f17d760525631f553ddcbea6f09423f78fcf52b47c97656cd0" +checksum = "b3ac1266522a8c9a2d2d26d205ec3028b88582d5f3cd5cbc75d0ec8271d197b7" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "frame-support-procedural-tools-derive" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4034ebf9ca7497fa3893191fe3e81adcd3d7cd1c232e60ef41ef58ea0c445ae9" +checksum = "d9c078db2242ea7265faa486004e7fd8daaf1a577cfcac0070ce55d926922883" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "frame-system" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc19d4d4037b695805385d56983da173bbb969f68e0e4e6a1240bb30118e87d7" +checksum = "57e316407c45a5093c833966a906301aa0dcbd05048061cd9cde2548d017bfd9" dependencies = [ "cfg-if", "frame-support", @@ -3565,35 +3687,35 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "sp-version", - "sp-weights", + "sp-weights 24.0.0", ] [[package]] name = "frame-system-benchmarking" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb79e630dc8fbed5601e58c1b8d84ec3900a511f105140b5bbb6c18c476488d2" +checksum = "b5b1388055d29a7a1c4d41b1623d3fcbc9d7f31d17abe04500b270b26901d926" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 25.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "frame-system-rpc-runtime-api" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13ed2be7e4ad2cf140d16b94194595d3b2fea0b60a46832945c497924c2d0d0" +checksum = "17572a34fd866ad6cab6977a2c30b38645e0a499b3486de00ae9103f7002d6d3" dependencies = [ "parity-scale-codec", "sp-api", @@ -3601,22 +3723,25 @@ dependencies = [ [[package]] name = "frame-try-runtime" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9eceb53c4efa82dd7dd08f0770abfaa9587c592a015b21dc29ce4c24422de13" +checksum = "f082e770275f9b46ddf46b09bc7a993f84db691c39d9e4d038ac07443cb17a18" dependencies = [ "frame-support", "parity-scale-codec", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "fs-err" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] name = "fs2" @@ -3636,9 +3761,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -3651,9 +3776,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -3661,15 +3786,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -3679,9 +3804,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -3698,15 +3823,28 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite 0.2.13", +] + [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -3717,20 +3855,20 @@ checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", "rustls 0.20.9", - "webpki 0.22.4", + "webpki", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" @@ -3740,9 +3878,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -3765,19 +3903,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "fxprof-processed-profile" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" -dependencies = [ - "bitflags 2.4.1", - "debugid", - "fxhash", - "serde", - "serde_json", -] - [[package]] name = "genco" version = "0.16.1" @@ -3822,9 +3947,9 @@ dependencies = [ [[package]] name = "generics" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39102f6bbbd8e1cf7ef8f9d86b3d388cb86d0cd4781b0e31d2622bd0fcd1aa9" +checksum = "62ea1d5f3caf0f32d023235ebfd9509cb553a349ce605e28a192a7b51c19801a" [[package]] name = "gethostname" @@ -3849,9 +3974,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -3860,16 +3985,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug 0.3.0", - "polyval 0.5.3", -] - [[package]] name = "ghash" version = "0.5.0" @@ -3877,7 +3992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" dependencies = [ "opaque-debug 0.3.0", - "polyval 0.6.1", + "polyval", ] [[package]] @@ -3893,9 +4008,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -3905,24 +4020,24 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", ] [[package]] name = "globwalk" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "ignore", "walkdir", ] @@ -3947,7 +4062,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff 0.12.1", "rand_core 0.6.4", - "subtle", + "subtle 2.5.0", ] [[package]] @@ -3958,14 +4073,14 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff 0.13.0", "rand_core 0.6.4", - "subtle", + "subtle 2.5.0", ] [[package]] name = "h2" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -3973,7 +4088,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.2.3", "slab", "tokio", "tokio-util", @@ -3982,15 +4097,19 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "handlebars" -version = "4.4.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" dependencies = [ "log", "pest", @@ -4021,7 +4140,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] @@ -4030,22 +4149,36 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", ] [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.8", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashlink" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", "byteorder", "flate2", "nom", @@ -4058,7 +4191,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "headers-core", "http", @@ -4093,9 +4226,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "hex" @@ -4105,9 +4238,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac 0.12.1", ] @@ -4128,7 +4261,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "crypto-mac 0.11.1", + "crypto-mac 0.11.0", "digest 0.9.0", ] @@ -4154,11 +4287,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4174,9 +4307,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -4185,9 +4318,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -4220,9 +4353,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -4235,7 +4368,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.4.10", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -4252,11 +4385,11 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.8", + "rustls 0.21.10", "rustls-native-certs", "tokio", "tokio-rustls", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", ] [[package]] @@ -4286,16 +4419,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -4326,9 +4459,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -4336,21 +4469,21 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.7.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" +checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "if-watch" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb892e5777fe09e16f3d44de7802f4daa7267ecbe8c466f19d94e25bb0c303e" +checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" dependencies = [ - "async-io", + "async-io 2.3.1", "core-foundation", "fnv", "futures", @@ -4365,17 +4498,16 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ + "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata 0.4.5", "same-file", - "thread_local", "walkdir", "winapi-util", ] @@ -4441,19 +4573,25 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.3", ] +[[package]] +name = "indexmap-nostd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" + [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -4507,23 +4645,10 @@ dependencies = [ ] [[package]] -name = "interceptor" -version = "0.8.2" +name = "intx" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8a11ae2da61704edada656798b61c94b35ecac2c58eb955156987d5e6be90b" -dependencies = [ - "async-trait", - "bytes", - "log", - "rand 0.8.5", - "rtcp", - "rtp", - "thiserror", - "tokio", - "waitgroup", - "webrtc-srtp", - "webrtc-util", -] +checksum = "f6f38a50a899dc47a6d0ed5508e7f601a2e34c3a85303514b5d137f3c10a0c75" [[package]] name = "io-lifetimes" @@ -4531,7 +4656,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.6", "libc", "windows-sys 0.48.0", ] @@ -4582,13 +4707,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.21", - "windows-sys 0.48.0", + "hermit-abi 0.3.6", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -4609,35 +4734,26 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -4773,9 +4889,9 @@ dependencies = [ [[package]] name = "json-number" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280f53da10842ffc42737ac8a6f2c14ced71f950de1cdb6765264a2eb1100cc5" +checksum = "4c54d19ae7e6fc83aafa649707655a9a0ac956a0f62793bde4cfd193b0693fdf" dependencies = [ "lexical", "ryu-js", @@ -4819,15 +4935,27 @@ version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "367a292944c07385839818bb71c8d76611138e2dedb0677d035b8da21d29c78b" dependencies = [ - "jsonrpsee-core", - "jsonrpsee-http-client", + "jsonrpsee-core 0.16.3", + "jsonrpsee-http-client 0.16.3", "jsonrpsee-proc-macros", "jsonrpsee-server", - "jsonrpsee-types", + "jsonrpsee-types 0.16.3", "jsonrpsee-ws-client", "tracing", ] +[[package]] +name = "jsonrpsee" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +dependencies = [ + "jsonrpsee-client-transport 0.20.3", + "jsonrpsee-core 0.20.3", + "jsonrpsee-http-client 0.20.3", + "jsonrpsee-types 0.20.3", +] + [[package]] name = "jsonrpsee-client-transport" version = "0.16.3" @@ -4836,8 +4964,28 @@ checksum = "c8b3815d9f5d5de348e5f162b316dc9cdf4548305ebb15b4eb9328e66cf27d7a" dependencies = [ "futures-util", "http", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "webpki-roots 0.25.4", +] + +[[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", + "jsonrpsee-core 0.20.3", "pin-project", "rustls-native-certs", "soketto", @@ -4846,7 +4994,7 @@ dependencies = [ "tokio-rustls", "tokio-util", "tracing", - "webpki-roots 0.25.2", + "url", ] [[package]] @@ -4857,7 +5005,7 @@ checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" dependencies = [ "anyhow", "arrayvec 0.7.4", - "async-lock", + "async-lock 2.8.0", "async-trait", "beef", "futures-channel", @@ -4865,7 +5013,7 @@ dependencies = [ "futures-util", "globset", "hyper", - "jsonrpsee-types", + "jsonrpsee-types 0.16.3", "parking_lot 0.12.1", "rand 0.8.5", "rustc-hash", @@ -4877,6 +5025,28 @@ dependencies = [ "tracing", ] +[[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", + "jsonrpsee-types 0.20.3", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "jsonrpsee-http-client" version = "0.16.3" @@ -4886,8 +5056,8 @@ dependencies = [ "async-trait", "hyper", "hyper-rustls", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", "rustc-hash", "serde", "serde_json", @@ -4897,15 +5067,35 @@ dependencies = [ ] [[package]] -name = "jsonrpsee-proc-macros" -version = "0.16.3" +name = "jsonrpsee-http-client" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44e8ab85614a08792b9bff6c8feee23be78c98d0182d4c622c05256ab553892a" +checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" dependencies = [ - "heck", - "proc-macro-crate", - "proc-macro2", - "quote", + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core 0.20.3", + "jsonrpsee-types 0.20.3", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44e8ab85614a08792b9bff6c8feee23be78c98d0182d4c622c05256ab553892a" +dependencies = [ + "heck", + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -4919,8 +5109,8 @@ dependencies = [ "futures-util", "http", "hyper", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", "serde", "serde_json", "soketto", @@ -4945,6 +5135,20 @@ dependencies = [ "tracing", ] +[[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.16.3" @@ -4952,9 +5156,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e1b3975ed5d73f456478681a417128597acd6a2487855fdb7b4a3d4d195bf5e" dependencies = [ "http", - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-client-transport 0.16.3", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", ] [[package]] @@ -4963,14 +5167,14 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", "anyhow", - "base64 0.21.5", + "base64 0.21.7", "bytecount", - "clap 4.4.7", + "clap 4.5.1", "fancy-regex", "fraction", - "getrandom 0.2.10", + "getrandom 0.2.12", "iso8601", "itoa", "memchr", @@ -4984,7 +5188,7 @@ dependencies = [ "serde_json", "time", "url", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] @@ -5025,30 +5229,37 @@ dependencies = [ "elliptic-curve 0.12.3", "serdect", "sha2 0.10.8", + "sha3", ] [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", - "ecdsa 0.16.8", - "elliptic-curve 0.13.6", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "sha2 0.10.8", ] [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + [[package]] name = "kvdb" version = "0.13.0" @@ -5178,18 +5389,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -5200,14 +5411,14 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libp2p" -version = "0.51.3" +version = "0.51.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" +checksum = "f35eae38201a993ece6bdc823292d6abd1bffed1c4d0f4a3517d2bd8e1d917fe" dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.10", + "getrandom 0.2.12", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -5225,7 +5436,6 @@ dependencies = [ "libp2p-swarm", "libp2p-tcp", "libp2p-wasm-ext", - "libp2p-webrtc", "libp2p-websocket", "libp2p-yamux", "multiaddr", @@ -5327,7 +5537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" dependencies = [ "bs58 0.4.0", - "ed25519-dalek", + "ed25519-dalek 2.1.1", "log", "multiaddr", "multihash", @@ -5537,12 +5747,12 @@ dependencies = [ "futures-rustls", "libp2p-core", "libp2p-identity", - "rcgen 0.10.0", + "rcgen", "ring 0.16.20", "rustls 0.20.9", "thiserror", - "webpki 0.22.4", - "x509-parser 0.14.0", + "webpki", + "x509-parser", "yasna", ] @@ -5560,37 +5770,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "libp2p-webrtc" -version = "0.4.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" -dependencies = [ - "async-trait", - "asynchronous-codec", - "bytes", - "futures", - "futures-timer", - "hex", - "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-noise", - "log", - "multihash", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "rcgen 0.9.3", - "serde", - "stun", - "thiserror", - "tinytemplate", - "tokio", - "tokio-util", - "webrtc", -] - [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -5623,6 +5802,17 @@ dependencies = [ "yamux", ] +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "librocksdb-sys" version = "0.11.0+8.1.1" @@ -5665,7 +5855,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle", + "subtle 2.5.0", ] [[package]] @@ -5688,9 +5878,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "pkg-config", @@ -5744,9 +5934,21 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lioness" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2 0.8.1", + "chacha", + "keystream", +] [[package]] name = "lock_api" @@ -5835,9 +6037,9 @@ dependencies = [ [[package]] name = "mach2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ "libc", ] @@ -5850,50 +6052,50 @@ checksum = "f21755d53936fc1663b414dba30636788f2183d3e782bdee4b1e7236637974e7" [[package]] name = "macro_magic" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aee866bfee30d2d7e83835a4574aad5b45adba4cc807f2a3bbba974e5d4383c9" +checksum = "e03844fc635e92f3a0067e25fa4bf3e3dbf3f2927bf3aa01bb7bc8f1c428949d" dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "macro_magic_core" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e766a20fd9c72bab3e1e64ed63f36bd08410e75803813df210d1ce297d7ad00" +checksum = "468155613a44cfd825f1fb0ffa532b018253920d404e6fca1e8d43155198a46d" dependencies = [ "const-random", "derive-syn-parse", "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "macro_magic_core_macros" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d710e1214dffbab3b5dacb21475dde7d6ed84c69ff722b3a47a782668d44fbac" +checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "macro_magic_macros" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fb85ec1620619edf2984a7693497d4ec88a9665d8b87e942856884c92dbf2a" +checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -5948,21 +6150,11 @@ dependencies = [ "rawpointer", ] -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest 0.10.7", -] - [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memfd" @@ -5970,7 +6162,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.31", ] [[package]] @@ -5982,15 +6174,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.8.0" @@ -6000,15 +6183,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "memory-db" version = "0.32.0" @@ -6031,14 +6205,15 @@ dependencies = [ ] [[package]] -name = "metadeps" -version = "1.1.2" +name = "merlin" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b122901b3a675fac8cecf68dcb2f0d3036193bc861d1ac0e1c337f7d5254c2" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" dependencies = [ - "error-chain", - "pkg-config", - "toml 0.2.1", + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", ] [[package]] @@ -6047,18 +6222,18 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", "metrics-macros", "portable-atomic", ] [[package]] name = "metrics-exporter-prometheus" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a4964177ddfdab1e3a2b37aec7cf320e14169abb0ed73999f558136409178d5" +checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "hyper", "indexmap 1.9.3", "ipnet", @@ -6072,13 +6247,13 @@ dependencies = [ [[package]] name = "metrics-macros" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -6131,24 +6306,49 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] +[[package]] +name = "mixnet" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa3eb39495d8e2e2947a1d862852c90cc6a4a8845f8b41c8829cb9fcc047f4a" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "bitflags 1.3.2", + "blake2 0.10.6", + "c2-chacha", + "curve25519-dalek 4.1.2", + "either", + "hashlink", + "lioness", + "log", + "parking_lot 0.12.1", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_distr", + "subtle 2.5.0", + "thiserror", + "zeroize", +] + [[package]] name = "mockall" version = "0.11.4" @@ -6176,6 +6376,24 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "mockito" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d10030163d67f681db11810bc486df3149e6d91c8b4f3f96fa8b62b546c2cef8" +dependencies = [ + "assert-json-diff", + "colored", + "difference", + "httparse", + "lazy_static", + "log", + "rand 0.8.5", + "regex", + "serde_json", + "serde_urlencoded", +] + [[package]] name = "mockito" version = "1.2.0" @@ -6272,7 +6490,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro-error", "proc-macro2", "quote", @@ -6302,9 +6520,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.3" +version = "0.32.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" dependencies = [ "approx", "matrixmultiply", @@ -6422,9 +6640,9 @@ dependencies = [ [[package]] name = "newtype-derive-2018" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742e162dd2b575e1870f918cb1032962aca5ea2dfb6a6988ce1455e74a0f8e83" +checksum = "db3cd4bb0e468d0aa3ec7d2ef337ddc0ad969648145bb467c88a045e6c8556ec" dependencies = [ "generics", ] @@ -6438,7 +6656,6 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.6.5", ] [[package]] @@ -6447,7 +6664,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "libc", ] @@ -6461,18 +6678,22 @@ dependencies = [ "serde", ] +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + [[package]] name = "node-chronicle" version = "4.0.0-dev" dependencies = [ - "clap 4.4.7", + "clap 4.5.1", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", "futures", - "jsonrpsee", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc", + "jsonrpsee 0.16.3", "runtime-chronicle", "sc-basic-authorship", "sc-cli", @@ -6494,17 +6715,24 @@ dependencies = [ "sp-blockchain", "sp-consensus-aura", "sp-consensus-grandpa", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-io", + "sp-io 27.0.0", "sp-keyring", - "sp-runtime", + "sp-runtime 28.0.0", "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", + "tracing", "try-runtime-cli", ] +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -6570,13 +6798,19 @@ checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa" [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-format" version = "0.4.4" @@ -6589,19 +6823,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -6622,9 +6855,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -6636,7 +6869,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.6", "libc", ] @@ -6663,7 +6896,7 @@ checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" dependencies = [ "base64 0.13.1", "chrono", - "getrandom 0.2.10", + "getrandom 0.2.12", "http", "rand 0.8.5", "reqwest", @@ -6689,36 +6922,27 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] -[[package]] -name = "oid-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" -dependencies = [ - "asn1-rs 0.3.1", -] - [[package]] name = "oid-registry" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" @@ -6729,7 +6953,7 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "opa" version = "0.9.0" -source = "git+https://github.com/tamasfe/opa-rs?rev=3cf7fea#3cf7fea850037fda7c353987db2d97ab90cc21f7" +source = "git+https://github.com/chronicleworks/opa-rs?rev=9fa2fbce#9fa2fbce24e90d5cc409091082bcafbfe420b47b" dependencies = [ "anyhow", "bytes", @@ -6739,129 +6963,37 @@ dependencies = [ "tar", "tempfile", "thiserror", + "tracing", "walkdir", - "wasmtime 10.0.2", + "wasmtime", "which", ] [[package]] -name = "opa-tp" -version = "0.7.5" -dependencies = [ - "async-stl-client", - "async-trait", - "bytes", - "chronicle-signing", - "chronicle-telemetry", - "clap 3.2.25", - "const_format", - "hex", - "insta", - "k256 0.11.6", - "opa-tp-protocol", - "prost 0.10.4", - "protobuf", - "rand 0.8.5", - "rand_core 0.6.4", - "sawtooth-sdk", - "serde_json", - "thiserror", - "tokio", - "tracing", - "url", -] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] -name = "opa-tp-protocol" -version = "0.7.5" +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ - "async-stl-client", - "async-trait", - "chronicle-signing", - "derivative", - "futures", - "glob", - "hex", - "k256 0.11.6", - "lazy_static", - "openssl", - "prost 0.10.4", - "prost-build 0.10.4", - "prost-types 0.11.9", - "rand 0.8.5", - "rand_core 0.6.4", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "uuid 1.5.0", - "zmq", -] - -[[package]] -name = "opactl" -version = "0.7.5" -dependencies = [ - "async-stl-client", - "async-trait", - "chronicle-signing", - "chronicle-telemetry", - "clap 4.4.7", - "common", - "const_format", - "futures", - "hex", - "insta", - "k256 0.11.6", - "lazy_static", - "opa-tp", - "opa-tp-protocol", - "portpicker", - "prost 0.10.4", - "protobuf", - "rand 0.8.5", - "rand_core 0.6.4", - "sawtooth-sdk", - "serde", - "serde_derive", - "serde_json", - "tempfile", - "thiserror", - "tmq", - "tokio", - "tokio-stream", - "tracing", - "url", - "user-error", - "uuid 1.5.0", -] - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", ] [[package]] @@ -6872,7 +7004,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -6883,9 +7015,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", @@ -6899,39 +7031,45 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f4b8347cc26099d3aeee044065ecc3ae11469796b4d65d065a23a584ed92a6f" dependencies = [ - "opentelemetry_api 0.19.0", - "opentelemetry_sdk 0.19.0", + "opentelemetry_api", + "opentelemetry_sdk", ] [[package]] name = "opentelemetry" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" dependencies = [ - "opentelemetry_api 0.20.0", - "opentelemetry_sdk 0.20.0", + "futures-core", + "futures-sink", + "indexmap 2.2.3", + "js-sys", + "once_cell", + "pin-project-lite 0.2.13", + "thiserror", + "urlencoding", ] [[package]] name = "opentelemetry-http" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7594ec0e11d8e33faf03530a4c49af7064ebba81c1480e01be67d90b356508b" +checksum = "7f51189ce8be654f9b5f7e70e49967ed894e84a06fc35c6c042e64ac1fc5399e" dependencies = [ "async-trait", "bytes", "http", - "opentelemetry_api 0.20.0", + "opentelemetry 0.21.0", ] [[package]] name = "opentelemetry-semantic-conventions" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9f9340ad135068800e7f1b24e9e09ed9e7143f5bf8518ded3d3ec69789269" +checksum = "f5774f1ef1f982ef2a447f6ee04ec383981a3ab99c8e77a1a7b30182e65bbc84" dependencies = [ - "opentelemetry 0.20.0", + "opentelemetry 0.21.0", ] [[package]] @@ -6949,22 +7087,6 @@ dependencies = [ "urlencoding", ] -[[package]] -name = "opentelemetry_api" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" -dependencies = [ - "futures-channel", - "futures-util", - "indexmap 1.9.3", - "js-sys", - "once_cell", - "pin-project-lite 0.2.13", - "thiserror", - "urlencoding", -] - [[package]] name = "opentelemetry_sdk" version = "0.19.0" @@ -6977,7 +7099,7 @@ dependencies = [ "futures-executor", "futures-util", "once_cell", - "opentelemetry_api 0.19.0", + "opentelemetry_api", "percent-encoding", "rand 0.8.5", "thiserror", @@ -6985,41 +7107,12 @@ dependencies = [ "tokio-stream", ] -[[package]] -name = "opentelemetry_sdk" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" -dependencies = [ - "async-trait", - "crossbeam-channel", - "futures-channel", - "futures-executor", - "futures-util", - "once_cell", - "opentelemetry_api 0.20.0", - "ordered-float", - "percent-encoding", - "rand 0.8.5", - "regex", - "thiserror", -] - [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - [[package]] name = "os_str_bytes" version = "6.6.1" @@ -7038,33 +7131,11 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -[[package]] -name = "p256" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - -[[package]] -name = "p384" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - [[package]] name = "pallet-aura" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7e2b1cf20dbd9fe630c69b4b0d3bb0d5fa1223ee728b0fc0064ef65698918c2" +checksum = "04fbef67cf62445b7fd8e68241e6b71d9fb8c77abb3d52259eebf525a4cd5586" dependencies = [ "frame-support", "frame-system", @@ -7072,41 +7143,25 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 27.0.0", "sp-consensus-aura", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "pallet-authorship" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae682e78744224150298730dfa1e2c39220e600dce17e42d2c77e49af3d9c59f" +checksum = "2d38eab59f7d15fe43c81fc3cd92f4c1f895ca6d0efb74fc2a6d6d7d3d34d413" dependencies = [ "frame-support", "frame-system", "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-balances" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c17ec19ad23b26866ad7d60cdf8b613f653db7f44232aa25009811441908e2b" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] @@ -7122,19 +7177,21 @@ dependencies = [ "newtype-derive-2018", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "serde", + "sp-core 25.0.0", + "sp-core-hashing 14.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "tracing", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] name = "pallet-grandpa" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977d01d5ce3f06fa17adf2ffa55ebaea765efa23bc11a242773a28955ee1d02b" +checksum = "b87c7f4cd94a526054dfebf7a84fbcaf6385033defa246ad83e321e71f8c5a92" dependencies = [ "frame-benchmarking", "frame-support", @@ -7144,21 +7201,46 @@ dependencies = [ "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 27.0.0", "sp-consensus-grandpa", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", "sp-session", "sp-staking", - "sp-std", + "sp-std 12.0.0", +] + +[[package]] +name = "pallet-opa" +version = "0.7.5" +dependencies = [ + "chronicle-telemetry", + "common", + "frame-benchmarking", + "frame-support", + "frame-system", + "k256 0.11.6", + "macro-attr-2018", + "newtype-derive-2018", + "parity-scale-codec", + "scale-info", + "serde", + "serde_json", + "sp-core 25.0.0", + "sp-core-hashing 14.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", + "tracing", + "uuid 1.6.1", ] [[package]] name = "pallet-session" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8482f465a73688a7d58e20dea4b10c9a0425995975b2a43d9ce4fe9a21a491" +checksum = "768a6fb5333efc2bd2a3538c1d6ffa4178398660d4e3be89f2eb82d4e9088ae6" dependencies = [ "frame-support", "frame-system", @@ -7167,21 +7249,21 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-runtime 28.0.0", "sp-session", "sp-staking", - "sp-state-machine", - "sp-std", - "sp-trie", + "sp-state-machine 0.32.0", + "sp-std 12.0.0", + "sp-trie 26.0.0", ] [[package]] name = "pallet-sudo" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "679c265de3a128714d43a7e2edf5ea29f2a39df65e4c44e216c04d6bb5dd5be7" +checksum = "fcec9f73ecb8d0439a13043a253a9fd90aa6bf5aece6470194bbfc7f79256d88" dependencies = [ "docify", "frame-benchmarking", @@ -7189,16 +7271,16 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "pallet-timestamp" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac4e66316d53673471420fb887b6a74e2507df169ced62584507ff0fb065c6b" +checksum = "b25ec8749cf3f481b5e5199be701bac0dea835851b83fc7c455192762711858d" dependencies = [ "docify", "frame-benchmarking", @@ -7208,67 +7290,20 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", - "sp-storage", + "sp-io 27.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", + "sp-storage 17.0.0", "sp-timestamp", ] -[[package]] -name = "pallet-transaction-payment" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4cbb78b8499af1d338072950e4aef6acf3cc630afdb8e19b00306e5252d0386" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-transaction-payment-rpc" -version = "26.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7857973b918e71367acb7c284c829612aa9c91a6ba1fb2985d56fbe224545" -dependencies = [ - "jsonrpsee", - "pallet-transaction-payment-rpc-runtime-api", - "parity-scale-codec", - "sp-api", - "sp-blockchain", - "sp-core", - "sp-rpc", - "sp-runtime", - "sp-weights", -] - -[[package]] -name = "pallet-transaction-payment-rpc-runtime-api" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402155004abb33b7f2eedfa60ba77fb6f898e62db979a796e013714d18a1c9c2" -dependencies = [ - "pallet-transaction-payment", - "parity-scale-codec", - "sp-api", - "sp-runtime", - "sp-weights", -] - [[package]] name = "parity-db" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e9ab494af9e6e813c72170f0d3c1de1500990d62c97cc05cc7576f91aa402f" +checksum = "592a28a24b09c9dc20ac8afaa6839abc417c720afe42c12e1e4a9d6aa2508d2e" dependencies = [ - "blake2", + "blake2 0.10.6", "crc32fast", "fs2", "hex", @@ -7280,13 +7315,14 @@ dependencies = [ "rand 0.8.5", "siphasher", "snap", + "winapi", ] [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -7299,11 +7335,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", "syn 1.0.109", @@ -7393,7 +7429,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" dependencies = [ - "crypto-mac 0.11.1", + "crypto-mac 0.11.0", ] [[package]] @@ -7405,6 +7441,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "pct-str" version = "1.2.0" @@ -7440,9 +7485,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "permutohedron" @@ -7452,9 +7497,9 @@ checksum = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c" [[package]] name = "pest" -version = "2.7.5" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -7463,9 +7508,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.5" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" dependencies = [ "pest", "pest_generator", @@ -7473,22 +7518,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.5" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "pest_meta" -version = "2.7.5" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" dependencies = [ "once_cell", "pest", @@ -7502,7 +7547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.2.3", ] [[package]] @@ -7545,22 +7590,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -7581,15 +7626,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pinvec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "840ab949b9845c83495aba5cdfb23ab17aaa67b99ac36b17211bd02a5f9e6b36" -dependencies = [ - "pow_of_2", -] - [[package]] name = "piper" version = "0.2.1" @@ -7618,20 +7654,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.8", - "spki 0.7.2", + "spki 0.7.3", ] [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" -version = "3.1.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "plotters" @@ -7663,19 +7699,20 @@ dependencies = [ [[package]] name = "poem" -version = "1.3.58" +version = "1.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc7ae19f3e791ae8108b08801abb3708d64d3a16490c720e0b81040cae87b5d" +checksum = "504774c97b0744c1ee108a37e5a65a9745a4725c4c06277521dabc28eb53a904" dependencies = [ "async-trait", - "base64 0.21.5", + "base64 0.21.7", "bytes", "futures-util", "headers", "http", "hyper", "mime", - "opentelemetry 0.20.0", + "nix 0.27.1", + "opentelemetry 0.21.0", "opentelemetry-http", "opentelemetry-semantic-conventions", "parking_lot 0.12.1", @@ -7693,18 +7730,19 @@ dependencies = [ "tokio-tungstenite", "tokio-util", "tracing", + "wildmatch", ] [[package]] name = "poem-derive" -version = "1.3.58" +version = "1.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2550a0bce7273b278894ef3ccc5a6869e7031b6870042f3cc6826ed9faa980a6" +checksum = "42ddcf4680d8d867e1e375116203846acb088483fa2070244f90589f458bbb31" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -7724,26 +7762,28 @@ dependencies = [ ] [[package]] -name = "poly1305" -version = "0.7.2" +name = "polling" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" dependencies = [ - "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash 0.4.1", + "cfg-if", + "concurrent-queue", + "pin-project-lite 0.2.13", + "rustix 0.38.31", + "tracing", + "windows-sys 0.52.0", ] [[package]] -name = "polyval" -version = "0.5.3" +name = "poly1305" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cfg-if", "cpufeatures", "opaque-debug 0.3.0", - "universal-hash 0.4.1", + "universal-hash", ] [[package]] @@ -7755,14 +7795,14 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug 0.3.0", - "universal-hash 0.5.1", + "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" [[package]] name = "portpicker" @@ -7773,12 +7813,6 @@ dependencies = [ "rand 0.8.5", ] -[[package]] -name = "pow_of_2" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4240ec1e46f35cb33cba66075d04778f53a5eba59ba4aecf2b1f8f6c4204d383" - [[package]] name = "powerfmt" version = "0.2.0" @@ -7808,7 +7842,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools 0.10.5", + "itertools", "normalize-line-endings", "predicates-core", "regex", @@ -7816,13 +7850,12 @@ dependencies = [ [[package]] name = "predicates" -version = "3.0.4" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" dependencies = [ "anstyle", "difflib", - "itertools 0.11.0", "predicates-core", ] @@ -7863,12 +7896,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -7894,6 +7927,16 @@ dependencies = [ "toml 0.5.11", ] +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -7920,20 +7963,20 @@ dependencies = [ [[package]] name = "proc-macro-warning" -version = "0.4.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" +checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -7972,24 +8015,24 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "proptest" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.4.2", "lazy_static", "num-traits", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", "rusty-fork", "tempfile", "unarray", @@ -7997,81 +8040,36 @@ dependencies = [ [[package]] name = "prost" -version = "0.10.4" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive 0.10.1", + "prost-derive", ] [[package]] -name = "prost" +name = "prost-build" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost-build" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae5a4388762d5815a9fc0dea33c56b021cdc8dde0c55e0c9ca57197254b0cab" -dependencies = [ - "bytes", - "cfg-if", - "cmake", - "heck", - "itertools 0.10.5", - "lazy_static", - "log", - "multimap", - "petgraph", - "prost 0.10.4", - "prost-types 0.10.1", - "regex", - "tempfile", - "which", -] - -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck", - "itertools 0.10.5", + "itertools", "lazy_static", "log", "multimap", "petgraph", "prettyplease 0.1.25", - "prost 0.11.9", - "prost-types 0.11.9", + "prost", + "prost-types", "regex", "syn 1.0.109", "tempfile", "which", ] -[[package]] -name = "prost-derive" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "prost-derive" version = "0.11.9" @@ -8079,73 +8077,119 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools", "proc-macro2", "quote", "syn 1.0.109", ] -[[package]] -name = "prost-types" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" -dependencies = [ - "bytes", - "prost 0.10.4", -] - [[package]] name = "prost-types" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "prost 0.11.9", + "prost", ] [[package]] -name = "protobuf" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +name = "protocol-abstract" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "futures", + "k256 0.11.6", + "pallet-chronicle", + "serde", + "subxt", + "thiserror", + "tokio", + "tracing", +] [[package]] -name = "protobuf-codegen" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6" +name = "protocol-substrate" +version = "0.1.0" dependencies = [ - "protobuf", + "anyhow", + "async-trait", + "chronicle-signing", + "common", + "derivative", + "futures", + "hex", + "k256 0.11.6", + "pallet-chronicle", + "protocol-abstract", + "serde", + "subxt", + "thiserror", + "tokio", + "tracing", + "uuid 1.6.1", ] [[package]] -name = "protoc" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0218039c514f9e14a5060742ecd50427f8ac4f85a6dc58f2ddb806e318c55ee" +name = "protocol-substrate-chronicle" +version = "0.1.0" dependencies = [ - "log", - "which", + "async-trait", + "chronicle-signing", + "chronicle-telemetry", + "clap_builder", + "common", + "embedded-substrate", + "futures", + "hex", + "k256 0.11.6", + "opa", + "pallet-chronicle", + "parity-scale-codec", + "protocol-abstract", + "protocol-substrate", + "scale-encode", + "scale-info", + "serde", + "subxt", + "thiserror", + "tokio", + "tracing", + "uuid 1.6.1", ] [[package]] -name = "protoc-rust" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f8a182bb17c485f20bdc4274a8c39000a61024cfe461c799b50fec77267838" +name = "protocol-substrate-opa" +version = "0.7.5" dependencies = [ - "protobuf", - "protobuf-codegen", - "protoc", - "tempfile", + "async-trait", + "chronicle-signing", + "common", + "derivative", + "futures", + "glob", + "hex", + "lazy_static", + "opa", + "pallet-opa", + "protocol-abstract", + "protocol-substrate", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "serde_json", + "subxt", + "thiserror", + "tokio", + "tracing", + "uuid 1.6.1", ] [[package]] name = "psl" -version = "2.1.4" +version = "2.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1be0afcd844b15cfce18bf8cccf2dfa887a00a6454a9ea135f122b948cee91" +checksum = "9cc7ffe15173de4c22def678345bb2ac7e1646b83a37c1484572732b5a79a49e" dependencies = [ "psl-types", ] @@ -8241,14 +8285,14 @@ dependencies = [ "thiserror", "tinyvec", "tracing", - "webpki 0.22.4", + "webpki", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -8330,7 +8374,17 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", ] [[package]] @@ -8386,9 +8440,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -8396,27 +8450,14 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", ] -[[package]] -name = "rcgen" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" -dependencies = [ - "pem", - "ring 0.16.20", - "time", - "x509-parser 0.13.2", - "yasna", -] - [[package]] name = "rcgen" version = "0.10.0" @@ -8452,15 +8493,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -8472,33 +8504,33 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", + "getrandom 0.2.12", + "libredox", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acde58d073e9c79da00f2b5b84eed919c8326832648a5b109b3fce1bb1175280" +checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" +checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -8513,28 +8545,15 @@ dependencies = [ "smallvec", ] -[[package]] -name = "regalloc2" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" -dependencies = [ - "hashbrown 0.13.2", - "log", - "rustc-hash", - "slice-group-by", - "smallvec", -] - [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -8549,9 +8568,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -8564,12 +8583,6 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -8578,17 +8591,17 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "relative-path" -version = "1.9.0" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" +checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -8607,11 +8620,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.8", + "rustls 0.21.10", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -8621,7 +8635,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", "winreg", ] @@ -8653,7 +8667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle", + "subtle 2.5.0", ] [[package]] @@ -8682,16 +8696,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.5" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "getrandom 0.2.10", + "cfg-if", + "getrandom 0.2.12", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -8706,13 +8721,13 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -8726,17 +8741,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rtcp" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1919efd6d4a6a85d13388f9487549bb8e359f17198cc03ffd72f79b553873691" -dependencies = [ - "bytes", - "thiserror", - "webrtc-util", -] - [[package]] name = "rtnetlink" version = "0.10.1" @@ -8754,26 +8758,21 @@ dependencies = [ [[package]] name = "rtoolbox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] -name = "rtp" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a095411ff00eed7b12e4c6a118ba984d113e1079582570d56a5ee723f11f80" +name = "runtime-api-chronicle" +version = "1.0.0" dependencies = [ - "async-trait", - "bytes", - "rand 0.8.5", - "serde", - "thiserror", - "webrtc-util", + "common", + "sp-api", + "sp-core 25.0.0", ] [[package]] @@ -8788,30 +8787,64 @@ dependencies = [ "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-aura", - "pallet-balances", "pallet-chronicle", "pallet-grandpa", + "pallet-opa", "pallet-sudo", "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", + "runtime-api-chronicle", "scale-info", "sp-api", "sp-block-builder", "sp-consensus-aura", "sp-consensus-grandpa", - "sp-core", + "sp-core 25.0.0", "sp-inherents", "sp-offchain", - "sp-runtime", + "sp-runtime 28.0.0", "sp-session", - "sp-std", + "sp-std 12.0.0", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", ] +[[package]] +name = "rust-embed" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.49", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +dependencies = [ + "globset", + "sha2 0.10.8", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -8836,7 +8869,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.20", + "semver 1.0.22", ] [[package]] @@ -8912,28 +8945,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring 0.16.20", - "sct 0.6.1", - "webpki 0.21.4", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", ] [[package]] @@ -8944,20 +8964,20 @@ checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring 0.16.20", - "sct 0.7.1", - "webpki 0.22.4", + "sct", + "webpki", ] [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.5", + "ring 0.17.8", "rustls-webpki", - "sct 0.7.1", + "sct", ] [[package]] @@ -8974,11 +8994,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] [[package]] @@ -8987,7 +9007,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.5", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -9009,6 +9029,17 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "ruzstd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc" +dependencies = [ + "byteorder", + "thiserror-core", + "twox-hash", +] + [[package]] name = "rvs_derive" version = "0.3.2" @@ -9042,9 +9073,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "ryu-js" @@ -9077,82 +9108,22 @@ dependencies = [ ] [[package]] -name = "sawtooth-sdk" -version = "0.5.3" -source = "git+https://github.com/hyperledger/sawtooth-sdk-rust?rev=5a300de#5a300de293666aa056a2970a39651d4dd5098885" +name = "sc-allocator" +version = "20.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b4c5976a9cff7fcf24c946276a62ea7837862b6f3bf9f8011f08faf4f08474" dependencies = [ - "ctrlc", - "glob", - "hex", - "libc", "log", - "openssl", - "protobuf", - "protoc-rust", - "rand 0.8.5", - "secp256k1 0.27.0", - "sha2 0.10.8", - "uuid 0.8.2", - "zmq", + "sp-core 25.0.0", + "sp-wasm-interface 18.0.0", + "thiserror", ] [[package]] -name = "sawtooth_tp" -version = "0.7.5" -dependencies = [ - "async-stl-client", - "async-trait", - "bytes", - "chronicle-protocol", - "chronicle-signing", - "chronicle-telemetry", - "chrono", - "clap 3.2.25", - "common", - "const_format", - "custom_error", - "derivative", - "futures", - "glob", - "hex", - "insta", - "lazy_static", - "opa-tp-protocol", - "openssl", - "opentelemetry 0.19.0", - "prost 0.10.4", - "protobuf", - "rand 0.8.5", - "rand_core 0.6.4", - "sawtooth-sdk", - "serde", - "serde_derive", - "serde_json", - "tempfile", - "tokio", - "tracing", - "url", - "uuid 1.5.0", - "zmq", -] - -[[package]] -name = "sc-allocator" -version = "19.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd6e58990dcb1eae76db49c456ded9a7906ee194857cf1dfb00da8bbc8cf73d" -dependencies = [ - "log", - "sp-core", - "sp-wasm-interface", - "thiserror", -] - -[[package]] -name = "sc-basic-authorship" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f802a95cece137daa3a0980f41a8e9265aa65d1b078f8d771f7d2f41e04266" +name = "sc-basic-authorship" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0aa6c85e3e0b5af9cab7078166d8c4575b7b9edac0ade6be1aadee828420104" dependencies = [ "futures", "futures-timer", @@ -9166,33 +9137,33 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-runtime", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", ] [[package]] name = "sc-block-builder" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4653cc3665319f76451f651bc5e3eb84965802293daeaf2def5bfe9c1310171b" +checksum = "9d3999b9b758c09a6c1155e481b683ee87712f071cc5a0679f9ee4906a14a404" dependencies = [ "parity-scale-codec", "sc-client-api", "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-runtime", + "sp-runtime 28.0.0", ] [[package]] name = "sc-chain-spec" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5fae1616d342e570fb4770c9f1a73ab8e1aecb9c5b71020404f8e45db458260" +checksum = "ec7e711ea9870d3fb8e2a3ea5b601a9e20c63d0d2f457f40146407721e246a77" dependencies = [ "memmap2", "sc-chain-spec-derive", @@ -9203,32 +9174,32 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 25.0.0", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", ] [[package]] name = "sc-chain-spec-derive" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a074891d17c03c58b1314c9add361a5a7fb28d4d3addd7a32dca8b119bd877" +checksum = "1f25158f791eb48715da9322375598b541cadd1f193674e8a4d77c79ffa3d95d" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "sc-cli" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc423e21a22adc4f6056ccb5e19fca9ddc6cce1a49cd9aa44c53d6b2338fbeb3" +checksum = "22c61058223f80c1f961b03f7737529609a3283eef91129e971a1966101c18ea" dependencies = [ - "array-bytes", + "array-bytes 6.2.2", "chrono", - "clap 4.4.7", + "clap 4.5.1", "fdlimit", "futures", "libp2p-identity", @@ -9241,6 +9212,7 @@ dependencies = [ "sc-client-api", "sc-client-db", "sc-keystore", + "sc-mixnet", "sc-network", "sc-service", "sc-telemetry", @@ -9249,11 +9221,11 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", + "sp-core 25.0.0", "sp-keyring", - "sp-keystore", - "sp-panic-handler", - "sp-runtime", + "sp-keystore 0.31.0", + "sp-panic-handler 12.0.0", + "sp-runtime 28.0.0", "sp-version", "thiserror", "tiny-bip39", @@ -9262,9 +9234,9 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49efb455b1b276557ba3cac01c2e42811148cc73149858296e4ae96707dc70e" +checksum = "c7d32101f415f4d7ddbe8b5de1c1387a78d6dce070e26407ec605fe9f3fc9e23" dependencies = [ "fnv", "futures", @@ -9277,22 +9249,22 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 25.0.0", "sp-database", - "sp-externalities", - "sp-runtime", - "sp-state-machine", + "sp-externalities 0.23.0", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", "sp-statement-store", - "sp-storage", - "sp-trie", + "sp-storage 17.0.0", + "sp-trie 26.0.0", "substrate-prometheus-endpoint", ] [[package]] name = "sc-client-db" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1062af3e43f09e0080714382ee3e7dd850037908938323eefdcd4f4b61bdd6b" +checksum = "d4ced79f609a44782874d856cf39d256838957195ef34f4fb8ced90bf4b725d0" dependencies = [ "hash-db", "kvdb", @@ -9306,20 +9278,20 @@ dependencies = [ "sc-client-api", "sc-state-db", "schnellru", - "sp-arithmetic", + "sp-arithmetic 20.0.0", "sp-blockchain", - "sp-core", + "sp-core 25.0.0", "sp-database", - "sp-runtime", - "sp-state-machine", - "sp-trie", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", + "sp-trie 26.0.0", ] [[package]] name = "sc-consensus" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f8da1ef0f036209b80d8bde5c8990ea1a86241532d84b5fd15f5e721da849c" +checksum = "86e4100cc8fb3876708e1ec5a7c63af3baa75febd5051beb9ddd1e4835fdfc27" dependencies = [ "async-trait", "futures", @@ -9334,18 +9306,18 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 25.0.0", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", "substrate-prometheus-endpoint", "thiserror", ] [[package]] name = "sc-consensus-aura" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbb98be43737b79517f2de34b5185a58238dc8f69e84ddf7e4730bc0e2e2e65" +checksum = "5e3e282836a7deeeb71d965a0942828f81ae2b03fd67515b733d5f33dd5da855" dependencies = [ "async-trait", "futures", @@ -9357,28 +9329,28 @@ dependencies = [ "sc-consensus-slots", "sc-telemetry", "sp-api", - "sp-application-crypto", + "sp-application-crypto 27.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-slots", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.31.0", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", "thiserror", ] [[package]] name = "sc-consensus-grandpa" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98285bbed76ba058f3c9f4111471208cd4c246d2ca7b52b7fbea15afdbb40ca5" +checksum = "30cbc5db21ea2c4ba65b23315e73e69e8155630fb47c84b93d40b0e759c9d86d" dependencies = [ - "ahash 0.8.6", - "array-bytes", + "ahash 0.8.8", + "array-bytes 6.2.2", "async-trait", "dyn-clone", "finality-grandpa", @@ -9401,23 +9373,23 @@ dependencies = [ "sc-utils", "serde_json", "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-application-crypto 27.0.0", + "sp-arithmetic 20.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core", - "sp-keystore", - "sp-runtime", + "sp-core 25.0.0", + "sp-keystore 0.31.0", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", "thiserror", ] [[package]] name = "sc-consensus-slots" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a232d18eb53288775eaeb782cad70ca75815cd10e6212352e6e53cc3961931" +checksum = "2059681962e33394682627e7bd7245b5094236594f5c97c4c96988d901bda534" dependencies = [ "async-trait", "futures", @@ -9427,21 +9399,21 @@ dependencies = [ "sc-client-api", "sc-consensus", "sc-telemetry", - "sp-arithmetic", + "sp-arithmetic 20.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", ] [[package]] name = "sc-executor" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfeaa8dc2a70ed5820667d3251266ed156f38d8062c2f976aa7c618411f1776" +checksum = "225f2ad733bc7234a6638d5203624194824b2f78ab631bc911223f536a66b9c8" dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", @@ -9449,53 +9421,54 @@ dependencies = [ "sc-executor-wasmtime", "schnellru", "sp-api", - "sp-core", - "sp-externalities", - "sp-io", - "sp-panic-handler", - "sp-runtime-interface", - "sp-trie", + "sp-core 25.0.0", + "sp-externalities 0.23.0", + "sp-io 27.0.0", + "sp-panic-handler 12.0.0", + "sp-runtime-interface 21.0.0", + "sp-trie 26.0.0", "sp-version", - "sp-wasm-interface", + "sp-wasm-interface 18.0.0", "tracing", ] [[package]] name = "sc-executor-common" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d404519f2a636d5977b1ac16c90aeb4129fe4609a5b284960a2dcb005c08da6" +checksum = "169c1cfe81ba0e0d44ab4ada1600e30b6a9de588c792db73e32a854a6e3e1a87" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface", + "sp-wasm-interface 18.0.0", "thiserror", "wasm-instrument", ] [[package]] name = "sc-executor-wasmtime" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82515a0cb74a2acb58f6ced20fae56eeb87ba4d813e60e46cf190a53d44c931" +checksum = "f9167d733e928c528273be63b905ec750cfda85d740453071463da69f7d633bc" dependencies = [ "anyhow", "cfg-if", "libc", "log", + "parking_lot 0.12.1", "rustix 0.36.17", "sc-allocator", "sc-executor-common", - "sp-runtime-interface", - "sp-wasm-interface", - "wasmtime 8.0.1", + "sp-runtime-interface 21.0.0", + "sp-wasm-interface 18.0.0", + "wasmtime", ] [[package]] name = "sc-informant" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233ece6736217208ffac94f84de2d15465f80f676f881dacd0a9b3411b476951" +checksum = "7189a0b95fe5d79895a107c6c057bc9351cd9c867552200815199cde25bcdb9d" dependencies = [ "ansi_term", "futures", @@ -9505,32 +9478,61 @@ dependencies = [ "sc-network", "sc-network-common", "sp-blockchain", - "sp-runtime", + "sp-runtime 28.0.0", ] [[package]] name = "sc-keystore" -version = "21.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c15cc8b79eb0832cac48fde41e9ecd011df5d57dad7608f2b89fe721e97012c" +checksum = "abecdf9778fccc254c0b5e227ea8b90fd59247044a30ad293a068b180427d244" dependencies = [ - "array-bytes", + "array-bytes 6.2.2", "parking_lot 0.12.1", "serde_json", - "sp-application-crypto", - "sp-core", - "sp-keystore", + "sp-application-crypto 27.0.0", + "sp-core 25.0.0", + "sp-keystore 0.31.0", + "thiserror", +] + +[[package]] +name = "sc-mixnet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53ea71ec60601c18d6adcaf7a62698fc2e886c16dc8fdf8d61b3b76244dea38" +dependencies = [ + "array-bytes 4.2.0", + "arrayvec 0.7.4", + "blake2 0.10.6", + "futures", + "futures-timer", + "libp2p-identity", + "log", + "mixnet", + "multiaddr", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-network", + "sc-transaction-pool-api", + "sp-api", + "sp-consensus", + "sp-core 25.0.0", + "sp-keystore 0.31.0", + "sp-mixnet", + "sp-runtime 28.0.0", "thiserror", ] [[package]] name = "sc-network" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3edad0e7930c2572d6920dc257bc03af6f40ba272bc45602edd0a045d94e5e59" +checksum = "01f519592a971199c486d412dbf38ba54096857080bf4b9d29c9ffabcfee3745" dependencies = [ - "array-bytes", - "async-channel", + "array-bytes 6.2.2", + "async-channel 1.9.0", "async-trait", "asynchronous-codec", "bytes", @@ -9554,10 +9556,10 @@ dependencies = [ "serde", "serde_json", "smallvec", - "sp-arithmetic", + "sp-arithmetic 20.0.0", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", "thiserror", "unsigned-varint", @@ -9567,50 +9569,50 @@ dependencies = [ [[package]] name = "sc-network-bitswap" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a0d247f576989cb2fe49df0511cbbd826f1e47b444848971e2bddec8f18a65" +checksum = "8fe63a55e03d8bc796ff1e94e7fb62a62acfd7a80a47865a97b55c13371c3e05" dependencies = [ - "async-channel", + "async-channel 1.9.0", "cid", "futures", "libp2p-identity", "log", - "prost 0.11.9", - "prost-build 0.11.9", + "prost", + "prost-build", "sc-client-api", "sc-network", "sp-blockchain", - "sp-runtime", + "sp-runtime 28.0.0", "thiserror", "unsigned-varint", ] [[package]] name = "sc-network-common" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418c79cea8ab5b43f5bbe7ee95da7d6490bdfedbe92a9b07a714ca4f09a2426" +checksum = "8d236686d15275e4aa49ca929a06fb6fac28aa70e35ee185b981036c149f9e9d" dependencies = [ "async-trait", "bitflags 1.3.2", "futures", "libp2p-identity", "parity-scale-codec", - "prost-build 0.11.9", + "prost-build", "sc-consensus", "sp-consensus", "sp-consensus-grandpa", - "sp-runtime", + "sp-runtime 28.0.0", ] [[package]] name = "sc-network-gossip" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27a9e8b4e16ab5b67b1fe389349855a2946d3c9168df54afcafec5dd67cae4cd" +checksum = "b884a9f7cd348c4c1899c0bbf95237e39dffba4baec48d4b98c1046f6bb04fa5" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", "futures", "futures-timer", "libp2p", @@ -9618,41 +9620,41 @@ dependencies = [ "sc-network", "sc-network-common", "schnellru", - "sp-runtime", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", "tracing", ] [[package]] name = "sc-network-light" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36fc98d43aa75eb0d0690af6a8c6a929318f6cb4bf1fc039410ece56c8bb5a9" +checksum = "aac888fd720ef8bb2ff7d2b7f7b2e54d17bb85a417cf1e1b6f0f64f7e644936d" dependencies = [ - "array-bytes", - "async-channel", + "array-bytes 6.2.2", + "async-channel 1.9.0", "futures", "libp2p-identity", "log", "parity-scale-codec", - "prost 0.11.9", - "prost-build 0.11.9", + "prost", + "prost-build", "sc-client-api", "sc-network", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "thiserror", ] [[package]] name = "sc-network-sync" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d049b008a7353fc46cb45a1f6f68e5e5128442b6726cfd82da09cb676443e73" +checksum = "10c697aa8f52cf194b9f00113a7d0d3ce5d1456bedd6169a9caae10737f02907" dependencies = [ - "array-bytes", - "async-channel", + "array-bytes 6.2.2", + "async-channel 1.9.0", "async-trait", "fork-tree", "futures", @@ -9661,8 +9663,8 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "prost 0.11.9", - "prost-build 0.11.9", + "prost", + "prost-build", "sc-client-api", "sc-consensus", "sc-network", @@ -9670,23 +9672,24 @@ dependencies = [ "sc-utils", "schnellru", "smallvec", - "sp-arithmetic", + "sp-arithmetic 20.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", "thiserror", + "tokio-stream", ] [[package]] name = "sc-network-transactions" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef6606f7705bc9c038c9e11715b7ddbdb2a5b43c12d8e3cc346e0b9927218e4" +checksum = "bb7c9bfc7b58ce229d1512158b8f13dc849ec24857d1c29a41a867fb8afb5c09" dependencies = [ - "array-bytes", + "array-bytes 6.2.2", "futures", "libp2p", "log", @@ -9695,17 +9698,17 @@ dependencies = [ "sc-network-common", "sc-utils", "sp-consensus", - "sp-runtime", + "sp-runtime 28.0.0", "substrate-prometheus-endpoint", ] [[package]] name = "sc-offchain" -version = "25.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9d2458e033256bca62b01e89369bb9a7d74a460b74a5e3786afc5db3f55b1c" +checksum = "47950facab8dedf71c39667ccce8834252944e8f091f3a3bcdfc0b4503573da4" dependencies = [ - "array-bytes", + "array-bytes 6.2.2", "bytes", "fnv", "futures", @@ -9725,20 +9728,20 @@ dependencies = [ "sc-transaction-pool-api", "sc-utils", "sp-api", - "sp-core", - "sp-externalities", - "sp-keystore", + "sp-core 25.0.0", + "sp-externalities 0.23.0", + "sp-keystore 0.31.0", "sp-offchain", - "sp-runtime", + "sp-runtime 28.0.0", "threadpool", "tracing", ] [[package]] name = "sc-proposer-metrics" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6fc35c74a42a49d4ea4df44f78ebbd5a744f9bdca3f4ea1d3d9e5e02b0e6ee7" +checksum = "221845dce4e7adb57eca5f73318699b377cff29aef92a586e71aa5cef62f879b" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -9746,18 +9749,19 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "25.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede50e654b3e0c076bb9beb041612af80f07dfb883cc05d8aaae1c7a1bb72761" +checksum = "eb277280b6b3519e4a2e693b75d4ca516ebb4a928162e6a1791b217b2be60c9f" dependencies = [ "futures", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "parity-scale-codec", "parking_lot 0.12.1", "sc-block-builder", "sc-chain-spec", "sc-client-api", + "sc-mixnet", "sc-rpc-api", "sc-tracing", "sc-transaction-pool-api", @@ -9765,11 +9769,11 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core", - "sp-keystore", + "sp-core 25.0.0", + "sp-keystore 0.31.0", "sp-offchain", "sp-rpc", - "sp-runtime", + "sp-runtime 28.0.0", "sp-session", "sp-statement-store", "sp-version", @@ -9778,32 +9782,33 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac4149b7427beed423006c78e0b75c0193ac01d6e66ff0dd8a1909747cf593" +checksum = "def499ac717db8442fe18543e52330d5f105027b666df73c0b38e81e9105078b" dependencies = [ - "jsonrpsee", + "jsonrpsee 0.16.3", "parity-scale-codec", "sc-chain-spec", + "sc-mixnet", "sc-transaction-pool-api", "scale-info", "serde", "serde_json", - "sp-core", + "sp-core 25.0.0", "sp-rpc", - "sp-runtime", + "sp-runtime 28.0.0", "sp-version", "thiserror", ] [[package]] name = "sc-rpc-server" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a62b9c5bf359cd4923ce10d294532936aa68d0cd59e890a0414f6434397180b" +checksum = "9e8083e1b026dcf397f8c1122b3fba6cc744c6962996df6a30e0fb75223f7637" dependencies = [ "http", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "serde_json", "substrate-prometheus-endpoint", @@ -9814,15 +9819,15 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e770646ab839fb33dfeb7cbde94d98cdaf78526c70b10aa59ec5810953ff2a5" +checksum = "198ea9287111b4060ce1d70dce99804b99d1a92b5fb23a79d94bf0cb460ca3ce" dependencies = [ - "array-bytes", + "array-bytes 6.2.2", "futures", "futures-util", "hex", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "parity-scale-codec", "parking_lot 0.12.1", @@ -9833,8 +9838,8 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "sp-version", "thiserror", "tokio", @@ -9843,16 +9848,16 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9c7fa14eaf48c44edff226ce9b18dc984c122e9deebbf825a8945be7c046ade" +checksum = "3623ae5bd7b089da9796a3f1edd974c94f34dd4b4b527146662ef409ae9cd38c" dependencies = [ "async-trait", "directories", "exit-future", "futures", "futures-timer", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "parity-scale-codec", "parking_lot 0.12.1", @@ -9886,16 +9891,16 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-externalities", - "sp-keystore", - "sp-runtime", + "sp-core 25.0.0", + "sp-externalities 0.23.0", + "sp-keystore 0.31.0", + "sp-runtime 28.0.0", "sp-session", - "sp-state-machine", - "sp-storage", + "sp-state-machine 0.32.0", + "sp-storage 17.0.0", "sp-transaction-pool", "sp-transaction-storage-proof", - "sp-trie", + "sp-trie 26.0.0", "sp-version", "static_init", "substrate-prometheus-endpoint", @@ -9908,21 +9913,21 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bc9266fdec30b59857e794fc329aa600aaa6ed46799f9df859a7e30c0ec34b" +checksum = "3635fe572adfe796886e18910c8b94f7ce67f9ae3e2c161176e122ddf0baa7e4" dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "sp-core", + "sp-core 25.0.0", ] [[package]] name = "sc-statement-store" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d73800507e32d92f804acfa379dc6b6e91e0a2a25ce853b3848eb8aea019ea98" +checksum = "58635973b3a8ca0a40c885b6bc1a61365e5424bf4312ef86963c799f50cfa15b" dependencies = [ "log", "parity-db", @@ -9931,8 +9936,8 @@ dependencies = [ "sc-keystore", "sp-api", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "sp-statement-store", "substrate-prometheus-endpoint", "tokio", @@ -9940,9 +9945,9 @@ dependencies = [ [[package]] name = "sc-sysinfo" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff97437e564c0e7483d7e32384e3f6571f656728ea03a6e1b07a6325e064a76" +checksum = "60967710b85e650652832df73915b64c315f7b437e53c4635bd26106d6d05c21" dependencies = [ "futures", "libc", @@ -9953,16 +9958,16 @@ dependencies = [ "sc-telemetry", "serde", "serde_json", - "sp-core", - "sp-io", - "sp-std", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-std 12.0.0", ] [[package]] name = "sc-telemetry" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46193a2979c86da75fc43276d222359757ea257b512fe6e4128e7a50b0bb22" +checksum = "28e214e4d46cac02321bc3dc6fd72f019ac10819d1ac8f24f6935a4ae74ef273" dependencies = [ "chrono", "futures", @@ -9980,9 +9985,9 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fcb4398268e83957ebbc84e6290307198e817caa47386135d3de6ba3316203a" +checksum = "83bcd745ea216ba0c0a344cff2c41b12e27846d5fca4b28f56ff77e1d3ff3634" dependencies = [ "ansi_term", "atty", @@ -9998,33 +10003,33 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 25.0.0", "sp-rpc", - "sp-runtime", - "sp-tracing", + "sp-runtime 28.0.0", + "sp-tracing 14.0.0", "thiserror", "tracing", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber 0.2.25", ] [[package]] name = "sc-tracing-proc-macro" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71bd05d3f24c0c2489c57b90a76db883c23c25577718ca05c9b0181fd427f501" +checksum = "9c4ae9e4f957d7274ac6b59d667b66262caf6482dbb1b63f1c370528626b1272" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "sc-transaction-pool" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6af477c0e8a2698aabf442a3918313e8f096eb6695ceaaa7e12679c496d2826" +checksum = "6f6db45a057a619670e07deefb4e69aab83386f076363db424907da2b2e82590" dependencies = [ "async-trait", "futures", @@ -10039,9 +10044,9 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", - "sp-runtime", - "sp-tracing", + "sp-core 25.0.0", + "sp-runtime 28.0.0", + "sp-tracing 14.0.0", "sp-transaction-pool", "substrate-prometheus-endpoint", "thiserror", @@ -10049,9 +10054,9 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f1b864d0ae8f1891eb310672c12fc160d24e37ef297d5ef0db257558fe13b1" +checksum = "1491607f296bb8cce09a5eb3a03320c60ad52bb8120127b26f69c32bcaccd8f2" dependencies = [ "async-trait", "futures", @@ -10059,25 +10064,92 @@ dependencies = [ "parity-scale-codec", "serde", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "thiserror", ] [[package]] name = "sc-utils" -version = "10.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b01c8eed623f999d402e44679d42ad42586afd4638aaed38708a307b59f4d7" +checksum = "81a4769c82dde62b9243dcc166be52e0c5d2d61cf2599923271118d9c8b997b1" dependencies = [ - "async-channel", + "async-channel 1.9.0", "futures", "futures-timer", "lazy_static", "log", "parking_lot 0.12.1", "prometheus", - "sp-arithmetic", + "sp-arithmetic 20.0.0", +] + +[[package]] +name = "scale-bits" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "036575c29af9b6e4866ffb7fa055dbf623fe7a9cc159b33786de6013a6969d89" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "scale-decode" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7789f5728e4e954aaa20cadcc370b99096fb8645fca3c9333ace44bb18f30095" +dependencies = [ + "derive_more", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode-derive", + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-decode-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27873eb6005868f8cc72dcfe109fae664cf51223d35387bc2f28be4c28d94c47" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scale-encode" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d70cb4b29360105483fac1ed567ff95d65224a14dd275b6303ed0a654c78de5" +dependencies = [ + "derive_more", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-encode-derive", + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-encode-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995491f110efdc6bea96d6a746140e32bfceb4ea47510750a5467295a4707a25" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -10100,19 +10172,39 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "scale-value" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6538d1cc1af9c0baf401c57da8a6d4730ef582db0d330d2efa56ec946b5b0283" +dependencies = [ + "base58", + "blake2 0.10.6", + "derive_more", + "either", + "frame-metadata 15.1.0", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "serde", + "yap", +] + [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -10130,7 +10222,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", "cfg-if", "hashbrown 0.13.2", ] @@ -10145,11 +10237,27 @@ dependencies = [ "arrayvec 0.5.2", "curve25519-dalek 2.1.3", "getrandom 0.1.16", - "merlin", + "merlin 2.0.1", "rand 0.7.3", "rand_core 0.5.1", "sha2 0.8.2", - "subtle", + "subtle 2.5.0", + "zeroize", +] + +[[package]] +name = "schnorrkel" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "844b7645371e6ecdf61ff246ba1958c29e802881a749ae3fb1993675d210d28d" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "curve25519-dalek-ng", + "merlin 3.0.0", + "rand_core 0.6.4", + "sha2 0.9.9", + "subtle-ng", "zeroize", ] @@ -10165,38 +10273,16 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.5", + "ring 0.17.8", "untrusted 0.9.0", ] -[[package]] -name = "sdp" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d22a5ef407871893fd72b4562ee15e4742269b173959db4b8df6f538c414e13" -dependencies = [ - "rand 0.8.5", - "substring", - "thiserror", - "url", -] - [[package]] name = "sec1" version = "0.3.0" @@ -10208,7 +10294,7 @@ dependencies = [ "generic-array 0.14.7", "pkcs8 0.9.0", "serdect", - "subtle", + "subtle 2.5.0", "zeroize", ] @@ -10222,7 +10308,7 @@ dependencies = [ "der 0.7.8", "generic-array 0.14.7", "pkcs8 0.10.2", - "subtle", + "subtle 2.5.0", "zeroize", ] @@ -10232,16 +10318,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ - "secp256k1-sys 0.6.1", -] - -[[package]] -name = "secp256k1" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" -dependencies = [ - "secp256k1-sys 0.8.1", + "secp256k1-sys", ] [[package]] @@ -10253,15 +10330,6 @@ dependencies = [ "cc", ] -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - [[package]] name = "secrecy" version = "0.8.0" @@ -10273,9 +10341,9 @@ dependencies = [ [[package]] name = "secret-vault" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45237d12adcb273fde95370c7f44bd993ffbc27e34c5d29b9cc5c12abd246f0f" +checksum = "4eeb0a50bc7c162000526b7fb02fc35fafc3675a637df5fd76d7db47e4da3201" dependencies = [ "async-trait", "cargo-husky", @@ -10333,9 +10401,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] @@ -10348,29 +10416,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -10379,9 +10447,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" dependencies = [ "itoa", "serde", @@ -10389,9 +10457,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -10432,11 +10500,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.27" +version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.2.3", "itoa", "ryu", "serde", @@ -10543,9 +10611,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" @@ -10568,9 +10636,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -10591,9 +10659,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597" +checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" [[package]] name = "siphasher" @@ -10603,9 +10671,9 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "sketches-ddsketch" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a406c1882ed7f29cd5e248c9848a80e7cb6ae0fea82346d2746f2f941c07e1" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" [[package]] name = "slab" @@ -10633,31 +10701,129 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] -name = "snap" -version = "1.1.0" +name = "smol" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" - +checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +dependencies = [ + "async-channel 1.9.0", + "async-executor", + "async-fs", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-net", + "async-process", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "smoldot" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cce5e2881b30bad7ef89f383a816ad0b22c45915911f28499026de4a76d20ee" +dependencies = [ + "arrayvec 0.7.4", + "async-lock 2.8.0", + "atomic", + "base64 0.21.7", + "bip39", + "blake2-rfc", + "bs58 0.5.0", + "crossbeam-queue", + "derive_more", + "ed25519-zebra", + "either", + "event-listener 2.5.3", + "fnv", + "futures-channel", + "futures-util", + "hashbrown 0.14.3", + "hex", + "hmac 0.12.1", + "itertools", + "libsecp256k1", + "merlin 3.0.0", + "no-std-net 0.6.0", + "nom", + "num-bigint", + "num-rational", + "num-traits", + "pbkdf2 0.12.2", + "pin-project", + "rand 0.8.5", + "rand_chacha 0.3.1", + "ruzstd", + "schnorrkel 0.10.2", + "serde", + "serde_json", + "sha2 0.10.8", + "siphasher", + "slab", + "smallvec", + "smol", + "snow", + "soketto", + "tiny-keccak", + "twox-hash", + "wasmi", +] + +[[package]] +name = "smoldot-light" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2f7b4687b83ff244ef6137735ed5716ad37dcdf3ee16c4eb1a32fb9808fa47" +dependencies = [ + "async-lock 2.8.0", + "blake2-rfc", + "derive_more", + "either", + "event-listener 2.5.3", + "fnv", + "futures-channel", + "futures-util", + "hashbrown 0.14.3", + "hex", + "itertools", + "log", + "lru", + "parking_lot 0.12.1", + "rand 0.8.5", + "serde", + "serde_json", + "siphasher", + "slab", + "smol", + "smoldot", +] + +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + [[package]] name = "snow" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155" +checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" dependencies = [ - "aes-gcm 0.9.4", - "blake2", + "aes-gcm", + "blake2 0.10.6", "chacha20poly1305", - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "rand_core 0.6.4", - "ring 0.16.20", + "ring 0.17.8", "rustc_version", "sha2 0.10.8", - "subtle", + "subtle 2.5.0", ] [[package]] @@ -10699,87 +10865,116 @@ dependencies = [ [[package]] name = "sp-api" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc5213210472ba2becdc094fbb9d30c4455753b1a608962797e1e971c3e5ec4" +checksum = "f582f92ce47c86e4ffffe81fdd5120fea7c850dc0800653a7fa203bcc1532335" dependencies = [ "hash-db", "log", "parity-scale-codec", "scale-info", "sp-api-proc-macro", - "sp-core", - "sp-externalities", + "sp-core 25.0.0", + "sp-externalities 0.23.0", "sp-metadata-ir", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", + "sp-std 12.0.0", + "sp-trie 26.0.0", "sp-version", "thiserror", ] [[package]] name = "sp-api-proc-macro" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e7f093302d30b9d35436db024376459bdc9da7530abcacf5d87c32a67d94fd" +checksum = "a896941b2d27365a6f937ebce11e36d55132dc32104f6a48b4cd765b55efd252" dependencies = [ "Inflector", - "blake2", + "blake2 0.10.6", "expander", - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "sp-application-crypto" -version = "26.0.0" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899492ea547816d5dfe9a5a2ecc32f65a7110805af6da3380aa4902371b31dc2" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-application-crypto" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74454c936a45ac55c8de95b9fd8b5e38f8b43d97df8f4274dd6777b20d95569" +checksum = "a93da025616ab59639f8e378df579c5aaa2c8b9999f328a0239156a57c991b53" dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-std", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-arithmetic" -version = "19.0.0" +version = "16.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e41f710a77e9debd1c9b80f862709dce648e50f0904cde4117488e7d11d4796d" +checksum = "bb6020576e544c6824a51d651bc8df8e6ab67cd59f1c9ac09868bb81a5199ded" dependencies = [ "integer-sqrt", "num-traits", "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 8.0.0", + "static_assertions", +] + +[[package]] +name = "sp-arithmetic" +version = "20.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f80b5c16afb61dde1037a469d570adcc686440036429e50abe2301ba9d61aad5" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-std 12.0.0", "static_assertions", ] [[package]] name = "sp-block-builder" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6a066e310d4c0c240829d7bb5d6bd01dde55d03e15b665f0372b40952f37e6" +checksum = "6cd16df3d1cdad862d3e764f10f7675876b011e032907423fdfa377ae2ec8575" dependencies = [ "sp-api", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-blockchain" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f506119858f25a73ed9d61a2ead0d5b97b5141055b3b4a12b9b82e530b06c673" +checksum = "4932b97cde61874f395bab9b02443e3bd2046943abb280b63f83da9d0b623ea7" dependencies = [ "futures", "log", @@ -10789,70 +10984,70 @@ dependencies = [ "sp-api", "sp-consensus", "sp-database", - "sp-runtime", - "sp-state-machine", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", "thiserror", ] [[package]] name = "sp-consensus" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e142e27f140d50701e613d925f61482fafccb7d90933ee30d7bae54d293ea3" +checksum = "2c5d7170fb7cfb18024ef7eeb40d272d22b9c3587d85cde2d091e8463b397f06" dependencies = [ "async-trait", "futures", "log", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", "thiserror", ] [[package]] name = "sp-consensus-aura" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dcc6df7a006a55651d0e7bdf2d8d4583d5b917cb4b7b6a1331398e96307a883" +checksum = "643a7c486a645f398d219d1fbcc8a416cad5018164a212fefde5c2ef00a182e4" dependencies = [ "async-trait", "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto", + "sp-application-crypto 27.0.0", "sp-consensus-slots", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "sp-timestamp", ] [[package]] name = "sp-consensus-babe" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572374a1260687fa18481ccac58c4a64611df379fb1aa65389ce96c6661b3b05" +checksum = "268f9b2e36d4e136c09ad87876cdcfd7ff734cb5917f333fefebff248f95a24f" dependencies = [ "async-trait", "parity-scale-codec", "scale-info", "serde", "sp-api", - "sp-application-crypto", + "sp-application-crypto 27.0.0", "sp-consensus-slots", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "sp-timestamp", ] [[package]] name = "sp-consensus-grandpa" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d20516ed05a6a17f712050d6be385ca53c16b2d49938a29ca05e07f7aa5118" +checksum = "28bbee685900110419913f281ce0f29457fbc17418f00d15f0212c8043aba167" dependencies = [ "finality-grandpa", "log", @@ -10860,35 +11055,80 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-core", - "sp-keystore", - "sp-runtime", - "sp-std", + "sp-application-crypto 27.0.0", + "sp-core 25.0.0", + "sp-keystore 0.31.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-consensus-slots" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ebe1c46246a76af1105639c7434c1383d376fd45a8548fc18ed66dbf86f803c" +checksum = "895b0c176d4eead833ddee5251d3cccbaeb0191ca3f33f84b11d347bebc6e21f" dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 12.0.0", "sp-timestamp", ] [[package]] name = "sp-core" -version = "24.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7921d278ed2aebbb21a644c96e09663dc49a6139d1e2e063c059dc9f866e149b" +checksum = "f18d9e2f67d8661f9729f35347069ac29d92758b59135176799db966947a7336" dependencies = [ - "array-bytes", + "array-bytes 4.2.0", "bitflags 1.3.2", - "blake2", + "blake2 0.10.6", + "bounded-collections", + "bs58 0.4.0", + "dyn-clonable", + "ed25519-zebra", + "futures", + "hash-db", + "hash256-std-hasher", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin 2.0.1", + "parity-scale-codec", + "parking_lot 0.12.1", + "paste", + "primitive-types", + "rand 0.8.5", + "regex", + "scale-info", + "schnorrkel 0.9.1", + "secp256k1", + "secrecy", + "serde", + "sp-core-hashing 9.0.0", + "sp-debug-derive 8.0.0", + "sp-externalities 0.19.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "ss58-registry", + "substrate-bip39", + "thiserror", + "tiny-bip39", + "zeroize", +] + +[[package]] +name = "sp-core" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9ebb090ead698a6df04347c86a31ba91a387edb8a58534ec70c4f977d1e1e87" +dependencies = [ + "array-bytes 6.2.2", + "bitflags 1.3.2", + "blake2 0.10.6", "bounded-collections", "bs58 0.5.0", "dyn-clonable", @@ -10900,7 +11140,7 @@ dependencies = [ "lazy_static", "libsecp256k1", "log", - "merlin", + "merlin 2.0.1", "parity-scale-codec", "parking_lot 0.12.1", "paste", @@ -10908,29 +11148,59 @@ dependencies = [ "rand 0.8.5", "regex", "scale-info", - "schnorrkel", - "secp256k1 0.24.3", + "schnorrkel 0.9.1", + "secp256k1", "secrecy", "serde", - "sp-core-hashing", - "sp-debug-derive", - "sp-externalities", - "sp-runtime-interface", - "sp-std", - "sp-storage", + "sp-core-hashing 13.0.0", + "sp-debug-derive 12.0.0", + "sp-externalities 0.23.0", + "sp-runtime-interface 21.0.0", + "sp-std 12.0.0", + "sp-storage 17.0.0", "ss58-registry", "substrate-bip39", "thiserror", "tiny-bip39", "tracing", + "w3f-bls", "zeroize", ] [[package]] name = "sp-core-hashing" -version = "12.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cb5c31aa385d6997a5b73fdc9837c1c0145559205198555c3000739a474767" +checksum = "2ee599a8399448e65197f9a6cee338ad192e9023e35e31f22382964c3c174c68" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.8", + "sha3", + "sp-std 8.0.0", + "twox-hash", +] + +[[package]] +name = "sp-core-hashing" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb8524f01591ee58b46cd83c9dbc0fcffd2fd730dabec4f59326cd58a00f17e2" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.8", + "sha3", + "twox-hash", +] + +[[package]] +name = "sp-core-hashing" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1936171e56a51272757760cc50883d2a8c37c650b3602a0aeed05b0c4fffc5f1" dependencies = [ "blake2b_simd", "byteorder", @@ -10942,20 +11212,20 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" -version = "12.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4327a220777a8d492ed3d0bcd4c769cbb030301e7d4a2d9e09513d690c313b" +checksum = "42ce3e6931303769197da81facefa86159fa1085dcd96ecb7e7407b5b93582a0" dependencies = [ "quote", - "sp-core-hashing", - "syn 2.0.38", + "sp-core-hashing 13.0.0", + "syn 2.0.49", ] [[package]] name = "sp-database" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab25f79468af89010a8eb84e6bf56068b59929a55291c03519f47208360f3ebe" +checksum = "9c6e8c710d6a71512af6f42d9dba9c3d1f6ad793846480babf459bbde3d60a94" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -10963,109 +11233,173 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "11.0.0" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f531814d2f16995144c74428830ccf7d94ff4a7749632b83ad8199b181140c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.49", +] + +[[package]] +name = "sp-debug-derive" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f7d375610590566e11882bf5b5a4b8d0666a96ba86808b2650bbbd9be50bf8" +checksum = "50535e1a5708d3ba5c1195b59ebefac61cc8679c2c24716b87a86e8b7ed2e4a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "sp-externalities" -version = "0.22.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede074871514ca7c5d2eca9563515d858c6220b47ae815714ed4393a4e99db4a" +checksum = "a0f71c671e01a8ca60da925d43a1b351b69626e268b8837f8371e320cf1dd100" dependencies = [ "environmental", "parity-scale-codec", - "sp-std", - "sp-storage", + "sp-std 8.0.0", + "sp-storage 13.0.0", +] + +[[package]] +name = "sp-externalities" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884d05160bc89d0943d1c9fb8006c3d44b80f37f8af607aeff8d4d9cc82e279a" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std 12.0.0", + "sp-storage 17.0.0", ] [[package]] name = "sp-genesis-builder" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b9f0251a09b578393f3297abe54a29abdb7e93c17e89a88dc1cabb8e2d5a2d" +checksum = "a0cb71d40ad47e40bdcce5ae5531c7d7ba579cd495a0e0413642fb063fa66f84" dependencies = [ "serde_json", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-inherents" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439882da80e9bcfd1ba53df7ec5070d4d7f2a9a93f988aa3598f99ee5bfc76eb" +checksum = "604229aa145be0cff853b47ffed8bc2c62eb08ec6974d6307b9a559c378e6dc5" dependencies = [ "async-trait", "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "thiserror", ] [[package]] name = "sp-io" -version = "26.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88fb6e281de5054565f07a9f79504d21133e115db549993c99f1b21236c677a5" +checksum = "9d597e35a9628fe7454b08965b2442e3ec0f264b0a90d41328e87422cec02e99" dependencies = [ "bytes", - "ed25519-dalek", + "ed25519 1.5.3", + "ed25519-dalek 1.0.1", + "futures", "libsecp256k1", "log", "parity-scale-codec", "rustversion", - "secp256k1 0.24.3", - "sp-core", - "sp-externalities", - "sp-keystore", - "sp-runtime-interface", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-trie", + "secp256k1", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-keystore 0.27.0", + "sp-runtime-interface 17.0.0", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", "tracing", "tracing-core", ] [[package]] -name = "sp-keyring" +name = "sp-io" version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f09927534d2233e135e4b4a0c758554d0ff66178f6e9cfba2e151dfeac97b3" +checksum = "0ced350da15e8ba3a106206840acc42a6d3eb0d7e8bf7aa43ab00eac0bdf956f" +dependencies = [ + "bytes", + "ed25519-dalek 2.1.1", + "libsecp256k1", + "log", + "parity-scale-codec", + "rustversion", + "secp256k1", + "sp-core 25.0.0", + "sp-externalities 0.23.0", + "sp-keystore 0.31.0", + "sp-runtime-interface 21.0.0", + "sp-state-machine 0.32.0", + "sp-std 12.0.0", + "sp-tracing 14.0.0", + "sp-trie 26.0.0", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-keyring" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655ec0b35cb9cb9029fb323aa676b07d58deb872cecc7566e50278409a00ee95" dependencies = [ "lazy_static", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", "strum 0.24.1", ] [[package]] name = "sp-keystore" -version = "0.30.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9f19e773319d96223ce8dba960267e6cb977907537a8f738746ceb86592413" +checksum = "9be3cdd67cc1d9c1db17c5cbc4ec4924054a8437009d167f21f6590797e4aa45" dependencies = [ + "futures", "parity-scale-codec", "parking_lot 0.12.1", - "sp-core", - "sp-externalities", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "thiserror", +] + +[[package]] +name = "sp-keystore" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8ec5ebbba70bee83d79c3fe5e49f12df0a4bb6029858ddf9a15eea7539a592" +dependencies = [ + "parity-scale-codec", + "parking_lot 0.12.1", + "sp-core 25.0.0", + "sp-externalities 0.23.0", "thiserror", ] [[package]] name = "sp-maybe-compressed-blob" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377a0e22a104a1a83804562fba6702537af6a36df9ee2049c89c3be9148b42b1" +checksum = "8846768f036429227e49f6ab523fbee4bc6edfee278a361bf27999590fe020d4" dependencies = [ "thiserror", "zstd 0.12.4", @@ -11073,32 +11407,56 @@ dependencies = [ [[package]] name = "sp-metadata-ir" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb0dec8af38c68358600da59cf14424e1230fe9ae1d4b4f64a098288145c0775" +checksum = "7ca9ff0e522a74725ac92f009d38deeb12e880f5296afbd78a6c6b970b773278" dependencies = [ - "frame-metadata", + "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", - "sp-std", + "sp-std 12.0.0", +] + +[[package]] +name = "sp-mixnet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf61f28ca97aab6c21a3c6e0ed496e60d505e5de1f43fd4ba748c9afaa4fc85" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-application-crypto 27.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-offchain" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b1501eb4ede6471162ff48c85ccabb21434b698c8b61e2651f85c00bc1656f" +checksum = "9310227f043ed99877b0449a683025a7461431a00995dcd6ef423a273d0fd85d" dependencies = [ "sp-api", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", ] [[package]] name = "sp-panic-handler" -version = "11.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd099ba2d6c1bfe5d0c79aa56e440fa3c9257eadfc0c782c09cdc2122b1e60ed" +checksum = "ebd2de46003fa8212426838ca71cd42ee36a26480ba9ffea983506ce03131033" +dependencies = [ + "backtrace", + "lazy_static", + "regex", +] + +[[package]] +name = "sp-panic-handler" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00e40857ed3e0187f145b037c733545c5633859f1bd1d1b09deb52805fa696a" dependencies = [ "backtrace", "lazy_static", @@ -11107,20 +11465,43 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8534ae0a6043f70a93054bf0d3da27436637a8134ed44667c360e7a955cb3d" +checksum = "51867fea921f54bbaa2bf505f373559b5f3b80e8d7f38ecb9677f0d3795a3e6a" dependencies = [ "rustc-hash", "serde", - "sp-core", + "sp-core 25.0.0", ] [[package]] name = "sp-runtime" -version = "27.0.0" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21c5bfc764a1a8259d7e8f7cfd22c84006275a512c958d3ff966c92151e134d5" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "paste", + "rand 0.8.5", + "scale-info", + "serde", + "sp-application-crypto 23.0.0", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-std 8.0.0", + "sp-weights 20.0.0", +] + +[[package]] +name = "sp-runtime" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c0641e1a9d340960b562bcceea1457680fd0e109fc1040f8f5364fd7bc2506" +checksum = "6d9c40ff7303e62219b55635e5245d963358cb77d6916250991ebcb82c0be2c6" dependencies = [ "either", "hash256-std-hasher", @@ -11131,82 +11512,135 @@ dependencies = [ "rand 0.8.5", "scale-info", "serde", - "sp-application-crypto", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-std", - "sp-weights", + "sp-application-crypto 27.0.0", + "sp-arithmetic 20.0.0", + "sp-core 25.0.0", + "sp-io 27.0.0", + "sp-std 12.0.0", + "sp-weights 24.0.0", ] [[package]] name = "sp-runtime-interface" -version = "20.0.0" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e676128182f90015e916f806cba635c8141e341e7abbc45d25525472e1bbce8" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities 0.19.0", + "sp-runtime-interface-proc-macro 11.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "sp-tracing 10.0.0", + "sp-wasm-interface 14.0.0", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17a4030ad93f05c93f2cc294c74bc5fea227f90fb3d1426d4a6f165e017fb7ea" +checksum = "4f365332922a8cfa98ab00c6d08b1b0f24e159e730dd554e720d950ff3371b1f" dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec", "primitive-types", - "sp-externalities", - "sp-runtime-interface-proc-macro", - "sp-std", - "sp-storage", - "sp-tracing", - "sp-wasm-interface", + "sp-externalities 0.23.0", + "sp-runtime-interface-proc-macro 15.0.0", + "sp-std 12.0.0", + "sp-storage 17.0.0", + "sp-tracing 14.0.0", + "sp-wasm-interface 18.0.0", "static_assertions", ] [[package]] name = "sp-runtime-interface-proc-macro" -version = "14.0.0" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d5bd5566fe5633ec48dfa35ab152fd29f8a577c21971e1c6db9f28afb9bbb9" +dependencies = [ + "Inflector", + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn 2.0.49", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b232943ee7ca83a6d56face33b8af12e9fb470a15a53835f4e12a6e452a41c1c" +checksum = "9b2afcbd1bd18d323371111b66b7ac2870bdc1c86c3d7b0dae67b112ca52b4d8" dependencies = [ "Inflector", - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "sp-session" -version = "23.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd062688577cc54493ba6f58383bfed89c66d5ef7b7c3747293b0da06c7f795" +checksum = "248dd8f49aa96b56bf0a7d513691ddb4194f9359fdb93e94397eabdef1036085" dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core", - "sp-keystore", - "sp-runtime", + "sp-core 25.0.0", + "sp-keystore 0.31.0", + "sp-runtime 28.0.0", "sp-staking", - "sp-std", + "sp-std 12.0.0", ] [[package]] name = "sp-staking" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3b2a4a7aa67a9adb2a8f49ed516f6694b5fa70792ab9b0125934b1c8cdc2e3" +checksum = "ee0feed0137234598bd1f76d0b468c585ea16619ea9ed1acbba82dd24ac79788" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 25.0.0", + "sp-runtime 28.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-state-machine" -version = "0.31.0" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef45d31f9e7ac648f8899a0cd038a3608f8499028bff55b6c799702592325b6" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "smallvec", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-panic-handler 8.0.0", + "sp-std 8.0.0", + "sp-trie 22.0.0", + "thiserror", + "tracing", +] + +[[package]] +name = "sp-state-machine" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf4c76bea1a9e4a2e79afe70f42f1d368a8a45308e58f19bfd755c5ddb2b4a3" +checksum = "96e087fa4430befd2047b61d912c9d6fa4eaed408c4b58b46c6e9acd7965f2d3" dependencies = [ "hash-db", "log", @@ -11214,83 +11648,122 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "smallvec", - "sp-core", - "sp-externalities", - "sp-panic-handler", - "sp-std", - "sp-trie", + "sp-core 25.0.0", + "sp-externalities 0.23.0", + "sp-panic-handler 12.0.0", + "sp-std 12.0.0", + "sp-trie 26.0.0", "thiserror", "tracing", - "trie-db", + "trie-db 0.28.0", ] [[package]] name = "sp-statement-store" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a11bbdc403457dd7a850078936aa7cc753c617b7bbeba5f5766ce5a55b2bf124" +checksum = "4b8654bcd37602b1811414050d34d14f543873bd4e64e50d210a0116b660c600" dependencies = [ - "aes-gcm 0.10.3", - "curve25519-dalek 4.1.1", - "ed25519-dalek", + "aes-gcm", + "curve25519-dalek 4.1.2", + "ed25519-dalek 2.1.1", "hkdf", "parity-scale-codec", "rand 0.8.5", "scale-info", "sha2 0.10.8", "sp-api", - "sp-application-crypto", - "sp-core", - "sp-externalities", - "sp-runtime", - "sp-runtime-interface", - "sp-std", + "sp-application-crypto 27.0.0", + "sp-core 25.0.0", + "sp-externalities 0.23.0", + "sp-runtime 28.0.0", + "sp-runtime-interface 21.0.0", + "sp-std 12.0.0", "thiserror", - "x25519-dalek 2.0.0", + "x25519-dalek 2.0.1", ] +[[package]] +name = "sp-std" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53458e3c57df53698b3401ec0934bea8e8cfce034816873c0b0abbd83d7bac0d" + [[package]] name = "sp-std" version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c91d32e165d08a14098ce5ec923eaec59d1d0583758a18a770beec1b780b0d0" +[[package]] +name = "sp-std" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c78c5a66682568cc7b153603c5d01a2cc8f5c221c7b1e921517a0eef18ae05" + [[package]] name = "sp-storage" -version = "16.0.0" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94294be83f11d4958cfea89ed5798f0b6605f5defc3a996948848458abbcc18e" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive 8.0.0", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-storage" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9660ecd48314443e73ad0f44d58b76426666a1343d72f6f65664e174da9244" +checksum = "016f20812cc51bd479cc88d048c35d44cd3adde4accdb159d49d6050f2953595" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive", - "sp-std", + "sp-debug-derive 12.0.0", + "sp-std 12.0.0", ] [[package]] name = "sp-timestamp" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0ab4b6b2d31db93e7da68894ccb7c5a305524cea051109820b958361d162be" +checksum = "004a7f453240db80b2967c0e1c6411836efc7daa7afae98fd16202caa51460e0" dependencies = [ "async-trait", "parity-scale-codec", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "thiserror", ] [[package]] name = "sp-tracing" -version = "13.0.0" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357f7591980dd58305956d32f8f6646d0a8ea9ea0e7e868e46f53b68ddf00cec" +dependencies = [ + "parity-scale-codec", + "sp-std 8.0.0", + "tracing", + "tracing-core", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "sp-tracing" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a61948986d2a9f8d67d60884ff0277d910df09ebe08d0e1f309da777516453" +checksum = "0d727cb5265641ffbb7d4e42c18b63e29f6cfdbd240aae3bcf093c3d6eb29a19" dependencies = [ "parity-scale-codec", - "sp-std", + "sp-std 12.0.0", "tracing", "tracing-core", "tracing-subscriber 0.2.25", @@ -11298,37 +11771,61 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ea9c85f85f52e0a49c3f2ec6cff952fdc3ffe8392bebe21ed30eddd8d059c5" +checksum = "c7cd2afe89c474339d15d06e73639171ebe4d280be6904d9349072103da21427" dependencies = [ "sp-api", - "sp-runtime", + "sp-runtime 28.0.0", ] [[package]] name = "sp-transaction-storage-proof" -version = "22.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a2d2d676a4c8e9ff18cb43782ed557d00de28ee9fb090842a8510e4a7ce0a7" +checksum = "39ae7c4954431b8479f7b2b6b82f0551cc360a1ee59b6a5276eef86a1099eaed" dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-core", + "sp-core 25.0.0", "sp-inherents", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-runtime 28.0.0", + "sp-std 12.0.0", + "sp-trie 26.0.0", ] [[package]] name = "sp-trie" -version = "25.0.0" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4eeb7ef23f79eba8609db79ef9cef242f994f1f87a3c0387b4b5f177fda74" +dependencies = [ + "ahash 0.8.8", + "hash-db", + "hashbrown 0.13.2", + "lazy_static", + "memory-db", + "nohash-hasher", + "parity-scale-codec", + "parking_lot 0.12.1", + "scale-info", + "schnellru", + "sp-core 21.0.0", + "sp-std 8.0.0", + "thiserror", + "tracing", + "trie-db 0.27.1", + "trie-root", +] + +[[package]] +name = "sp-trie" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb2d292eb90452dcb0909fb44e74bf04395e3ffa37a66c0f1635a00600382a4" +checksum = "1e359b358263cc322c3f678c272a3a519621d9853dcfa1374dfcbdb5f54c6f85" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", "hash-db", "hashbrown 0.13.2", "lazy_static", @@ -11336,21 +11833,22 @@ dependencies = [ "nohash-hasher", "parity-scale-codec", "parking_lot 0.12.1", + "rand 0.8.5", "scale-info", "schnellru", - "sp-core", - "sp-std", + "sp-core 25.0.0", + "sp-std 12.0.0", "thiserror", "tracing", - "trie-db", + "trie-db 0.28.0", "trie-root", ] [[package]] name = "sp-version" -version = "25.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125da59ea46ecb23860e7d895f6f2882f596b71ffca0ae4887558aac541f4342" +checksum = "3e93da332eba3cb59a65f128da5edd5c70e1475692b45470104e7465b1278471" dependencies = [ "impl-serde", "parity-scale-codec", @@ -11358,52 +11856,82 @@ dependencies = [ "scale-info", "serde", "sp-core-hashing-proc-macro", - "sp-runtime", - "sp-std", + "sp-runtime 28.0.0", + "sp-std 12.0.0", "sp-version-proc-macro", "thiserror", ] [[package]] name = "sp-version-proc-macro" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92897ffa04436cbd100c49ea1f8b637cb68e2a9fe144115f4b545b5ace2f47e2" +checksum = "49535d8c7184dab46d15639c68374a30cbb1534e392fa09a1ebb059a993ad436" dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "sp-wasm-interface" -version = "17.0.0" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19c122609ca5d8246be6386888596320d03c7bc880959eaa2c36bcd5acd6846" +dependencies = [ + "anyhow", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "sp-std 8.0.0", + "wasmtime", +] + +[[package]] +name = "sp-wasm-interface" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf43bb0c8eb76dc41057ce0fb6b744b94c9aec28b31dff53a1efc4f04ef25384" +checksum = "d5d85813d46a22484cdf5e5afddbbe85442dd1b4d84d67a8c7792f92f9f93607" dependencies = [ "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std", - "wasmtime 8.0.1", + "sp-std 12.0.0", + "wasmtime", ] [[package]] name = "sp-weights" -version = "23.0.0" +version = "20.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d084c735544f70625b821c3acdbc7a2fc1893ca98b85f1942631284692c75b" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "smallvec", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-debug-derive 8.0.0", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-weights" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1cef0aad13ed8a8522a6e86ace16fb97ab220c16d2357e628352b528582693" +checksum = "751676c1263e7f3600af16bad26a7978a816bc532676fe05eafa23b862c05b9e" dependencies = [ "parity-scale-codec", "scale-info", "serde", "smallvec", - "sp-arithmetic", - "sp-core", - "sp-debug-derive", - "sp-std", + "sp-arithmetic 20.0.0", + "sp-core 25.0.0", + "sp-debug-derive 12.0.0", + "sp-std 12.0.0", ] [[package]] @@ -11420,9 +11948,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spinners" -version = "4.1.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08615eea740067d9899969bc2891c68a19c315cb1f66640af9a9ecb91b13bcab" +checksum = "a0ef947f358b9c238923f764c72a4a9d42f2d637c46e059dbd319d6e7cfb4f82" dependencies = [ "lazy_static", "maplit", @@ -11441,25 +11969,19 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der 0.7.8", ] -[[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - [[package]] name = "ss58-registry" -version = "1.43.0" +version = "1.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6915280e2d0db8911e5032a5c275571af6bdded2916abd691a659be25d3439" +checksum = "b1114ee5900b8569bbc8b1a014a942f937b752af4b44f4607430b5f86cedaac0" dependencies = [ "Inflector", "num-format", @@ -11525,6 +12047,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "strum" version = "0.24.1" @@ -11563,26 +12091,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", -] - -[[package]] -name = "stun" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" -dependencies = [ - "base64 0.13.1", - "crc", - "lazy_static", - "md-5", - "rand 0.8.5", - "ring 0.16.20", - "subtle", - "thiserror", - "tokio", - "url", - "webrtc-util", + "syn 2.0.49", ] [[package]] @@ -11593,26 +12102,26 @@ checksum = "e620c7098893ba667438b47169c00aacdd9e7c10e042250ce2b60b087ec97328" dependencies = [ "hmac 0.11.0", "pbkdf2 0.8.0", - "schnorrkel", + "schnorrkel 0.9.1", "sha2 0.9.9", "zeroize", ] [[package]] name = "substrate-build-script-utils" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78127cdb5849eed7399ff9c730faea57c2a4e148e3b46e565abe98248432feb9" +checksum = "8a3b7556a62d77b7b8abc34e425817f6f563c2f2aa7142f1c4e93e6422156cc1" [[package]] name = "substrate-frame-rpc-system" -version = "24.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5978d5bc95506e7770fe7de97610db13ee72dd1e242894d4843587dc5954102" +checksum = "4c241af714c378075b1185e574202cbb9105e849b8c9ea44ef87880bdb3e9a75" dependencies = [ "frame-system-rpc-runtime-api", "futures", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "parity-scale-codec", "sc-rpc-api", @@ -11620,15 +12129,15 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 25.0.0", + "sp-runtime 28.0.0", ] [[package]] name = "substrate-prometheus-endpoint" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e99fe4e955b8d7c25bd3a88a6907933867d11ef6194ef935e865a9e87c320ff" +checksum = "ededbe617291db8a47d6e5155486ff1e5425f0bbf5dcb7f752730466a62bd293" dependencies = [ "hyper", "log", @@ -11639,23 +12148,23 @@ dependencies = [ [[package]] name = "substrate-rpc-client" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624257055386482adba21684a4af2cebdbaf0a8dd0e1b7cd9eec05b564afa5db" +checksum = "5575c2bef89385e5406565b8fe5620856d414e3846c60927a78f0788cb288c8c" dependencies = [ "async-trait", - "jsonrpsee", + "jsonrpsee 0.16.3", "log", "sc-rpc-api", "serde", - "sp-runtime", + "sp-runtime 28.0.0", ] [[package]] name = "substrate-wasm-builder" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a23975404eca6d81818f3f3d4ecde9635dae3e616f366dbc1a0d510c86f02a2" +checksum = "12ab1707dbbd129622b771a9b80b25f0ebf1c04854b907bc44b51ec96fb4005b" dependencies = [ "ansi_term", "build-helper", @@ -11671,19 +12180,119 @@ dependencies = [ ] [[package]] -name = "substring" -version = "1.4.5" +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "subxt" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +checksum = "588b8ce92699eeb06290f4fb02dad4f7e426c4e6db4d53889c6bcbc808cf24ac" dependencies = [ - "autocfg", + "async-trait", + "base58", + "blake2 0.10.6", + "derivative", + "either", + "frame-metadata 16.0.0", + "futures", + "hex", + "impl-serde", + "jsonrpsee 0.20.3", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-core 21.0.0", + "sp-core-hashing 9.0.0", + "sp-runtime 24.0.0", + "subxt-lightclient", + "subxt-macro", + "subxt-metadata", + "thiserror", + "tracing", ] [[package]] -name = "subtle" -version = "2.4.1" +name = "subxt-codegen" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98f5a534c8d475919e9c845d51fc2316da4fcadd04fe17552d932d2106de930e" +dependencies = [ + "frame-metadata 16.0.0", + "heck", + "hex", + "jsonrpsee 0.20.3", + "parity-scale-codec", + "proc-macro2", + "quote", + "scale-info", + "subxt-metadata", + "syn 2.0.49", + "thiserror", + "tokio", +] + +[[package]] +name = "subxt-lightclient" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10fd0ac9b091211f962b6ae19e26cd08e0b86efa064dfb7fac69c8f79f122329" +dependencies = [ + "futures", + "futures-util", + "serde", + "serde_json", + "smoldot-light", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "subxt-macro" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e8be9ab6fe88b8c13edbe15911e148482cfb905a8b8d5b8d766a64c54be0bd" +dependencies = [ + "darling 0.20.6", + "proc-macro-error", + "subxt-codegen", + "syn 2.0.49", +] + +[[package]] +name = "subxt-metadata" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "b6898275765d36a37e5ef564358e0341cf41b5f3a91683d7d8b859381b65ac8a" +dependencies = [ + "frame-metadata 16.0.0", + "parity-scale-codec", + "scale-info", + "sp-core-hashing 9.0.0", + "thiserror", +] [[package]] name = "syn" @@ -11698,9 +12307,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" dependencies = [ "proc-macro2", "quote", @@ -11765,28 +12374,27 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.12" +version = "0.12.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall 0.4.1", - "rustix 0.38.21", - "windows-sys 0.48.0", + "rustix 0.38.31", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -11816,28 +12424,48 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] -name = "thiserror-impl" +name = "thiserror-core" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c001ee18b7e5e3f62cbf58c7fe220119e68d902bb7443179c0c8aef30090e999" +dependencies = [ + "thiserror-core-impl", +] + +[[package]] +name = "thiserror-core-impl" version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.49", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -11897,12 +12525,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -11917,10 +12546,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -11977,24 +12607,11 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tmq" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e83994e39464b6dd4b3d3e1596744d6c1d56b6687fa4aa099c4994c31835763" -dependencies = [ - "futures", - "log", - "thiserror", - "tokio", - "zmq", -] - [[package]] name = "tokio" -version = "1.33.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -12022,13 +12639,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -12058,7 +12675,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.8", + "rustls 0.21.10", "tokio", ] @@ -12101,12 +12718,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" - [[package]] name = "toml" version = "0.5.11" @@ -12125,14 +12736,26 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.2", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] @@ -12143,7 +12766,20 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.2.3", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.2.3", "serde", "serde_spanned", "toml_datetime", @@ -12158,7 +12794,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.5", + "base64 0.21.7", "bytes", "futures-core", "futures-util", @@ -12169,7 +12805,7 @@ dependencies = [ "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.11.9", + "prost", "tokio", "tokio-stream", "tower", @@ -12204,7 +12840,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bytes", "futures-core", "futures-util", @@ -12248,7 +12884,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] @@ -12276,7 +12912,7 @@ dependencies = [ "serde_json", "tokio", "tracing", - "tracing-subscriber 0.3.17", + "tracing-subscriber 0.3.18", "version", ] @@ -12301,6 +12937,17 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + [[package]] name = "tracing-serde" version = "0.1.3" @@ -12330,15 +12977,15 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-serde", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers 0.1.0", "nu-ansi-term", @@ -12351,10 +12998,23 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", "tracing-serde", ] +[[package]] +name = "trie-db" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "767abe6ffed88a1889671a102c2861ae742726f52e0a5a425b92c9fbfa7e9c85" +dependencies = [ + "hash-db", + "hashbrown 0.13.2", + "log", + "rustc-hex", + "smallvec", +] + [[package]] name = "trie-db" version = "0.28.0" @@ -12425,18 +13085,18 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "try-runtime-cli" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e30562bc5a4beccd52cc4091607830fa0b77c1ce09d55b47f232c8b3d03e23fa" +checksum = "845090aa8572116b06813914fc1d09448fe895d82982b63d58de4f91b4eb79b6" dependencies = [ "async-trait", - "clap 4.4.7", + "clap 4.5.1", "frame-remote-externalities", "frame-try-runtime", "hex", @@ -12449,19 +13109,19 @@ dependencies = [ "sp-api", "sp-consensus-aura", "sp-consensus-babe", - "sp-core", - "sp-debug-derive", - "sp-externalities", + "sp-core 25.0.0", + "sp-debug-derive 12.0.0", + "sp-externalities 0.23.0", "sp-inherents", - "sp-io", - "sp-keystore", + "sp-io 27.0.0", + "sp-keystore 0.31.0", "sp-rpc", - "sp-runtime", - "sp-state-machine", + "sp-runtime 28.0.0", + "sp-state-machine 0.32.0", "sp-timestamp", "sp-transaction-storage-proof", "sp-version", - "sp-weights", + "sp-weights 24.0.0", "substrate-rpc-client", "zstd 0.12.4", ] @@ -12491,25 +13151,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "turn" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" -dependencies = [ - "async-trait", - "base64 0.13.1", - "futures", - "log", - "md-5", - "rand 0.8.5", - "ring 0.16.20", - "stun", - "thiserror", - "tokio", - "webrtc-util", -] - [[package]] name = "twox-hash" version = "1.6.3" @@ -12554,18 +13195,18 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "uncased" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" dependencies = [ "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -12594,16 +13235,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" -[[package]] -name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array 0.14.7", - "subtle", -] - [[package]] name = "universal-hash" version = "0.5.1" @@ -12611,14 +13242,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle", + "subtle 2.5.0", ] [[package]] name = "unsafe-libyaml" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" [[package]] name = "unsigned-varint" @@ -12655,12 +13286,12 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.4.0", + "idna 0.5.0", "percent-encoding", "serde", ] @@ -12701,16 +13332,16 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] name = "uuid" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", "serde", ] @@ -12750,7 +13381,7 @@ checksum = "28084ac780b443e7f3514df984a2933bd3ab39e71914d951cdf8e4d298a7c9bc" dependencies = [ "async-trait", "bytes", - "derive_builder 0.12.0", + "derive_builder", "http", "reqwest", "rustify", @@ -12787,21 +13418,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] -name = "wait-timeout" -version = "0.2.0" +name = "w3f-bls" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "7335e4c132c28cc43caef6adb339789e599e39adbe78da0c4d547fad48cbc331" dependencies = [ - "libc", + "ark-bls12-377", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-serialize-derive", + "arrayref", + "constcat", + "digest 0.10.7", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "sha2 0.10.8", + "sha3", + "thiserror", + "zeroize", ] [[package]] -name = "waitgroup" -version = "0.1.2" +name = "wait-timeout" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ - "atomic-waker", + "libc", ] [[package]] @@ -12843,9 +13489,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -12853,24 +13499,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -12880,9 +13526,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12890,22 +13536,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "wasm-instrument" @@ -12918,9 +13564,9 @@ dependencies = [ [[package]] name = "wasm-opt" -version = "0.114.2" +version = "0.116.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effbef3bd1dde18acb401f73e740a6f3d4a1bc651e9773bddc512fe4d8d68f67" +checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52" dependencies = [ "anyhow", "libc", @@ -12934,9 +13580,9 @@ dependencies = [ [[package]] name = "wasm-opt-cxx-sys" -version = "0.114.2" +version = "0.116.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c09e24eb283919ace2ed5733bda4842a59ce4c8de110ef5c6d98859513d17047" +checksum = "8c57b28207aa724318fcec6575fe74803c23f6f266fce10cbc9f3f116762f12e" dependencies = [ "anyhow", "cxx", @@ -12946,9 +13592,9 @@ dependencies = [ [[package]] name = "wasm-opt-sys" -version = "0.114.2" +version = "0.116.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f2f817bed2e8d65eb779fa37317e74de15585751f903c9118342d1970703a4" +checksum = "8a1cce564dc768dacbdb718fc29df2dba80bd21cb47d8f77ae7e3d95ceb98cbe" dependencies = [ "anyhow", "cc", @@ -12971,6 +13617,38 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmi" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51fb5c61993e71158abf5bb863df2674ca3ec39ed6471c64f07aeaf751d67b4" +dependencies = [ + "intx", + "smallvec", + "spin 0.9.8", + "wasmi_arena", + "wasmi_core", + "wasmparser-nostd", +] + +[[package]] +name = "wasmi_arena" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104a7f73be44570cac297b3035d76b169d6599637631cf37a1703326a0727073" + +[[package]] +name = "wasmi_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624e6333e861ef49095d2d678b76ebf30b06bf37effca845be7e5b87c90071b7" +dependencies = [ + "downcast-rs", + "libm", + "num-traits", + "paste", +] + [[package]] name = "wasmparser" version = "0.102.0" @@ -12982,13 +13660,12 @@ dependencies = [ ] [[package]] -name = "wasmparser" -version = "0.107.0" +name = "wasmparser-nostd" +version = "0.100.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e3ac9b780c7dda0cac7a52a5d6d2d6707cc6e3451c9db209b6c758f40d7acb" +checksum = "9157cab83003221bfd385833ab587a039f5d6fa7304854042ba358a3b09e0724" dependencies = [ - "indexmap 1.9.3", - "semver 1.0.20", + "indexmap-nostd", ] [[package]] @@ -13010,44 +13687,15 @@ dependencies = [ "rayon", "serde", "target-lexicon", - "wasmparser 0.102.0", + "wasmparser", "wasmtime-cache", - "wasmtime-cranelift 8.0.1", - "wasmtime-environ 8.0.1", - "wasmtime-jit 8.0.1", - "wasmtime-runtime 8.0.1", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-jit", + "wasmtime-runtime", "windows-sys 0.45.0", ] -[[package]] -name = "wasmtime" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc104ced94ff0a6981bde77a0bc29aab4af279914a4143b8d1af9fd4b2c9d41" -dependencies = [ - "anyhow", - "bincode", - "bumpalo", - "cfg-if", - "fxprof-processed-profile", - "indexmap 1.9.3", - "libc", - "log", - "object 0.30.4", - "once_cell", - "paste", - "psm", - "serde", - "serde_json", - "target-lexicon", - "wasmparser 0.107.0", - "wasmtime-cranelift 10.0.2", - "wasmtime-environ 10.0.2", - "wasmtime-jit 10.0.2", - "wasmtime-runtime 10.0.2", - "windows-sys 0.48.0", -] - [[package]] name = "wasmtime-asm-macros" version = "8.0.1" @@ -13057,15 +13705,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "wasmtime-asm-macros" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b28e5661a9b5f7610a62ab3c69222fa161f7bd31d04529e856461d8c3e706b" -dependencies = [ - "cfg-if", -] - [[package]] name = "wasmtime-cache" version = "8.0.1" @@ -13073,7 +13712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c86437fa68626fe896e5afc69234bb2b5894949083586535f200385adfd71213" dependencies = [ "anyhow", - "base64 0.21.5", + "base64 0.21.7", "bincode", "directories-next", "file-per-thread-logger", @@ -13093,42 +13732,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1cefde0cce8cb700b1b21b6298a3837dba46521affd7b8c38a9ee2c869eee04" dependencies = [ "anyhow", - "cranelift-codegen 0.95.1", - "cranelift-entity 0.95.1", - "cranelift-frontend 0.95.1", - "cranelift-native 0.95.1", - "cranelift-wasm 0.95.1", - "gimli 0.27.3", - "log", - "object 0.30.4", - "target-lexicon", - "thiserror", - "wasmparser 0.102.0", - "wasmtime-cranelift-shared 8.0.1", - "wasmtime-environ 8.0.1", -] - -[[package]] -name = "wasmtime-cranelift" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc1e39ce9aa0fa0b319541ed423960b06cfa7343eca1574f811ea34275739c2" -dependencies = [ - "anyhow", - "cranelift-codegen 0.97.2", - "cranelift-control", - "cranelift-entity 0.97.2", - "cranelift-frontend 0.97.2", - "cranelift-native 0.97.2", - "cranelift-wasm 0.97.2", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", "gimli 0.27.3", "log", "object 0.30.4", "target-lexicon", "thiserror", - "wasmparser 0.107.0", - "wasmtime-cranelift-shared 10.0.2", - "wasmtime-environ 10.0.2", + "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", ] [[package]] @@ -13138,28 +13754,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd041e382ef5aea1b9fc78442394f1a4f6d676ce457e7076ca4cb3f397882f8b" dependencies = [ "anyhow", - "cranelift-codegen 0.95.1", - "cranelift-native 0.95.1", - "gimli 0.27.3", - "object 0.30.4", - "target-lexicon", - "wasmtime-environ 8.0.1", -] - -[[package]] -name = "wasmtime-cranelift-shared" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd32739326690e51c76551d7cbf29d371e7de4dc7b37d2d503be314ab5b7d04" -dependencies = [ - "anyhow", - "cranelift-codegen 0.97.2", - "cranelift-control", - "cranelift-native 0.97.2", + "cranelift-codegen", + "cranelift-native", "gimli 0.27.3", "object 0.30.4", "target-lexicon", - "wasmtime-environ 10.0.2", + "wasmtime-environ", ] [[package]] @@ -13169,26 +13769,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949" dependencies = [ "anyhow", - "cranelift-entity 0.95.1", - "gimli 0.27.3", - "indexmap 1.9.3", - "log", - "object 0.30.4", - "serde", - "target-lexicon", - "thiserror", - "wasmparser 0.102.0", - "wasmtime-types 8.0.1", -] - -[[package]] -name = "wasmtime-environ" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b60e4ae5c9ae81750d8bc59110bf25444aa1d9266c19999c3b64b801db3c73" -dependencies = [ - "anyhow", - "cranelift-entity 0.97.2", + "cranelift-entity", "gimli 0.27.3", "indexmap 1.9.3", "log", @@ -13196,8 +13777,8 @@ dependencies = [ "serde", "target-lexicon", "thiserror", - "wasmparser 0.107.0", - "wasmtime-types 10.0.2", + "wasmparser", + "wasmtime-types", ] [[package]] @@ -13217,37 +13798,13 @@ dependencies = [ "rustc-demangle", "serde", "target-lexicon", - "wasmtime-environ 8.0.1", - "wasmtime-jit-debug 8.0.1", - "wasmtime-jit-icache-coherence 8.0.1", - "wasmtime-runtime 8.0.1", + "wasmtime-environ", + "wasmtime-jit-debug", + "wasmtime-jit-icache-coherence", + "wasmtime-runtime", "windows-sys 0.45.0", ] -[[package]] -name = "wasmtime-jit" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b23a10eddfe7814feb548a466f3f25aa4bb4f43098a147305c544a2de28e1" -dependencies = [ - "addr2line 0.19.0", - "anyhow", - "bincode", - "cfg-if", - "cpp_demangle", - "gimli 0.27.3", - "log", - "object 0.30.4", - "rustc-demangle", - "rustix 0.37.27", - "serde", - "target-lexicon", - "wasmtime-environ 10.0.2", - "wasmtime-jit-icache-coherence 10.0.2", - "wasmtime-runtime 10.0.2", - "windows-sys 0.48.0", -] - [[package]] name = "wasmtime-jit-debug" version = "8.0.1" @@ -13259,66 +13816,22 @@ dependencies = [ "rustix 0.36.17", ] -[[package]] -name = "wasmtime-jit-debug" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46b7e98979a69d3df093076bde8431204e3c96a770e8d216fea365c627d88a4" -dependencies = [ - "once_cell", -] - -[[package]] -name = "wasmtime-jit-icache-coherence" -version = "8.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.45.0", -] - [[package]] name = "wasmtime-jit-icache-coherence" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb1e7c68ede63dc7a98c3e473162954e224951854e229c8b4e74697fe17dbdd" -dependencies = [ - "cfg-if", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "wasmtime-runtime" version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658cf6f325232b6760e202e5255d823da5e348fdea827eff0a2a22319000b441" -dependencies = [ - "anyhow", - "cc", - "cfg-if", - "indexmap 1.9.3", - "libc", - "log", - "mach", - "memfd", - "memoffset 0.8.0", - "paste", - "rand 0.8.5", - "rustix 0.36.17", - "wasmtime-asm-macros 8.0.1", - "wasmtime-environ 8.0.1", - "wasmtime-jit-debug 8.0.1", +checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd" +dependencies = [ + "cfg-if", + "libc", "windows-sys 0.45.0", ] [[package]] name = "wasmtime-runtime" -version = "10.0.2" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843e33bf9e0f0c57902c87a1dea1389cc23865c65f007214318dbdfcb3fd4ae5" +checksum = "658cf6f325232b6760e202e5255d823da5e348fdea827eff0a2a22319000b441" dependencies = [ "anyhow", "cc", @@ -13328,15 +13841,14 @@ dependencies = [ "log", "mach", "memfd", - "memoffset 0.8.0", + "memoffset", "paste", "rand 0.8.5", - "rustix 0.37.27", - "sptr", - "wasmtime-asm-macros 10.0.2", - "wasmtime-environ 10.0.2", - "wasmtime-jit-debug 10.0.2", - "windows-sys 0.48.0", + "rustix 0.36.17", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-jit-debug", + "windows-sys 0.45.0", ] [[package]] @@ -13345,51 +13857,29 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f" dependencies = [ - "cranelift-entity 0.95.1", - "serde", - "thiserror", - "wasmparser 0.102.0", -] - -[[package]] -name = "wasmtime-types" -version = "10.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7473a07bebd85671bada453123e3d465c8e0a59668ff79f5004076e6a2235ef5" -dependencies = [ - "cranelift-entity 0.97.2", + "cranelift-entity", "serde", "thiserror", - "wasmparser 0.107.0", + "wasmparser", ] [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "webpki" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.5", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -13399,222 +13889,14 @@ version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ - "webpki 0.22.4", + "webpki", ] [[package]] name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - -[[package]] -name = "webrtc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3bc9049bdb2cea52f5fd4f6f728184225bdb867ed0dc2410eab6df5bdd67bb" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "hex", - "interceptor", - "lazy_static", - "log", - "rand 0.8.5", - "rcgen 0.9.3", - "regex", - "ring 0.16.20", - "rtcp", - "rtp", - "rustls 0.19.1", - "sdp", - "serde", - "serde_json", - "sha2 0.10.8", - "stun", - "thiserror", - "time", - "tokio", - "turn", - "url", - "waitgroup", - "webrtc-data", - "webrtc-dtls", - "webrtc-ice", - "webrtc-mdns", - "webrtc-media", - "webrtc-sctp", - "webrtc-srtp", - "webrtc-util", -] - -[[package]] -name = "webrtc-data" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef36a4d12baa6e842582fe9ec16a57184ba35e1a09308307b67d43ec8883100" -dependencies = [ - "bytes", - "derive_builder 0.11.2", - "log", - "thiserror", - "tokio", - "webrtc-sctp", - "webrtc-util", -] - -[[package]] -name = "webrtc-dtls" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a00f4242f2db33307347bd5be53263c52a0331c96c14292118c9a6bb48d267" -dependencies = [ - "aes 0.6.0", - "aes-gcm 0.10.3", - "async-trait", - "bincode", - "block-modes", - "byteorder", - "ccm", - "curve25519-dalek 3.2.0", - "der-parser 8.2.0", - "elliptic-curve 0.12.3", - "hkdf", - "hmac 0.12.1", - "log", - "p256", - "p384", - "rand 0.8.5", - "rand_core 0.6.4", - "rcgen 0.10.0", - "ring 0.16.20", - "rustls 0.19.1", - "sec1 0.3.0", - "serde", - "sha1", - "sha2 0.10.8", - "signature 1.6.4", - "subtle", - "thiserror", - "tokio", - "webpki 0.21.4", - "webrtc-util", - "x25519-dalek 2.0.0", - "x509-parser 0.13.2", -] - -[[package]] -name = "webrtc-ice" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a03cc11e9a7d7b4f9f99870558fe37a102b65b93f8045392fef7c67b39e80" -dependencies = [ - "arc-swap", - "async-trait", - "crc", - "log", - "rand 0.8.5", - "serde", - "serde_json", - "stun", - "thiserror", - "tokio", - "turn", - "url", - "uuid 1.5.0", - "waitgroup", - "webrtc-mdns", - "webrtc-util", -] - -[[package]] -name = "webrtc-mdns" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" -dependencies = [ - "log", - "socket2 0.4.10", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-media" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f72e1650a8ae006017d1a5280efb49e2610c19ccc3c0905b03b648aee9554991" -dependencies = [ - "byteorder", - "bytes", - "rand 0.8.5", - "rtp", - "thiserror", -] - -[[package]] -name = "webrtc-sctp" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d47adcd9427eb3ede33d5a7f3424038f63c965491beafcc20bc650a2f6679c0" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "crc", - "log", - "rand 0.8.5", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-srtp" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6183edc4c1c6c0175f8812eefdce84dfa0aea9c3ece71c2bf6ddd3c964de3da5" -dependencies = [ - "aead 0.4.3", - "aes 0.7.5", - "aes-gcm 0.9.4", - "async-trait", - "byteorder", - "bytes", - "ctr 0.8.0", - "hmac 0.11.0", - "log", - "rtcp", - "rtp", - "sha-1", - "subtle", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-util" -version = "0.7.0" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" -dependencies = [ - "async-trait", - "bitflags 1.3.2", - "bytes", - "cc", - "ipnet", - "lazy_static", - "libc", - "log", - "nix 0.24.3", - "rand 0.8.5", - "thiserror", - "tokio", - "winapi", -] +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" @@ -13625,14 +13907,14 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.21", + "rustix 0.38.31", ] [[package]] name = "wide" -version = "0.7.13" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68938b57b33da363195412cfc5fc37c9ed49aa9cfe2156fde64b8d2c9498242" +checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" dependencies = [ "bytemuck", "safe_arch", @@ -13644,6 +13926,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +[[package]] +name = "wildmatch" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "495ec47bf3c1345005f40724f0269362c8556cbc43aed0526ed44cae1d35fceb" + [[package]] name = "winapi" version = "0.3.9" @@ -13681,7 +13969,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core", + "windows-core 0.51.1", "windows-targets 0.48.5", ] @@ -13694,6 +13982,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -13712,6 +14009,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -13742,6 +14048,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -13754,6 +14075,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -13766,6 +14093,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -13778,6 +14111,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -13790,6 +14129,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -13802,6 +14147,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -13814,6 +14165,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -13826,11 +14183,17 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" -version = "0.5.18" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176b6138793677221d420fd2f0aeeced263f197688b36484660da767bca2fa32" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -13867,48 +14230,29 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "rand_core 0.6.4", "serde", "zeroize", ] -[[package]] -name = "x509-parser" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" -dependencies = [ - "asn1-rs 0.3.1", - "base64 0.13.1", - "data-encoding", - "der-parser 7.0.0", - "lazy_static", - "nom", - "oid-registry 0.4.0", - "ring 0.16.20", - "rusticata-macros", - "thiserror", - "time", -] - [[package]] name = "x509-parser" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", "base64 0.13.1", "data-encoding", - "der-parser 8.2.0", + "der-parser", "lazy_static", "nom", - "oid-registry 0.6.1", + "oid-registry", "rusticata-macros", "thiserror", "time", @@ -13916,11 +14260,13 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", + "linux-raw-sys 0.4.13", + "rustix 0.38.31", ] [[package]] @@ -13952,6 +14298,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4524214bc4629eba08d78ceb1d6507070cc0bcbbed23af74e19e6e924a24cf" + [[package]] name = "yasna" version = "0.5.2" @@ -13963,29 +14315,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.20" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.20" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.49", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -13998,39 +14350,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", -] - -[[package]] -name = "zeromq-src" -version = "0.1.10+4.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9133d366817fcffe22e4356043ba187ae122ec5db63d7ce73d1e6a18efa2f1" -dependencies = [ - "cmake", -] - -[[package]] -name = "zmq" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aad98a7a617d608cd9e1127147f630d24af07c7cd95ba1533246d96cbdd76c66" -dependencies = [ - "bitflags 1.3.2", - "libc", - "log", - "zmq-sys", -] - -[[package]] -name = "zmq-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d33a2c51dde24d5b451a2ed4b488266df221a5eaee2ee519933dc46b9a9b3648" -dependencies = [ - "libc", - "metadeps", - "zeromq-src", + "syn 2.0.49", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3339dacdf..2d87b62dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,19 +8,23 @@ members = [ "crates/chronicle-domain", "crates/chronicle-domain-lint", "crates/chronicle-domain-test", - "crates/chronicle-protocol", + "crates/chronicle-test-infrastructure", "crates/chronicle-synth", "crates/chronicle-signing", "crates/chronicle-telemetry", "crates/gq-subscribe", "crates/id-provider", - "crates/opa-tp", - "crates/opa-tp-protocol", - "crates/opactl", - "crates/sawtooth-tp", "crates/pallet-chronicle", + "crates/pallet-opa", "node/runtime-chronicle", "node/node-chronicle", + "crates/embedded-substrate", + "crates/runtime-api-chronicle", + "crates/protocol-abstract", + "crates/protocol-substrate", + "crates/protocol-substrate-chronicle", + "crates/protocol-substrate-opa", + "crates/chronicle-test-infrastructure", ] [workspace.dependencies] @@ -29,16 +33,12 @@ anyhow = "1.0.6" assert_fs = "1.0" async-graphql = "5.0.9" async-graphql-poem = "5.0.9" -async-stl-client = { git = "https://github.com/btpworks/async-stl-sdk" } async-stream = "0.3.3" async-trait = "0.1.61" backoff = { version = "0.4.0", features = ["futures", "tokio"] } base64 = "0.21" bytes = "1.3.0" cached = "0.42" -frame-support = "24.0.0" -frame-system = "24.0.0" -frame-benchmarking = "24.0.0" cfg-if = "1.0.0" chronicle-signing = { path = "crates/chronicle-signing" } chrono = "0.4.26" @@ -53,14 +53,13 @@ criterion = { version = "0.5.1", features = ["async_futures", "async_tokio"] } crossbeam = "0.8.1" custom_error = "1.9.2" derivative = "2.2.0" -diesel = { version = "2.0.0-rc.0", features = [ - "postgres", - "uuid", - "chrono", - "r2d2", -] } -diesel_migrations = { version = "2.0.0-rc.0", features = ["postgres"] } +diesel = { version = "2.1", features = ["postgres", "uuid", "chrono", "r2d2"] } +diesel-async = { version = "0.4" } +diesel_migrations = { version = "2.1", features = ["postgres"] } dotenvy = "0.15" +frame-benchmarking = "24.0.0" +frame-support = "24.0.0" +frame-system = "24.0.0" futures = "0.3.21" genco = "0.16.1" glob = "0.3.0" @@ -80,6 +79,7 @@ k256 = { version = "0.11.3", features = [ "ecdsa", "pkcs8", "sha256", + "keccak256", "std", "pem", "serde", @@ -87,15 +87,16 @@ k256 = { version = "0.11.3", features = [ lazy_static = "1.4.0" locspan = "0.7" lru = "0.11" +macro-attr-2018 = "3.0.0" maplit = "1.0.2" metrics = "0.21.0" metrics-exporter-prometheus = "0.12.1" mime = "0.3" +mobc = "0.8" mockito = "1.1" +newtype-derive-2018 = "0.2.1" oauth2 = "4.4" -opa = { git = "https://github.com/tamasfe/opa-rs", rev = "3cf7fea" } -openssl = { version = "0.10" } -openssl-sys = { version = "0.10", features = ["vendored"] } +opa = { git = "https://github.com/chronicleworks/opa-rs", rev = "9fa2fbce" } opentelemetry = { version = "0.19.0", features = ["rt-tokio"] } opentelemetry-jaeger = { version = "0.18.0", features = [ "rt-tokio", @@ -110,37 +111,30 @@ pin-project-lite = "0.2" pinvec = "0.1.0" pkcs8 = { version = "0.10", features = ["std", "alloc"] } poem = { version = "1.3.58", features = ["opentelemetry", "websocket"] } -portpicker = "0.1.1" -pow_of_2 = "0.1.2" -proptest = "1.0.0" -prost = "0.10" # common, sawtooth-protocol, sawtooth-tp: version = "0.10.0" -prost-build = "0.10.0" -prost-types = "0.11.2" -protobuf = "2.27.1" +portpicker = "0.1" +pow_of_2 = "0.1" +proptest = "1" question = "0.2.2" r2d2 = "0.8.9" -rand = { version = "0.8.5", features = ["getrandom"] } -rand_core = "0.6.3" +rand = { version = "0.8", features = ["getrandom"] } +rand_core = "0.6" rdf-types = "0.14" -reqwest = "0.11.20" +reqwest = "0.11" rust-embed = { version = "6.6.0", features = [ "debug-embed", "include-exclude", ] } -sawtooth-sdk = { git = "https://github.com/hyperledger/sawtooth-sdk-rust", rev = "5a300de" } secret-vault = { version = "1.8", features = [] } secret-vault-value = "0.3" -serde = "1.0.152" -serde_derive = "1.0.152" -serde_json = "1.0.93" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" serde_yaml = "0.9.14" shellexpand = "3.0.0" -macro-attr-2018 = "3.0.0" -newtype-derive-2018 = "0.2.1" temp-dir = "0.1.11" tempfile = "3.4.0" +testcontainers = "0.14" thiserror = "1.0" -tmq = "0.3" tokio = { version = "1.27", features = [ "time", "macros", @@ -149,7 +143,7 @@ tokio = { version = "1.27", features = [ ] } tokio-stream = { version = "0.1.11", features = ["sync"] } toml = "0.7.3" -tracing = "0.1.37" +tracing = "0.1" tracing-elastic-apm = "3.2.3" tracing-log = "0.1.3" tracing-opentelemetry = "0.19" @@ -160,10 +154,8 @@ tracing-subscriber = { version = "0.3.15", features = [ "json", ] } tungstenite = "0.20.1" -url = "2.3.1" -user-error = "1.2.8" -uuid = "1.2.2" +url = "2" +user-error = "1" +uuid = "1" valico = "3.6.0" -vaultrs = "*" -zmq = { version = "0.9", features = ["vendored"] } -testcontainers = "0.14" +vaultrs = "0.7" diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index c0295433b..622b133bc 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -6,6 +6,7 @@ version = "0.7.5" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = { workspace = true } async-graphql = { workspace = true, features = [ "opentelemetry", "chrono", @@ -14,23 +15,25 @@ async-graphql = { workspace = true, features = [ "uuid", ] } async-graphql-poem = { workspace = true } -async-stl-client = { workspace = true } async-stream = { workspace = true } async-trait = { workspace = true } base64 = { workspace = true } cached = { workspace = true } cfg-if = { workspace = true } -chronicle-protocol = { path = "../chronicle-protocol" } chronicle-signing = { workspace = true } chronicle-telemetry = { path = "../chronicle-telemetry" } chrono = { workspace = true } -common = { path = "../common" } +common = { path = "../common", features = [ + "json-ld", + "diesel-bindings", + "graphql-bindings", + "std", +] } custom_error = { workspace = true } derivative = { workspace = true } diesel = { workspace = true } diesel_migrations = { workspace = true } futures = { workspace = true } -glob = { workspace = true } hex = { workspace = true } iref = { workspace = true } json-ld = { workspace = true } @@ -42,20 +45,18 @@ opa = { workspace = true } opentelemetry = { workspace = true } parking_lot = { workspace = true } poem = { workspace = true } -portpicker = { workspace = true } -prost = { workspace = true } -protobuf = { workspace = true } +protocol-substrate = { path = "../protocol-substrate" } +protocol-substrate-chronicle = { path = "../protocol-substrate-chronicle" } +protocol-substrate-opa = { path = "../protocol-substrate-opa" } r2d2 = { workspace = true } rand = { workspace = true } rand_core = { workspace = true } reqwest = { workspace = true } -sawtooth-sdk = { workspace = true } -sawtooth_tp = { path = "../sawtooth-tp" } +rust-embed = { workspace = true } serde = { workspace = true } serde_derive = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } -tmq = { workspace = true } tokio = { workspace = true } tokio-stream = { workspace = true } tracing = { workspace = true } @@ -64,17 +65,13 @@ user-error = { workspace = true } uuid = { workspace = true } [dev-dependencies] -assert_fs = { workspace = true } -chronicle-protocol = { path = "../chronicle-protocol" } -insta = { workspace = true, features = ["json", "yaml"] } -opa-tp-protocol = { path = "../opa-tp-protocol" } -tempfile = { workspace = true } +assert_fs = { workspace = true } +insta = { workspace = true, features = ["json", "yaml"] } +tempfile = { workspace = true } [build-dependencies] [features] -devmode = ["inmem"] +devmode = [] -# Use an in-memory stub ledger -inmem = [] strict = [] diff --git a/crates/api/src/chronicle_graphql/mod.rs b/crates/api/src/chronicle_graphql/mod.rs index e2b80a510..83658fe2a 100644 --- a/crates/api/src/chronicle_graphql/mod.rs +++ b/crates/api/src/chronicle_graphql/mod.rs @@ -12,9 +12,9 @@ use chrono::NaiveDateTime; use common::{ identity::{AuthId, IdentityError, JwtClaims, OpaData, SignedIdentity}, ledger::{SubmissionError, SubmissionStage}, - opa::{ExecutorContext, OpaExecutorError}, + opa::std::{ExecutorContext, OpaExecutorError}, prov::{ - to_json_ld::ToJson, ChronicleIri, ChronicleTransactionId, ExternalId, ExternalIdPart, + json_ld::ToJson, ChronicleIri, ChronicleTransactionId, ExternalId, ExternalIdPart, ProvModel, }, }; @@ -292,10 +292,7 @@ impl From for CommitIdentity { CommitIdentity { identity: identity.identity, signature: identity.signature.map(|x| hex::encode(&*x)).unwrap_or_default(), - verifying_key: identity - .verifying_key - .map(|x| hex::encode(x.to_bytes())) - .unwrap_or_default(), + verifying_key: identity.verifying_key.map(hex::encode).unwrap_or_default(), } } } @@ -810,8 +807,8 @@ impl IriEndpoint { .body("failed to compact JSON response")) }, }, - Err(StoreError::Db(diesel::result::Error::NotFound)) - | Err(StoreError::RecordNotFound) => { + Err(StoreError::Db(diesel::result::Error::NotFound)) | + Err(StoreError::RecordNotFound) => { tracing::debug!("not found: {prov_type} {} in {ns}", id.external_id_part()); Ok(poem::Response::builder() .status(StatusCode::NOT_FOUND) @@ -875,9 +872,8 @@ impl IriEndpoint { match ChronicleIri::from_str(&ns_iri.iri) { Ok(iri) => Ok(Ok((ns_iri.ns.into(), iri))), - Err(error) => { - Ok(Err(Response::builder().status(StatusCode::NOT_FOUND).body(error.to_string()))) - }, + Err(error) => + Ok(Err(Response::builder().status(StatusCode::NOT_FOUND).body(error.to_string()))), } } @@ -888,24 +884,21 @@ impl IriEndpoint { claims: Option<&JwtClaims>, ) -> poem::Result { match self.parse_ns_iri_from_uri_path(req).await? { - Ok((ns, ChronicleIri::Activity(id))) => { + Ok((ns, ChronicleIri::Activity(id))) => self.response_for_query(claims, "activity", &id, &ns, |mut conn, id, ns| { self.store.prov_model_for_activity_id(&mut conn, id, ns) }) - .await - }, - Ok((ns, ChronicleIri::Agent(id))) => { + .await, + Ok((ns, ChronicleIri::Agent(id))) => self.response_for_query(claims, "agent", &id, &ns, |mut conn, id, ns| { self.store.prov_model_for_agent_id(&mut conn, id, ns) }) - .await - }, - Ok((ns, ChronicleIri::Entity(id))) => { + .await, + Ok((ns, ChronicleIri::Entity(id))) => self.response_for_query(claims, "entity", &id, &ns, |mut conn, id, ns| { self.store.prov_model_for_entity_id(&mut conn, id, ns) }) - .await - }, + .await, Ok(_) => Ok(poem::Response::builder() .status(StatusCode::NOT_FOUND) .body("may query only: activity, agent, entity")), diff --git a/crates/api/src/chronicle_graphql/mutation.rs b/crates/api/src/chronicle_graphql/mutation.rs index 43c806858..e96255ff9 100644 --- a/crates/api/src/chronicle_graphql/mutation.rs +++ b/crates/api/src/chronicle_graphql/mutation.rs @@ -1,10 +1,9 @@ //! Primitive mutation operations that are not in terms of particular domain types - +use crate::commands::{ActivityCommand, AgentCommand, ApiCommand, ApiResponse, EntityCommand}; use async_graphql::Context; use chrono::{DateTime, Utc}; use common::{ attributes::Attributes, - commands::{ActivityCommand, AgentCommand, ApiCommand, ApiResponse, EntityCommand}, identity::AuthId, prov::{operations::DerivationType, ActivityId, AgentId, EntityId, Role}, }; diff --git a/crates/api/src/commands.rs b/crates/api/src/commands.rs index 3719d38fc..baf77e4f6 100644 --- a/crates/api/src/commands.rs +++ b/crates/api/src/commands.rs @@ -1,4 +1,5 @@ use core::pin::Pin; +use std::{path::PathBuf, sync::Arc}; #[cfg(feature = "std")] use std::{path::PathBuf, sync::Arc}; @@ -7,7 +8,7 @@ use futures::AsyncRead; use serde::{Deserialize, Serialize}; -use crate::{ +use common::{ attributes::Attributes, prov::{ operations::{ChronicleOperation, DerivationType}, @@ -16,13 +17,6 @@ use crate::{ }, }; -#[cfg(not(feature = "std"))] -use parity_scale_codec::{ - alloc::boxed::Box, alloc::string::String, alloc::sync::Arc, alloc::vec::Vec, -}; -#[cfg(not(feature = "std"))] -use scale_info::prelude::*; - #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NamespaceCommand { Create { external_id: ExternalId }, @@ -47,7 +41,6 @@ pub enum AgentCommand { role: Option, }, } - #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ActivityCommand { Create { @@ -156,8 +149,7 @@ impl ActivityCommand { #[derive(Clone)] pub enum PathOrFile { Path(PathBuf), - File(Arc>>), /* Non serialisable variant, used in - * process */ + File(Arc>>), } impl core::fmt::Debug for PathOrFile { diff --git a/crates/api/src/import.rs b/crates/api/src/import.rs index 92a2185c2..8b1378917 100644 --- a/crates/api/src/import.rs +++ b/crates/api/src/import.rs @@ -1,60 +1 @@ -use std::{ - fs::File, - io::{self, Read}, - path::PathBuf, -}; -use thiserror::Error; -use url::Url; - -#[derive(Error, Debug)] -pub enum FromUrlError { - #[error("HTTP error while attempting to read from URL: {0}")] - HTTP(#[from] reqwest::Error), - - #[error("Invalid URL scheme: {0}")] - InvalidUrlScheme(String), - - #[error("IO error while attempting to read from URL: {0}")] - IO(#[from] std::io::Error), -} - -pub enum PathOrUrl { - File(PathBuf), - Url(Url), -} - -pub async fn load_bytes_from_url(url: &str) -> Result, FromUrlError> { - let path_or_url = match url.parse::() { - Ok(url) => PathOrUrl::Url(url), - Err(_) => PathOrUrl::File(PathBuf::from(url)), - }; - - let content = match path_or_url { - PathOrUrl::File(path) => { - let mut file = File::open(path)?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; - Ok(buf) - }, - PathOrUrl::Url(url) => match url.scheme() { - "file" => { - let mut file = File::open(url.path())?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf)?; - Ok(buf) - }, - "http" | "https" => Ok(reqwest::get(url).await?.bytes().await?.into()), - _ => Err(FromUrlError::InvalidUrlScheme(url.scheme().to_owned())), - }, - }?; - - Ok(content) -} - -pub fn load_bytes_from_stdin() -> Result, io::Error> { - let mut buffer = Vec::new(); - let mut stdin = io::stdin(); - let _ = stdin.read_to_end(&mut buffer)?; - Ok(buffer) -} diff --git a/crates/api/src/inmem.rs b/crates/api/src/inmem.rs deleted file mode 100644 index 73d0b8aa4..000000000 --- a/crates/api/src/inmem.rs +++ /dev/null @@ -1,405 +0,0 @@ -use async_stl_client::{ - error::SawtoothCommunicationError, - ledger::SawtoothLedger, - zmq_client::{HighestBlockValidatorSelector, ZmqRequestResponseSawtoothChannel}, -}; -use chronicle_protocol::address::{FAMILY, VERSION}; -use protobuf::{self, Message, ProtobufEnum}; - -use chronicle_protocol::{messages::ChronicleSubmitTransaction, protocol::ChronicleOperationEvent}; -use chronicle_sawtooth_tp::tp::ChronicleTransactionHandler; -use futures::{select, FutureExt, SinkExt, StreamExt}; -use sawtooth_sdk::{ - messages::{ - block::{Block, BlockHeader}, - client_batch_submit::{ - ClientBatchSubmitRequest, ClientBatchSubmitResponse, ClientBatchSubmitResponse_Status, - }, - client_block::{ - ClientBlockGetByNumRequest, ClientBlockGetResponse, ClientBlockGetResponse_Status, - ClientBlockListResponse, ClientBlockListResponse_Status, - }, - client_event::{ClientEventsSubscribeResponse, ClientEventsSubscribeResponse_Status}, - client_state::{ - ClientStateGetRequest, ClientStateGetResponse, ClientStateGetResponse_Status, - }, - processor::TpProcessRequest, - transaction::TransactionHeader, - validator::Message_MessageType, - }, - processor::handler::{ContextError, TransactionContext, TransactionHandler}, -}; -use serde_json::Value; -use std::{ - cell::RefCell, - collections::BTreeMap, - net::{Ipv4Addr, SocketAddr}, - sync::{Arc, Mutex}, - thread::{self}, -}; -use tmq::{router, Context, Multipart}; -use tokio::runtime; -use tokio_stream::wrappers::UnboundedReceiverStream; -use tracing::{debug, error, info, instrument}; -use uuid::Uuid; - -type TestTxEvents = Vec<(String, Vec<(String, String)>, Vec)>; - -pub trait SimulatedSawtoothBehavior { - fn handle_request( - &self, - message_type: Message_MessageType, - request: Vec, - ) -> Result<(Message_MessageType, Vec), SawtoothCommunicationError>; -} - -pub type InMemLedger = SawtoothLedger< - ZmqRequestResponseSawtoothChannel, - ChronicleOperationEvent, - ChronicleSubmitTransaction, ->; - -pub struct SimulatedTransactionContext { - pub state: RefCell>>, - pub events: RefCell, - tx: tokio::sync::mpsc::UnboundedSender)>>, -} - -impl SimulatedTransactionContext { - pub fn new( - tx: tokio::sync::mpsc::UnboundedSender)>>, - ) -> Self { - Self { state: RefCell::new(BTreeMap::new()), events: RefCell::new(vec![]), tx } - } - - pub fn new_with_state( - tx: tokio::sync::mpsc::UnboundedSender)>>, - state: BTreeMap>, - ) -> Self { - Self { state: state.into(), events: RefCell::new(vec![]), tx } - } - - pub fn readable_state(&self) -> Vec<(String, Value)> { - // Deal with the fact that policies are raw bytes, but meta data and - // keys are json - - self.state - .borrow() - .iter() - .map(|(k, v)| { - let as_string = String::from_utf8(v.clone()).unwrap(); - if serde_json::from_str::(&as_string).is_ok() { - (k.clone(), serde_json::from_str(&as_string).unwrap()) - } else { - (k.clone(), serde_json::to_value(v.clone()).unwrap()) - } - }) - .collect() - } -} - -impl TransactionContext for SimulatedTransactionContext { - fn add_receipt_data( - self: &SimulatedTransactionContext, - _data: &[u8], - ) -> Result<(), ContextError> { - unimplemented!() - } - - #[instrument(skip(self))] - fn add_event( - self: &SimulatedTransactionContext, - event_type: String, - attributes: Vec<(String, String)>, - data: &[u8], - ) -> Result<(), ContextError> { - let stl_event = sawtooth_sdk::messages::events::Event { - event_type: event_type.clone(), - attributes: attributes - .iter() - .map(|(k, v)| sawtooth_sdk::messages::events::Event_Attribute { - key: k.clone(), - value: v.clone(), - ..Default::default() - }) - .collect(), - data: data.to_vec(), - ..Default::default() - }; - let list = sawtooth_sdk::messages::events::EventList { - events: vec![stl_event].into(), - ..Default::default() - }; - let stl_event = list.write_to_bytes().unwrap(); - - self.tx.send(Some((Message_MessageType::CLIENT_EVENTS, stl_event))).unwrap(); - - self.events.borrow_mut().push((event_type, attributes, data.to_vec())); - - Ok(()) - } - - fn delete_state_entries( - self: &SimulatedTransactionContext, - _addresses: &[std::string::String], - ) -> Result, ContextError> { - unimplemented!() - } - - fn get_state_entries( - &self, - addresses: &[String], - ) -> Result)>, ContextError> { - Ok(self - .state - .borrow() - .iter() - .filter(|(k, _)| addresses.contains(k)) - .map(|(k, v)| (k.clone(), v.clone())) - .collect()) - } - - fn set_state_entries( - self: &SimulatedTransactionContext, - entries: Vec<(String, Vec)>, - ) -> std::result::Result<(), sawtooth_sdk::processor::handler::ContextError> { - for entry in entries { - self.state.borrow_mut().insert(entry.0, entry.1); - } - - Ok(()) - } -} - -#[derive(Clone)] -pub struct WellBehavedBehavior { - handler: Arc, - context: Arc>, -} - -impl SimulatedSawtoothBehavior for WellBehavedBehavior { - #[instrument(skip(self, request))] - fn handle_request( - &self, - message_type: Message_MessageType, - request: Vec, - ) -> Result<(Message_MessageType, Vec), SawtoothCommunicationError> { - match message_type { - // Batch submit request, decode and apply the transactions - // in the batch - Message_MessageType::CLIENT_BATCH_SUBMIT_REQUEST => { - let mut req = ClientBatchSubmitRequest::parse_from_bytes(&request).unwrap(); - let batch = req.take_batches().into_iter().next().unwrap(); - - debug!(received_batch = ?batch, transactions = ?batch.transactions); - - // Convert transaction into TpProcessRequest - for tx in batch.transactions { - let req = TpProcessRequest { - payload: tx.get_payload().to_vec(), - header: Some(TransactionHeader::parse_from_bytes(tx.get_header()).unwrap()) - .into(), - signature: tx.get_header_signature().to_string(), - ..Default::default() - }; - - self.handler.as_ref().apply(&req, &mut *self.context.lock().unwrap()).unwrap(); - } - let mut response = ClientBatchSubmitResponse::new(); - response.set_status(ClientBatchSubmitResponse_Status::OK); - let mut buf = vec![]; - response.write_to_vec(&mut buf).unwrap(); - Ok((Message_MessageType::CLIENT_BATCH_SUBMIT_RESPONSE, buf)) - }, - Message_MessageType::CLIENT_BLOCK_GET_BY_NUM_REQUEST => { - let req = ClientBlockGetByNumRequest::parse_from_bytes(&request).unwrap(); - debug!(get_block=?req); - let mut response = ClientBlockGetResponse::new(); - let block_header = BlockHeader { - block_num: req.get_block_num(), - previous_block_id: hex::encode([0; 32]), - ..Default::default() - }; - let block_header_bytes = block_header.write_to_bytes().unwrap(); - response.set_block(Block { header: block_header_bytes, ..Default::default() }); - response.set_status(ClientBlockGetResponse_Status::OK); - let mut buf = vec![]; - response.write_to_vec(&mut buf).unwrap(); - Ok((Message_MessageType::CLIENT_BLOCK_GET_RESPONSE, buf)) - }, - // Always respond with a block height of one - Message_MessageType::CLIENT_BLOCK_LIST_REQUEST => { - let mut response = ClientBlockListResponse::new(); - let block_header = BlockHeader { block_num: 1, ..Default::default() }; - let block_header_bytes = block_header.write_to_bytes().unwrap(); - response.set_blocks( - vec![Block { header: block_header_bytes, ..Default::default() }].into(), - ); - response.set_status(ClientBlockListResponse_Status::OK); - let mut buf = vec![]; - response.write_to_vec(&mut buf).unwrap(); - Ok((Message_MessageType::CLIENT_BLOCK_LIST_RESPONSE, buf)) - }, - // We can just return Ok here, no need to fake routing - Message_MessageType::CLIENT_EVENTS_SUBSCRIBE_REQUEST => { - let mut response = ClientEventsSubscribeResponse::new(); - response.set_status(ClientEventsSubscribeResponse_Status::OK); - let mut buf = vec![]; - response.write_to_vec(&mut buf).unwrap(); - Ok((Message_MessageType::CLIENT_EVENTS_SUBSCRIBE_RESPONSE, buf)) - }, - Message_MessageType::CLIENT_STATE_GET_REQUEST => { - let mut request = ClientStateGetRequest::parse_from_bytes(&request).unwrap(); - let address = request.take_address(); - - let state = self.context.lock().unwrap().get_state_entries(&[address]).unwrap(); - - let mut response = ClientStateGetResponse { - status: ClientStateGetResponse_Status::OK, - ..Default::default() - }; - - if state.is_empty() { - response.set_status(ClientStateGetResponse_Status::NO_RESOURCE); - } else { - response.set_value(state[0].1.clone()); - } - - let mut buf = vec![]; - response.write_to_vec(&mut buf).unwrap(); - Ok((Message_MessageType::CLIENT_STATE_GET_RESPONSE, buf)) - }, - _ => panic!("Unexpected message type {} received", message_type as i32), - } - } -} - -pub struct EmbeddedChronicleTp { - pub ledger: InMemLedger, - context: Arc>, -} - -impl EmbeddedChronicleTp { - pub fn new_with_state( - state: BTreeMap>, - ) -> Result { - let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); - - let context = Arc::new(Mutex::new(SimulatedTransactionContext::new_with_state(tx, state))); - - let (policy, entrypoint) = ("allow_transactions", "allow_transactions.allowed_users"); - - let handler = Arc::new(ChronicleTransactionHandler::new(policy, entrypoint).unwrap()); - - let behavior = WellBehavedBehavior { handler, context: context.clone() }; - - let listen_port = portpicker::pick_unused_port().expect("No ports free"); - let listen_addr = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), listen_port); - let connect_addr = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), listen_port); - - let behavior_clone = behavior; - thread::spawn(move || { - let rt = runtime::Builder::new_current_thread() - .enable_io() - .enable_time() - .build() - .unwrap(); - let mut rx = UnboundedReceiverStream::new(rx); - let local = tokio::task::LocalSet::new(); - - let task = local.run_until(async move { - tokio::task::spawn_local(async move { - let (mut router_tx, mut router_rx) = router(&Context::new()) - .bind(&format!("tcp://{}", listen_addr)) - .unwrap() - .split(); - - debug!(listen_addr = ?listen_addr, "Embedded TP listening"); - let mut last_address = vec![]; - loop { - select! { - message = router_rx.next().fuse() => { - if message.is_none() { - break; - } - - let multipart = message.unwrap().unwrap(); - - last_address = multipart[0].to_vec(); - let request: async_stl_client::messages::Message = - async_stl_client::prost::Message::decode(&*multipart[1].to_vec()).map_err(|e| error!(%e)).unwrap(); - - debug!(request = ?request); - - let response = behavior_clone - .handle_request( - Message_MessageType::from_i32(request.message_type).unwrap(), - request.content, - ) - .unwrap(); - - let message_wrapper = async_stl_client::messages::Message { - message_type: response.0 as i32, - tx_id: request.tx_id, - content: response.1 - }; - - let mut multipart = Multipart::default(); - multipart.push_back(last_address.clone().into()); - multipart.push_back(tmq::Message::from(prost::Message::encode_to_vec(&message_wrapper))); - - debug!(response = ?multipart); - router_tx.send(multipart).await.ok(); - }, - unsolicited_message = rx.next().fuse() => { - if unsolicited_message.is_none() { - break; - } - tracing::trace!(unsolicited_message=?unsolicited_message); - - let unsolicited_message = unsolicited_message.unwrap().unwrap(); - debug!(unsolicited_message = ?unsolicited_message); - let message_wrapper = async_stl_client::messages::Message { - message_type: unsolicited_message.0 as i32, - tx_id: "".to_string(), - content: unsolicited_message.1 - }; - let mut multipart = Multipart::default(); - multipart.push_back(last_address.clone().into()); - - multipart.push_back(tmq::Message::from(prost::Message::encode_to_vec(&message_wrapper))); - router_tx.send(multipart).await.ok(); - }, - complete => { - info!("close embedded router"); - } - } - } - }) - .await - }); - rt.block_on(task).ok(); - }); - - Ok(Self { - ledger: InMemLedger::new( - ZmqRequestResponseSawtoothChannel::new( - &format!("test_{}", Uuid::new_v4()), - &[connect_addr], - HighestBlockValidatorSelector, - )?, - FAMILY, - VERSION, - ), - context, - }) - } - - pub fn new() -> Result { - Self::new_with_state(BTreeMap::new()) - } - - pub fn readable_state(&self) -> Vec<(String, Value)> { - self.context.lock().unwrap().readable_state() - } -} diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index c835fa9d6..119b60f0a 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,53 +1,48 @@ #![cfg_attr(feature = "strict", deny(warnings))] pub mod chronicle_graphql; -pub mod inmem; +pub mod commands; +mod opa; mod persistence; -use async_stl_client::{ - error::SawtoothCommunicationError, - ledger::{BlockId, BlockingLedgerWriter, FromBlock}, -}; -use chronicle_protocol::{ - async_stl_client::ledger::{LedgerReader, LedgerWriter}, - messages::ChronicleSubmitTransaction, - protocol::ChronicleOperationEvent, -}; -use chronicle_signing::{ChronicleSigning, SecretError}; +use chronicle_signing::{ChronicleKnownKeyNamesSigner, ChronicleSigning, SecretError}; use chrono::{DateTime, Utc}; -use diesel::{r2d2::ConnectionManager, PgConnection}; -use diesel_migrations::MigrationHarness; -use futures::{select, FutureExt, StreamExt}; - use common::{ attributes::Attributes, - commands::*, - identity::{AuthId, IdentityError}, - ledger::{Commit, SubmissionError, SubmissionStage, SubscriptionError}, + identity::{AuthId, IdentityError, SignedIdentity}, + ledger::{Commit, SubmissionError, SubmissionStage}, + opa::PolicyAddress, prov::{ + json_ld::ToJson, operations::{ ActivityExists, ActivityUses, ActsOnBehalfOf, AgentExists, ChronicleOperation, CreateNamespace, DerivationType, EndActivity, EntityDerive, EntityExists, SetAttributes, StartActivity, WasAssociatedWith, WasAttributedTo, WasGeneratedBy, WasInformedBy, }, - to_json_ld::ToJson, - ActivityId, AgentId, ChronicleIri, ChronicleTransaction, ChronicleTransactionId, - Contradiction, EntityId, ExternalId, ExternalIdPart, NamespaceId, ProcessorError, - ProvModel, Role, UuidPart, SYSTEM_ID, SYSTEM_UUID, + ActivityId, AgentId, ChronicleIri, ChronicleTransactionId, Contradiction, EntityId, + ExternalId, ExternalIdPart, NamespaceId, ProcessorError, ProvModel, Role, UuidPart, + SYSTEM_ID, SYSTEM_UUID, }, }; +use diesel::{r2d2::ConnectionManager, PgConnection}; +use diesel_migrations::MigrationHarness; +use futures::{select, FutureExt, StreamExt}; use metrics::histogram; use metrics_exporter_prometheus::PrometheusBuilder; pub use persistence::StoreError; use persistence::{Store, MIGRATIONS}; +use protocol_substrate::SubxtClientError; +use protocol_substrate_chronicle::{ + protocol::{BlockId, FromBlock, LedgerReader, LedgerWriter}, + ChronicleEvent, ChronicleTransaction, +}; use r2d2::Pool; use std::{ convert::Infallible, marker::PhantomData, net::AddrParseError, - sync::Arc, time::{Duration, Instant}, }; use thiserror::Error; @@ -56,12 +51,13 @@ use tokio::{ task::JoinError, }; +use commands::*; +pub mod import; +pub use persistence::{database, ConnectionOptions}; use tracing::{debug, error, info, info_span, instrument, trace, warn, Instrument}; -pub use persistence::ConnectionOptions; use user_error::UFE; use uuid::Uuid; - #[derive(Error, Debug)] pub enum ApiError { #[error("Storage: {0:?}")] @@ -76,9 +72,6 @@ pub enum ApiError { #[error("JSON-LD processing: {0}")] JsonLD(String), - #[error("Ledger error: {0}")] - Ledger(#[from] SubmissionError), - #[error("Signing: {0}")] Signing(#[from] SecretError), @@ -106,26 +99,29 @@ pub enum ApiError { #[error("Blocking thread pool: {0}")] Join(#[from] JoinError), - #[error("State update subscription: {0}")] - Subscription(#[from] SubscriptionError), - #[error("No appropriate activity to end")] NotCurrentActivity, - #[error("Contradiction: {0}")] - Contradiction(#[from] Contradiction), - #[error("Processor: {0}")] ProcessorError(#[from] ProcessorError), #[error("Identity: {0}")] IdentityError(#[from] IdentityError), - #[error("Sawtooth communication error: {0}")] - SawtoothCommunicationError(#[from] SawtoothCommunicationError), - #[error("Authentication endpoint error: {0}")] AuthenticationEndpoint(#[from] chronicle_graphql::AuthorizationError), + + #[error("Substrate : {0}")] + ClientError(#[from] SubxtClientError), + + #[error("Submission : {0}")] + Submission(#[from] SubmissionError), + + #[error("Contradiction: {0}")] + Contradiction(Contradiction), + + #[error("Embedded substrate: {0}")] + EmbeddedSubstrate(anyhow::Error), } /// Ugly but we need this until ! is stable, see @@ -135,10 +131,16 @@ impl From for ApiError { } } +impl From for ApiError { + fn from(x: Contradiction) -> Self { + Self::Contradiction(x) + } +} + impl UFE for ApiError {} type LedgerSendWithReply = - (ChronicleSubmitTransaction, Sender>); + (ChronicleTransaction, Sender>); type ApiSendWithReply = ((ApiCommand, AuthId), Sender>); @@ -150,25 +152,27 @@ pub trait UuidGen { pub trait ChronicleSigned { /// Get the user identity's [`SignedIdentity`] - pub fn signed_identity( + fn signed_identity( &self, store: &S, ) -> Result; } -impl ChronicleSigned for Identity { - pub fn signed_identity( +impl ChronicleSigned for AuthId { + fn signed_identity( &self, store: &S, ) -> Result { - let buf = serde_json::to_string(self)?.as_bytes().to_vec(); - - futures::executor::block_on(async move { - SignedIdentity::new( - self, - store.chronicle_sign(&buf).await?, - store.chronicle_verifying().await?, - ) + let signable = self.to_string(); + let signature = futures::executor::block_on(store.chronicle_sign(signable.as_bytes())) + .map_err(|e| IdentityError::Signing(e.into()))?; + let public_key = futures::executor::block_on(store.chronicle_verifying()) + .map_err(|e| IdentityError::Signing(e.into()))?; + + Ok(SignedIdentity { + identity: signable, + signature: signature.into(), + verifying_key: Some(public_key.to_bytes().to_vec()), }) } } @@ -176,19 +180,17 @@ impl ChronicleSigned for Identity { #[derive(Clone)] pub struct Api< U: UuidGen + Send + Sync + Clone, - W: LedgerWriter + W: LedgerWriter + Clone + Send + Sync + 'static, > { - _reply_tx: Sender, submit_tx: tokio::sync::broadcast::Sender, signing: ChronicleSigning, - ledger_writer: Arc>, + ledger_writer: W, store: persistence::Store, uuid_source: PhantomData, - policy_name: Option, } #[derive(Debug, Clone)] @@ -283,12 +285,12 @@ fn install_prometheus_metrics_exporter() { impl Api where U: UuidGen + Send + Sync + Clone + core::fmt::Debug + 'static, - LEDGER: LedgerWriter + LEDGER: LedgerWriter + + LedgerReader + Clone + Send + Sync - + 'static - + LedgerReader, + + 'static, { #[instrument(skip(ledger))] pub async fn new( @@ -297,7 +299,7 @@ where uuidgen: U, signing: ChronicleSigning, namespace_bindings: Vec, - policy_name: Option, + policy_address: Option, liveness_check_interval: Option, ) -> Result { let (commit_tx, mut commit_rx) = mpsc::channel::(10); @@ -335,21 +337,17 @@ where tokio::task::spawn(async move { let mut api = Api:: { - _reply_tx: commit_tx.clone(), submit_tx: commit_notify_tx.clone(), signing, - ledger_writer: Arc::new(BlockingLedgerWriter::new(ledger)), + ledger_writer: ledger, store: store.clone(), uuid_source: PhantomData, - policy_name, }; loop { let state_updates = reuse_reader.clone(); - let state_updates = state_updates - .state_updates("chronicle/prov-update", start_from_block, None) - .await; + let state_updates = state_updates.state_updates(start_from_block, None).await; if let Err(e) = state_updates { error!(subscribe_to_events = ?e); @@ -370,27 +368,27 @@ where } // Ledger contradicted or error, so nothing to // apply, but forward notification - Some((ChronicleOperationEvent(Err(e), id),tx,_block_id,_position, _span)) => { + Some((ChronicleEvent::Contradicted{contradiction,identity,..},tx,_block_id,_position, _span)) => { commit_notify_tx.send(SubmissionStage::not_committed( - ChronicleTransactionId::from(tx.as_str()),e.clone(), id + tx,contradiction, identity )).ok(); }, // Successfully committed to ledger, so apply // to db and broadcast notification to // subscription subscribers - Some((ChronicleOperationEvent(Ok(ref commit), id,),tx,block_id,_position,_span )) => { + Some((ChronicleEvent::Committed{ref diff, ref identity, ..},tx,block_id,_position,_span )) => { debug!(committed = ?tx); - debug!(delta = %serde_json::to_string_pretty(&commit.to_json().compact().await.unwrap()).unwrap()); + debug!(delta = %serde_json::to_string_pretty(&diff.to_json().compact().await.unwrap()).unwrap()); - api.sync( commit.clone().into(), &block_id,ChronicleTransactionId::from(tx.as_str())) - .instrument(info_span!("Incoming confirmation", offset = ?block_id, tx_id = %tx)) + api.sync( diff.clone().into(), &block_id,tx ) + .instrument(info_span!("Incoming confirmation", offset = ?block_id, tx = %tx)) .await .map_err(|e| { error!(?e, "Api sync to confirmed commit"); }).map(|_| commit_notify_tx.send(SubmissionStage::committed(Commit::new( - ChronicleTransactionId::from(tx.as_str()),block_id, Box::new(commit.clone()) - ), id )).ok()) + tx,block_id.to_string(), Box::new(diff.clone()) + ), identity.clone() )).ok()) .ok(); }, } @@ -450,12 +448,11 @@ where }; match stage { - SubmissionStage::Submitted(Ok(id)) => { + SubmissionStage::Submitted(Ok(id)) => if id == tx_id { debug!("Depth charge operation submitted: {id}"); continue; - } - }, + }, SubmissionStage::Submitted(Err(err)) => { if err.tx_id() == &tx_id { error!("Depth charge transaction rejected by Chronicle: {} {}", @@ -510,30 +507,22 @@ where /// This is a measure to keep the api interface stable once this is introduced fn submit_blocking( &mut self, - tx: &ChronicleTransaction, + tx: ChronicleTransaction, ) -> Result { - let res = self.ledger_writer.submit(&ChronicleSubmitTransaction { - tx: tx.clone(), - signer: self.signing.clone(), - policy_name: self.policy_name.clone(), - }); + let (submission, _id) = futures::executor::block_on(self.ledger_writer.pre_submit(tx))?; + let res = futures::executor::block_on(self.ledger_writer.do_submit(submission)); match res { Ok(tx_id) => { - let tx_id = ChronicleTransactionId::from(tx_id.as_str()); self.submit_tx.send(SubmissionStage::submitted(&tx_id)).ok(); Ok(tx_id) }, - Err((Some(tx_id), e)) => { + Err((e, id)) => { // We need the cloneable SubmissionError wrapper here - let submission_error = SubmissionError::communication( - &ChronicleTransactionId::from(tx_id.as_str()), - e, - ); + let submission_error = SubmissionError::communication(&id, e.into()); self.submit_tx.send(SubmissionStage::submitted_error(&submission_error)).ok(); Err(submission_error.into()) }, - Err((None, e)) => Err(e.into()), } } @@ -546,8 +535,10 @@ where to_apply: Vec, ) -> Result { let identity = identity.signed_identity(&self.signing)?; - let model = ProvModel::from_tx(&to_apply)?; - let tx_id = self.submit_blocking(&ChronicleTransaction::new(to_apply, identity))?; + let model = ProvModel::from_tx(&to_apply).map_err(ApiError::Contradiction)?; + let tx_id = self.submit_blocking(futures::executor::block_on( + ChronicleTransaction::new(&self.signing, identity, to_apply), + )?)?; Ok(ApiResponse::submission(id, model, tx_id)) } @@ -568,8 +559,9 @@ where let mut transactions = Vec::::with_capacity(to_apply.len()); for op in to_apply { let mut applied_model = match op { - ChronicleOperation::CreateNamespace(CreateNamespace { external_id, .. }) => { - let (namespace, _) = self.ensure_namespace(connection, external_id)?; + ChronicleOperation::CreateNamespace(CreateNamespace { id, .. }) => { + let (namespace, _) = + self.ensure_namespace(connection, id.external_id_part())?; model.namespace_context(&namespace); model }, @@ -866,14 +858,7 @@ where let uuid = U::uuid(); let id: NamespaceId = NamespaceId::from_external_id(external_id, uuid); - Ok(( - id.clone(), - vec![ChronicleOperation::CreateNamespace(CreateNamespace::new( - id, - external_id, - uuid, - ))], - )) + Ok((id.clone(), vec![ChronicleOperation::CreateNamespace(CreateNamespace::new(id))])) } else { Ok((ns?.0, vec![])) } @@ -1188,9 +1173,13 @@ where ChronicleOperation::StartActivity(StartActivity { namespace: namespace.clone(), id: id.clone(), - time: Utc::now(), + time: Utc::now().into(), + }), + ChronicleOperation::EndActivity(EndActivity { + namespace, + id, + time: Utc::now().into(), }), - ChronicleOperation::EndActivity(EndActivity { namespace, id, time: Utc::now() }), ]; api.submit_depth_charge(identity, to_apply) }) @@ -1203,29 +1192,27 @@ where to_apply: Vec, ) -> Result { let identity = identity.signed_identity(&self.signing)?; - let tx_id = self.submit_blocking(&ChronicleTransaction::new(to_apply, identity))?; + let tx_id = self.submit_blocking(futures::executor::block_on( + ChronicleTransaction::new(&self.signing, identity, to_apply), + )?)?; Ok(ApiResponse::depth_charge_submission(tx_id)) } #[instrument(skip(self))] async fn dispatch(&mut self, command: (ApiCommand, AuthId)) -> Result { match command { - (ApiCommand::DepthCharge(DepthChargeCommand { namespace }), identity) => { - self.depth_charge(namespace, identity).await - }, - (ApiCommand::Import(ImportCommand { namespace, operations }), identity) => { - self.submit_import_operations(identity, namespace, operations).await - }, - (ApiCommand::NameSpace(NamespaceCommand::Create { external_id }), identity) => { - self.create_namespace(&external_id, identity).await - }, + (ApiCommand::DepthCharge(DepthChargeCommand { namespace }), identity) => + self.depth_charge(namespace, identity).await, + (ApiCommand::Import(ImportCommand { namespace, operations }), identity) => + self.submit_import_operations(identity, namespace, operations).await, + (ApiCommand::NameSpace(NamespaceCommand::Create { external_id }), identity) => + self.create_namespace(&external_id, identity).await, ( ApiCommand::Agent(AgentCommand::Create { external_id, namespace, attributes }), identity, ) => self.create_agent(external_id, namespace, attributes, identity).await, - (ApiCommand::Agent(AgentCommand::UseInContext { id, namespace }), _identity) => { - self.use_agent_in_cli_context(id, namespace).await - }, + (ApiCommand::Agent(AgentCommand::UseInContext { id, namespace }), _identity) => + self.use_agent_in_cli_context(id, namespace).await, ( ApiCommand::Agent(AgentCommand::Delegate { id, @@ -1256,9 +1243,8 @@ where ApiCommand::Activity(ActivityCommand::End { id, namespace, time, agent }), identity, ) => self.end_activity(id, namespace, time, agent, identity).await, - (ApiCommand::Activity(ActivityCommand::Use { id, namespace, activity }), identity) => { - self.activity_use(id, namespace, activity, identity).await - }, + (ApiCommand::Activity(ActivityCommand::Use { id, namespace, activity }), identity) => + self.activity_use(id, namespace, activity, identity).await, ( ApiCommand::Activity(ActivityCommand::WasInformedBy { id, @@ -1297,10 +1283,9 @@ where derivation, }), identity, - ) => { + ) => self.entity_derive(id, namespace, activity, used_entity, derivation, identity) - .await - }, + .await, (ApiCommand::Query(query), _identity) => self.query(query).await, } } @@ -1491,16 +1476,16 @@ where let mut api = self.clone(); let identity = identity.signed_identity(&self.signing)?; let model = ProvModel::from_tx(&operations)?; + let signer = self.signing.clone(); tokio::task::spawn_blocking(move || { // Check here to ensure that import operations result in data changes let mut connection = api.store.connection()?; connection.build_transaction().run(|connection| { if let Some(operations_to_apply) = api.check_for_effects(connection, &operations)? { info!("Submitting import operations to ledger"); - let tx_id = api.submit_blocking(&ChronicleTransaction::new( - operations_to_apply, - identity, - ))?; + let tx_id = api.submit_blocking(futures::executor::block_on( + ChronicleTransaction::new(&signer, identity, operations_to_apply), + )?)?; Ok(ApiResponse::import_submitted(model, tx_id)) } else { info!("Import will not result in any data changes"); @@ -1563,13 +1548,13 @@ where to_apply.push(ChronicleOperation::StartActivity(StartActivity { namespace: namespace.clone(), id: id.clone(), - time: time.unwrap_or_else(Utc::now), + time: time.unwrap_or_else(Utc::now).into(), })); to_apply.push(ChronicleOperation::EndActivity(EndActivity { namespace: namespace.clone(), id: id.clone(), - time: time.unwrap_or_else(Utc::now), + time: time.unwrap_or_else(Utc::now).into(), })); if let Some(agent_id) = agent_id { @@ -1623,7 +1608,7 @@ where to_apply.push(ChronicleOperation::StartActivity(StartActivity { namespace: namespace.clone(), id: id.clone(), - time: time.unwrap_or_else(Utc::now), + time: time.unwrap_or_else(Utc::now).into(), })); if let Some(agent_id) = agent_id { @@ -1677,7 +1662,7 @@ where to_apply.push(ChronicleOperation::EndActivity(EndActivity { namespace: namespace.clone(), id: id.clone(), - time: time.unwrap_or_else(Utc::now), + time: time.unwrap_or_else(Utc::now).into(), })); if let Some(agent_id) = agent_id { @@ -1717,1651 +1702,3 @@ where .await? } } - -#[cfg(test)] -mod test { - - use crate::{inmem::EmbeddedChronicleTp, Api, ApiDispatch, ApiError, UuidGen}; - - use chronicle_signing::{ - chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, - CHRONICLE_NAMESPACE, - }; - use chrono::{TimeZone, Utc}; - use common::{ - attributes::{Attribute, Attributes}, - commands::{ - ActivityCommand, AgentCommand, ApiCommand, ApiResponse, EntityCommand, ImportCommand, - NamespaceCommand, - }, - database::TemporaryDatabase, - identity::AuthId, - k256::sha2::{Digest, Sha256}, - prov::{ - operations::{ChronicleOperation, DerivationType}, - to_json_ld::ToJson, - ActivityId, AgentId, ChronicleTransactionId, DomaintypeId, EntityId, NamespaceId, - ProvModel, - }, - }; - use opa_tp_protocol::state::{policy_address, policy_meta_address, PolicyMeta}; - use protobuf::Message; - use sawtooth_sdk::messages::setting::{Setting, Setting_Entry}; - - use uuid::Uuid; - - struct TestDispatch<'a> { - api: ApiDispatch, - _db: TemporaryDatabase<'a>, // share lifetime - _tp: EmbeddedChronicleTp, - } - - impl<'a> TestDispatch<'a> { - pub async fn dispatch( - &mut self, - command: ApiCommand, - identity: AuthId, - ) -> Result, ChronicleTransactionId)>, ApiError> { - // We can sort of get final on chain state here by using a map of subject to model - match self.api.dispatch(command, identity).await? { - ApiResponse::Submission { .. } | ApiResponse::ImportSubmitted { .. } => { - // Recv until we get a commit notification - loop { - let commit = self.api.notify_commit.subscribe().recv().await.unwrap(); - match commit { - common::ledger::SubmissionStage::Submitted(Ok(_)) => continue, - common::ledger::SubmissionStage::Committed(commit, _id) => { - return Ok(Some((commit.delta, commit.tx_id))) - }, - common::ledger::SubmissionStage::Submitted(Err(e)) => panic!("{e:?}"), - common::ledger::SubmissionStage::NotCommitted((_, tx, _id)) => { - panic!("{tx:?}") - }, - } - } - }, - ApiResponse::AlreadyRecorded { subject: _, prov } => { - Ok(Some((prov, ChronicleTransactionId::from("null")))) - }, - _ => Ok(None), - } - } - } - - #[derive(Debug, Clone)] - struct SameUuid; - - impl UuidGen for SameUuid { - fn uuid() -> Uuid { - Uuid::parse_str("5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea").unwrap() - } - } - - fn embed_chronicle_tp() -> EmbeddedChronicleTp { - chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); - let mut buf = vec![]; - Setting { - entries: vec![Setting_Entry { - key: "chronicle.opa.policy_name".to_string(), - value: "allow_transactions".to_string(), - ..Default::default() - }] - .into(), - ..Default::default() - } - .write_to_vec(&mut buf) - .unwrap(); - let setting_id = ( - chronicle_protocol::settings::sawtooth_settings_address("chronicle.opa.policy_name"), - buf, - ); - let mut buf = vec![]; - Setting { - entries: vec![Setting_Entry { - key: "chronicle.opa.entrypoint".to_string(), - value: "allow_transactions.allowed_users".to_string(), - ..Default::default() - }] - .into(), - ..Default::default() - } - .write_to_vec(&mut buf) - .unwrap(); - - let setting_entrypoint = ( - chronicle_protocol::settings::sawtooth_settings_address("chronicle.opa.entrypoint"), - buf, - ); - - let d = env!("CARGO_MANIFEST_DIR").to_owned() + "/../../policies/bundle.tar.gz"; - let bin = std::fs::read(d).unwrap(); - - let meta = PolicyMeta { - id: "allow_transactions".to_string(), - hash: hex::encode(Sha256::digest(&bin)), - policy_address: policy_address("allow_transactions"), - }; - - EmbeddedChronicleTp::new_with_state( - vec![ - setting_id, - setting_entrypoint, - (policy_address("allow_transactions"), bin), - (policy_meta_address("allow_transactions"), serde_json::to_vec(&meta).unwrap()), - ] - .into_iter() - .collect(), - ) - .unwrap() - } - - async fn test_api<'a>() -> TestDispatch<'a> { - chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); - - let secrets = ChronicleSigning::new( - chronicle_secret_names(), - vec![ - (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), - (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), - ], - ) - .await - .unwrap(); - let embed_tp = embed_chronicle_tp(); - let database = TemporaryDatabase::default(); - let pool = database.connection_pool().unwrap(); - - let liveness_check_interval = None; - - let dispatch = Api::new( - pool, - embed_tp.ledger.clone(), - SameUuid, - secrets, - vec![], - Some("allow_transactions".into()), - liveness_check_interval, - ) - .await - .unwrap(); - - TestDispatch { - api: dispatch, - _db: database, // share the lifetime - _tp: embed_tp, - } - } - - // Creates a mock file containing JSON-LD of the ChronicleOperations - // that would be created by the given command, although not in any particular order. - fn test_create_agent_operations_import() -> assert_fs::NamedTempFile { - let file = assert_fs::NamedTempFile::new("import.json").unwrap(); - assert_fs::prelude::FileWriteStr::write_str( - &file, - r#" - [ - { - "@id": "_:n1", - "@type": [ - "http://btp.works/chronicleoperations/ns#SetAttributes" - ], - "http://btp.works/chronicleoperations/ns#agentName": [ - { - "@value": "testagent" - } - ], - "http://btp.works/chronicleoperations/ns#attributes": [ - { - "@type": "@json", - "@value": {} - } - ], - "http://btp.works/chronicleoperations/ns#domaintypeId": [ - { - "@value": "type" - } - ], - "http://btp.works/chronicleoperations/ns#namespaceName": [ - { - "@value": "testns" - } - ], - "http://btp.works/chronicleoperations/ns#namespaceUuid": [ - { - "@value": "6803790d-5891-4dfa-b773-41827d2c630b" - } - ] - }, - { - "@id": "_:n1", - "@type": [ - "http://btp.works/chronicleoperations/ns#CreateNamespace" - ], - "http://btp.works/chronicleoperations/ns#namespaceName": [ - { - "@value": "testns" - } - ], - "http://btp.works/chronicleoperations/ns#namespaceUuid": [ - { - "@value": "6803790d-5891-4dfa-b773-41827d2c630b" - } - ] - }, - { - "@id": "_:n1", - "@type": [ - "http://btp.works/chronicleoperations/ns#AgentExists" - ], - "http://btp.works/chronicleoperations/ns#agentName": [ - { - "@value": "testagent" - } - ], - "http://btp.works/chronicleoperations/ns#namespaceName": [ - { - "@value": "testns" - } - ], - "http://btp.works/chronicleoperations/ns#namespaceUuid": [ - { - "@value": "6803790d-5891-4dfa-b773-41827d2c630b" - } - ] - } - ] - "#, - ) - .unwrap(); - file - } - - #[tokio::test] - async fn test_import_operations() { - let mut api = test_api().await; - - let file = test_create_agent_operations_import(); - - let contents = std::fs::read_to_string(file.path()).unwrap(); - - let json_array = serde_json::from_str::>(&contents).unwrap(); - - let mut operations = Vec::with_capacity(json_array.len()); - for value in json_array.into_iter() { - let op = ChronicleOperation::from_json(&value) - .await - .expect("Failed to parse imported JSON-LD to ChronicleOperation"); - operations.push(op); - } - - let namespace = NamespaceId::from_external_id( - "testns", - Uuid::parse_str("6803790d-5891-4dfa-b773-41827d2c630b").unwrap(), - ); - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!(api - .dispatch(ApiCommand::Import(ImportCommand { namespace: namespace.clone(), operations: operations.clone() } ), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:type" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:6803790d-5891-4dfa-b773-41827d2c630b", - "value": {} - }, - { - "@id": "chronicle:ns:testns:6803790d-5891-4dfa-b773-41827d2c630b", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - // Check that the operations that do not result in data changes are not submitted - insta::assert_json_snapshot!(api - .dispatch(ApiCommand::Import(ImportCommand { namespace, operations } ), identity) - .await - .unwrap() - .unwrap() - .1, @r###""null""###); - } - - #[tokio::test] - async fn create_namespace() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!(api - .dispatch(ApiCommand::NameSpace(NamespaceCommand::Create { - external_id: "testns".into(), - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - "###); - } - - #[tokio::test] - async fn create_agent() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!(api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn create_system_activity() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!(api.dispatch(ApiCommand::Activity(ActivityCommand::Create { - external_id: "testactivity".into(), - namespace: common::prov::SYSTEM_ID.into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:test" - ], - "externalId": "testactivity", - "namespace": "chronicle:ns:chronicle%2Dsystem:00000000-0000-0000-0000-000000000001", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:chronicle%2Dsystem:00000000-0000-0000-0000-000000000001", - "@type": "chronicle:Namespace", - "externalId": "chronicle-system" - } - ] - } - "###); - } - - #[tokio::test] - async fn create_activity() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!(api.dispatch(ApiCommand::Activity(ActivityCommand::Create { - external_id: "testactivity".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:test" - ], - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn start_activity() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - api.dispatch( - ApiCommand::Agent(AgentCommand::UseInContext { - id: AgentId::from_external_id("testagent"), - namespace: "testns".into(), - }), - identity.clone(), - ) - .await - .unwrap(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Start { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "startTime": "2014-07-08T09:10:11+00:00", - "value": {}, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn contradict_attributes() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - let res = api - .dispatch( - ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test2".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), - identity, - ) - .await; - - insta::assert_snapshot!(res.err().unwrap().to_string(), @r###"Contradiction: Contradiction { attribute value change: test Attribute { typ: "test", value: String("test2") } Attribute { typ: "test", value: String("test") } }"###); - } - - #[tokio::test] - async fn contradict_start_time() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - api.dispatch( - ApiCommand::Agent(AgentCommand::UseInContext { - id: AgentId::from_external_id("testagent"), - namespace: "testns".into(), - }), - identity.clone(), - ) - .await - .unwrap(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Start { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "startTime": "2014-07-08T09:10:11+00:00", - "value": {}, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - // Should contradict - let res = api - .dispatch( - ApiCommand::Activity(ActivityCommand::Start { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2018, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), - identity, - ) - .await; - - insta::assert_snapshot!(res.err().unwrap().to_string(), @"Contradiction: Contradiction { start date alteration: 2014-07-08 09:10:11 UTC 2018-07-08 09:10:11 UTC }"); - } - - #[tokio::test] - async fn contradict_end_time() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - api.dispatch( - ApiCommand::Agent(AgentCommand::UseInContext { - id: AgentId::from_external_id("testagent"), - namespace: "testns".into(), - }), - identity.clone(), - ) - .await - .unwrap(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::End { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2018, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "endTime": "2018-07-08T09:10:11+00:00", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "value": {}, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - // Should contradict - let res = api - .dispatch( - ApiCommand::Activity(ActivityCommand::End { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2022, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), - identity, - ) - .await; - - insta::assert_snapshot!(res.err().unwrap().to_string(), @"Contradiction: Contradiction { end date alteration: 2018-07-08 09:10:11 UTC 2022-07-08 09:10:11 UTC }"); - } - - #[tokio::test] - async fn end_activity() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - api.dispatch( - ApiCommand::Agent(AgentCommand::UseInContext { - id: AgentId::from_external_id("testagent"), - namespace: "testns".into(), - }), - identity.clone(), - ) - .await - .unwrap(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Start { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "startTime": "2014-07-08T09:10:11+00:00", - "value": {}, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::End { - - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), - agent: None, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "endTime": "2014-07-08T09:10:11+00:00", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "startTime": "2014-07-08T09:10:11+00:00", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_use() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Agent(AgentCommand::Create { - external_id: "testagent".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:test" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - api.dispatch( - ApiCommand::Agent(AgentCommand::UseInContext { - id: AgentId::from_external_id("testagent"), - namespace: "testns".into(), - }), - identity.clone(), - ) - .await - .unwrap(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Create { - external_id: "testactivity".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:test" - ], - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Use { - id: EntityId::from_external_id("testentity"), - namespace: "testns".into(), - activity: ActivityId::from_external_id("testactivity"), - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:test" - ], - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "used": [ - "chronicle:entity:testentity" - ], - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:entity:testentity", - "@type": "prov:Entity", - "externalId": "testentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::End { - id: ActivityId::from_external_id("testactivity"), - namespace: "testns".into(), - time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), - agent: Some(AgentId::from_external_id("testagent")), - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:test" - ], - "endTime": "2014-07-08T09:10:11+00:00", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "used": [ - "chronicle:entity:testentity" - ], - "value": { - "test": "test" - }, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_generate() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Create { - external_id: "testactivity".into(), - namespace: "testns".into(), - attributes: Attributes { - typ: Some(DomaintypeId::from_external_id("test")), - attributes: [( - "test".to_owned(), - Attribute { - typ: "test".to_owned(), - value: serde_json::Value::String("test".to_owned()), - }, - )] - .into_iter() - .collect(), - }, - }), identity.clone()) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:test" - ], - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "test": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Activity(ActivityCommand::Generate { - id: EntityId::from_external_id("testentity"), - namespace: "testns".into(), - activity: ActivityId::from_external_id("testactivity"), - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testentity", - "@type": "prov:Entity", - "externalId": "testentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasGeneratedBy": [ - "chronicle:activity:testactivity" - ] - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn derive_entity_abstract() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Entity(EntityCommand::Derive { - id: EntityId::from_external_id("testgeneratedentity"), - namespace: "testns".into(), - activity: None, - used_entity: EntityId::from_external_id("testusedentity"), - derivation: DerivationType::None, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasDerivedFrom": [ - "chronicle:entity:testusedentity" - ] - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn derive_entity_primary_source() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Entity(EntityCommand::Derive { - id: EntityId::from_external_id("testgeneratedentity"), - namespace: "testns".into(), - activity: None, - derivation: DerivationType::PrimarySource, - used_entity: EntityId::from_external_id("testusedentity"), - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "hadPrimarySource": [ - "chronicle:entity:testusedentity" - ], - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn derive_entity_revision() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Entity(EntityCommand::Derive { - id: EntityId::from_external_id("testgeneratedentity"), - namespace: "testns".into(), - activity: None, - used_entity: EntityId::from_external_id("testusedentity"), - derivation: DerivationType::Revision, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasRevisionOf": [ - "chronicle:entity:testusedentity" - ] - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn derive_entity_quotation() { - let mut api = test_api().await; - - let identity = AuthId::chronicle(); - - insta::assert_json_snapshot!( - api.dispatch(ApiCommand::Entity(EntityCommand::Derive { - id: EntityId::from_external_id("testgeneratedentity"), - namespace: "testns".into(), - activity: None, - used_entity: EntityId::from_external_id("testusedentity"), - derivation: DerivationType::Quotation, - }), identity) - .await - .unwrap() - .unwrap() - .0 - .to_json() - .compact_stable_order() - .await - .unwrap(), @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasQuotedFrom": [ - "chronicle:entity:testusedentity" - ] - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } -} diff --git a/crates/api/src/opa.rs b/crates/api/src/opa.rs index 39ef0ad8f..8b1378917 100644 --- a/crates/api/src/opa.rs +++ b/crates/api/src/opa.rs @@ -1,157 +1 @@ -use crate::{ - identity::{AuthId, IdentityError, OpaData}, - import::FromUrlError, -}; -use futures::lock::Mutex; -use opa::{bundle::Bundle, wasm::Opa}; -#[cfg(not(feature = "std"))] -use parity_scale_codec::alloc::sync::Arc; -#[cfg(feature = "std")] -use std::sync::Arc; - -use rust_embed::RustEmbed; -use thiserror::Error; -use tracing::{error, instrument}; - -#[derive(Debug, Error)] -pub enum PolicyLoaderError { - #[error("Failed to read embedded OPA policies")] - EmbeddedOpaPolicies, - - #[error("Policy not found: {0}")] - MissingPolicy(String), - - #[error("OPA bundle I/O error: {0}")] - OpaBundleError(#[from] opa::bundle::Error), - - #[error("Error loading OPA policy: {0}")] - SawtoothCommunicationError(#[from] anyhow::Error), - - #[error("Error loading policy bundle from URL: {0}")] - UrlError(#[from] FromUrlError), -} - -#[async_trait::async_trait] -pub trait PolicyLoader { - /// Set address of OPA policy - fn set_address(&mut self, address: &str); - - /// Set OPA policy - fn set_rule_name(&mut self, policy: &str); - - /// Set entrypoint for OPA policy - fn set_entrypoint(&mut self, entrypoint: &str); - - fn get_address(&self) -> &str; - - fn get_rule_name(&self) -> &str; - - fn get_entrypoint(&self) -> &str; - - fn get_policy(&self) -> &[u8]; - - /// Load OPA policy from address set in `PolicyLoader` - async fn load_policy(&mut self) -> Result<(), PolicyLoaderError>; - - /// Load OPA policy from provided bytes - fn load_policy_from_bytes(&mut self, policy: &[u8]); - - /// Return a built OPA instance from the cached policy - #[instrument(level = "trace", skip(self), ret)] - fn build_opa(&self) -> Result { - Ok(Opa::new().build(self.get_policy())?) - } - - /// Load OPA policy from provided policy bundle - fn load_policy_from_bundle(&mut self, bundle: &Bundle) -> Result<(), PolicyLoaderError> { - let rule = self.get_rule_name(); - self.load_policy_from_bytes( - bundle - .wasm_policies - .iter() - .find(|p| p.entrypoint == rule) - .map(|p| p.bytes.as_ref()) - .ok_or(PolicyLoaderError::MissingPolicy(rule.to_string()))?, - ); - Ok(()) - } - - fn hash(&self) -> String; -} - -#[derive(Debug, Error)] -pub enum OpaExecutorError { - #[error("Access denied")] - AccessDenied, - - #[error("Identity error: {0}")] - IdentityError(#[from] IdentityError), - - #[error("Error loading OPA policy: {0}")] - PolicyLoaderError(#[from] PolicyLoaderError), - - #[error("Error evaluating OPA policy: {0}")] - OpaEvaluationError(#[from] anyhow::Error), -} - -#[async_trait::async_trait] -pub trait OpaExecutor { - /// Evaluate the loaded OPA instance against the provided identity and context - async fn evaluate(&mut self, id: &AuthId, context: &OpaData) -> Result<(), OpaExecutorError>; -} - -#[derive(Clone, Debug)] -pub struct ExecutorContext { - executor: Arc>, - hash: String, -} - -impl ExecutorContext { - #[instrument(skip(self), level = "trace", ret(Debug))] - pub async fn evaluate(&self, id: &AuthId, context: &OpaData) -> Result<(), OpaExecutorError> { - self.executor.lock().await.evaluate(id, context).await - } - - pub fn from_loader(loader: &L) -> Result { - Ok(Self { - executor: Arc::new(Mutex::new(WasmtimeOpaExecutor::from_loader(loader)?)), - hash: loader.hash(), - }) - } - - pub fn hash(&self) -> &str { - &self.hash - } -} - -#[derive(Debug)] -pub struct WasmtimeOpaExecutor { - opa: Opa, - entrypoint: String, -} - -impl WasmtimeOpaExecutor { - /// Build a `WasmtimeOpaExecutor` from the `PolicyLoader` provided - pub fn from_loader(loader: &L) -> Result { - Ok(Self { opa: loader.build_opa()?, entrypoint: loader.get_entrypoint().to_owned() }) - } -} - -#[async_trait::async_trait] -impl OpaExecutor for WasmtimeOpaExecutor { - #[instrument(level = "trace", skip(self))] - async fn evaluate(&mut self, id: &AuthId, context: &OpaData) -> Result<(), OpaExecutorError> { - self.opa.set_data(context)?; - let input = id.identity()?; - match self.opa.eval(&self.entrypoint, &input)? { - true => Ok(()), - false => Err(OpaExecutorError::AccessDenied), - } - } -} - -#[derive(RustEmbed)] -#[folder = "../../policies"] -#[include = "bundle.tar.gz"] -struct EmbeddedOpaPolicies; diff --git a/crates/api/src/persistence/database.rs b/crates/api/src/persistence/database.rs index b371beadf..97e505c25 100644 --- a/crates/api/src/persistence/database.rs +++ b/crates/api/src/persistence/database.rs @@ -1,42 +1,7 @@ -use diesel::{r2d2::ConnectionManager, Connection, PgConnection}; -use lazy_static::lazy_static; +use diesel::{r2d2::ConnectionManager, PgConnection}; + use r2d2::Pool; use std::{fmt::Display, time::Duration}; -use testcontainers::{clients::Cli, images::postgres::Postgres, Container}; - -lazy_static! { - static ref CLIENT: Cli = Cli::default(); -} - -pub struct TemporaryDatabase<'a> { - db_uris: Vec, - _container: Container<'a, Postgres>, -} - -impl<'a> TemporaryDatabase<'a> { - pub fn connection_pool(&self) -> Result>, r2d2::Error> { - let db_uri = self - .db_uris - .iter() - .find(|db_uri| PgConnection::establish(db_uri).is_ok()) - .expect("cannot establish connection"); - Pool::builder().build(ConnectionManager::::new(db_uri)) - } -} - -impl<'a> Default for TemporaryDatabase<'a> { - fn default() -> Self { - let container = CLIENT.run(Postgres::default()); - const PORT: u16 = 5432; - Self { - db_uris: vec![ - format!("postgresql://postgres@127.0.0.1:{}/", container.get_host_port_ipv4(PORT)), - format!("postgresql://postgres@{}:{}/", container.get_bridge_ip_address(), PORT), - ], - _container: container, - } - } -} #[async_trait::async_trait] pub trait DatabaseConnector { diff --git a/crates/api/src/persistence/mod.rs b/crates/api/src/persistence/mod.rs index 0e363446d..8f85a8083 100644 --- a/crates/api/src/persistence/mod.rs +++ b/crates/api/src/persistence/mod.rs @@ -1,6 +1,4 @@ -use std::{collections::BTreeMap, str::FromStr, time::Duration}; - -use async_stl_client::ledger::{BlockId, BlockIdError}; +use std::{collections::BTreeMap, str::FromStr, sync::Arc, time::Duration}; use chrono::{TimeZone, Utc}; use common::{ @@ -8,8 +6,8 @@ use common::{ prov::{ operations::DerivationType, Activity, ActivityId, Agent, AgentId, Association, Attribution, ChronicleTransactionId, ChronicleTransactionIdError, Delegation, Derivation, DomaintypeId, - Entity, EntityId, ExternalId, ExternalIdPart, Generation, Identity, IdentityId, Namespace, - NamespaceId, ProvModel, PublicKeyPart, Role, Usage, + Entity, EntityId, ExternalId, ExternalIdPart, Generation, Namespace, NamespaceId, + ProvModel, Role, Usage, }, }; use derivative::*; @@ -20,9 +18,11 @@ use diesel::{ PgConnection, }; use diesel_migrations::{embed_migrations, EmbeddedMigrations}; +use protocol_substrate_chronicle::protocol::{BlockId, BlockIdError}; use thiserror::Error; use tracing::{debug, instrument, warn}; use uuid::Uuid; +pub mod database; mod query; pub(crate) mod schema; @@ -117,10 +117,10 @@ impl Store { &self, connection: &mut PgConnection, external_id: &ExternalId, - namespaceid: &NamespaceId, + namespace_id: &NamespaceId, ) -> Result { let (_namespaceid, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; + self.namespace_by_external_id(connection, namespace_id.external_id_part())?; use schema::activity::dsl; Ok(schema::activity::table @@ -149,10 +149,10 @@ impl Store { &self, connection: &mut PgConnection, external_id: &ExternalId, - namespaceid: &NamespaceId, + namespace_id: &NamespaceId, ) -> Result { let (_namespaceid, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; + self.namespace_by_external_id(connection, namespace_id.external_id_part())?; use schema::agent::dsl; Ok(schema::agent::table @@ -167,27 +167,21 @@ impl Store { &self, connection: &mut PgConnection, Activity { - ref external_id, - namespaceid, - started, - ended, - domaintypeid, - attributes, - .. - }: &Activity, - ns: &BTreeMap, + ref external_id, namespace_id, started, ended, domaintype_id, attributes, .. + }: &Activity, + ns: &BTreeMap>, ) -> Result<(), StoreError> { use schema::activity as dsl; - let _namespace = ns.get(namespaceid).ok_or(StoreError::InvalidNamespace {})?; + let _namespace = ns.get(namespace_id).ok_or(StoreError::InvalidNamespace {})?; let (_, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; + self.namespace_by_external_id(connection, namespace_id.external_id_part())?; let existing = self - .activity_by_activity_external_id_and_namespace(connection, external_id, namespaceid) + .activity_by_activity_external_id_and_namespace(connection, external_id, namespace_id) .ok(); let resolved_domain_type = - domaintypeid.as_ref().map(|x| x.external_id_part().clone()).or_else(|| { + domaintype_id.as_ref().map(|x| x.external_id_part().clone()).or_else(|| { existing.as_ref().and_then(|x| x.domaintype.as_ref().map(ExternalId::from)) }); @@ -204,7 +198,7 @@ impl Store { dsl::namespace_id.eq(nsid), dsl::started.eq(started.map(|t| t.naive_utc())), dsl::ended.eq(ended.map(|t| t.naive_utc())), - dsl::domaintype.eq(domaintypeid.as_ref().map(|x| x.external_id_part())), + dsl::domaintype.eq(domaintype_id.as_ref().map(|x| x.external_id_part())), )) .on_conflict((dsl::external_id, dsl::namespace_id)) .do_update() @@ -218,7 +212,7 @@ impl Store { let query::Activity { id, .. } = self.activity_by_activity_external_id_and_namespace( connection, external_id, - namespaceid, + namespace_id, )?; diesel::insert_into(schema::activity_attribute::table) @@ -246,7 +240,7 @@ impl Store { &self, connection: &mut PgConnection, Agent { ref external_id, namespaceid, domaintypeid, attributes, .. }: &Agent, - ns: &BTreeMap, + ns: &BTreeMap>, ) -> Result<(), StoreError> { use schema::agent::dsl; let _namespace = ns.get(namespaceid).ok_or(StoreError::InvalidNamespace {})?; @@ -298,16 +292,16 @@ impl Store { fn apply_entity( &self, connection: &mut PgConnection, - Entity { namespaceid, id, external_id, domaintypeid, attributes }: &Entity, - ns: &BTreeMap, + Entity { namespace_id, id, external_id, domaintypeid, attributes }: &Entity, + ns: &BTreeMap>, ) -> Result<(), StoreError> { use schema::entity::dsl; - let _namespace = ns.get(namespaceid).ok_or(StoreError::InvalidNamespace {})?; + let _namespace = ns.get(namespace_id).ok_or(StoreError::InvalidNamespace {})?; let (_, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; + self.namespace_by_external_id(connection, namespace_id.external_id_part())?; let existing = self - .entity_by_entity_external_id_and_namespace(connection, external_id, namespaceid) + .entity_by_entity_external_id_and_namespace(connection, external_id, namespace_id) .ok(); let resolved_domain_type = @@ -327,7 +321,7 @@ impl Store { .execute(connection)?; let query::Entity { id, .. } = - self.entity_by_entity_external_id_and_namespace(connection, external_id, namespaceid)?; + self.entity_by_entity_external_id_and_namespace(connection, external_id, namespace_id)?; diesel::insert_into(schema::entity_attribute::table) .values( @@ -346,73 +340,6 @@ impl Store { Ok(()) } - #[instrument(level = "trace", skip(self, connection), ret(Debug))] - fn apply_has_identity( - &self, - connection: &mut PgConnection, - model: &ProvModel, - namespaceid: &NamespaceId, - agent: &AgentId, - identity: &IdentityId, - ) -> Result<(), StoreError> { - let (_, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; - let identity = self.identity_by(connection, namespaceid, identity)?; - use schema::agent::dsl; - - diesel::update(schema::agent::table) - .filter(dsl::external_id.eq(agent.external_id_part()).and(dsl::namespace_id.eq(nsid))) - .set(dsl::identity_id.eq(identity.id)) - .execute(connection)?; - - Ok(()) - } - - #[instrument(level = "trace", skip(self, connection), ret(Debug))] - fn apply_had_identity( - &self, - connection: &mut PgConnection, - model: &ProvModel, - namespaceid: &NamespaceId, - agent: &AgentId, - identity: &IdentityId, - ) -> Result<(), StoreError> { - let identity = self.identity_by(connection, namespaceid, identity)?; - let agent = self.agent_by_agent_external_id_and_namespace( - connection, - agent.external_id_part(), - namespaceid, - )?; - use schema::hadidentity::dsl; - - diesel::insert_into(schema::hadidentity::table) - .values((dsl::agent_id.eq(agent.id), dsl::identity_id.eq(identity.id))) - .on_conflict_do_nothing() - .execute(connection)?; - - Ok(()) - } - - #[instrument(level = "trace", skip(self, connection), ret(Debug))] - fn apply_identity( - &self, - connection: &mut PgConnection, - Identity { id, namespaceid, public_key, .. }: &Identity, - ns: &BTreeMap, - ) -> Result<(), StoreError> { - use schema::identity::dsl; - let _namespace = ns.get(namespaceid).ok_or(StoreError::InvalidNamespace {})?; - let (_, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; - - diesel::insert_into(schema::identity::table) - .values((dsl::namespace_id.eq(nsid), dsl::public_key.eq(public_key))) - .on_conflict_do_nothing() - .execute(connection)?; - - Ok(()) - } - fn apply_model( &self, connection: &mut PgConnection, @@ -430,19 +357,6 @@ impl Store { for (_, entity) in model.entities.iter() { self.apply_entity(connection, entity, &model.namespaces)? } - for (_, identity) in model.identities.iter() { - self.apply_identity(connection, identity, &model.namespaces)? - } - - for ((namespaceid, agent_id), (_, identity_id)) in model.has_identity.iter() { - self.apply_has_identity(connection, model, namespaceid, agent_id, identity_id)?; - } - - for ((namespaceid, agent_id), identity_id) in model.had_identity.iter() { - for (_, identity_id) in identity_id { - self.apply_had_identity(connection, model, namespaceid, agent_id, identity_id)?; - } - } for ((namespaceid, _), association) in model.association.iter() { for association in association.iter() { @@ -502,7 +416,7 @@ impl Store { ) -> Result<(), StoreError> { use schema::namespace::dsl; diesel::insert_into(schema::namespace::table) - .values((dsl::external_id.eq(external_id), dsl::uuid.eq(uuid.to_string()))) + .values((dsl::external_id.eq(external_id), dsl::uuid.eq(hex::encode(uuid)))) .on_conflict_do_nothing() .execute(connection)?; @@ -800,7 +714,7 @@ impl Store { .map_err(StoreError::from)?; if let Some(block_id) = block_id_and_tx.0 { - Ok(Some(BlockId::try_from(block_id)?)) + Ok(Some(BlockId::try_from(&*block_id)?)) } else { Ok(None) } @@ -825,23 +739,6 @@ impl Store { Ok((NamespaceId::from_external_id(ns.1, Uuid::from_str(&ns.2)?), ns.0)) } - #[instrument(skip(connection))] - pub(crate) fn identity_by( - &self, - connection: &mut PgConnection, - namespaceid: &NamespaceId, - identity: &IdentityId, - ) -> Result { - use self::schema::identity::dsl; - let (_, nsid) = - self.namespace_by_external_id(connection, namespaceid.external_id_part())?; - let public_key = identity.public_key_part(); - - Ok(dsl::identity - .filter(dsl::public_key.eq(public_key).and(dsl::namespace_id.eq(nsid))) - .first::(connection)?) - } - #[instrument] pub(crate) fn new(pool: Pool>) -> Result { Ok(Store { pool }) @@ -876,7 +773,8 @@ impl Store { }) }) .collect::, _>>()?, - }, + } + .into(), ); for (responsible, activity, role) in schema::delegation::table @@ -938,11 +836,11 @@ impl Store { (namespaceid.clone(), id.clone()), Activity { id: id.clone(), - namespaceid: namespaceid.clone(), + namespace_id: namespaceid.clone(), external_id: activity.external_id.into(), - started: activity.started.map(|x| Utc.from_utc_datetime(&x)), - ended: activity.ended.map(|x| Utc.from_utc_datetime(&x)), - domaintypeid: activity.domaintype.map(DomaintypeId::from_external_id), + started: activity.started.map(|x| Utc.from_utc_datetime(&x).into()), + ended: activity.ended.map(|x| Utc.from_utc_datetime(&x).into()), + domaintype_id: activity.domaintype.map(DomaintypeId::from_external_id), attributes: attributes .into_iter() .map(|attr| { @@ -951,7 +849,8 @@ impl Store { }) }) .collect::, _>>()?, - }, + } + .into(), ); for generation in schema::generation::table @@ -1055,7 +954,7 @@ impl Store { (namespace_id.clone(), entity_id.clone()), Entity { id: entity_id.clone(), - namespaceid: namespace_id.clone(), + namespace_id: namespace_id.clone(), external_id: external_id.into(), domaintypeid: domaintype.map(DomaintypeId::from_external_id), attributes: attributes @@ -1066,7 +965,8 @@ impl Store { }) }) .collect::, _>>()?, - }, + } + .into(), ); for (activity_id, activity_external_id, used_entity_id, typ) in schema::derivation::table diff --git a/crates/chronicle-domain-test/Cargo.toml b/crates/chronicle-domain-test/Cargo.toml index 4500bf4b4..b1a3cf205 100644 --- a/crates/chronicle-domain-test/Cargo.toml +++ b/crates/chronicle-domain-test/Cargo.toml @@ -22,16 +22,19 @@ uuid = { workspace = true } chronicle = { path = "../chronicle" } [features] -devmode = ["inmem"] -strict = [] +strict = [] # Use an in-memory stub ledger -inmem = ["chronicle/inmem"] +devmode = ["chronicle/devmode"] [dev-dependencies] -async-stl-client = { workspace = true } -chronicle-protocol = { path = "../chronicle-protocol" } -futures = { workspace = true } -hex = { workspace = true } -insta = { workspace = true, features = ["json"] } -opa-tp-protocol = { path = "../opa-tp-protocol" } -tempfile = { workspace = true } +chronicle-test-infrastructure = { path = "../chronicle-test-infrastructure" } +common = { path = "../common", features = ["std"] } +embedded-substrate = { path = "../embedded-substrate" } +futures = { workspace = true } +hex = { workspace = true } +insta = { workspace = true, features = ["json"] } +protocol-substrate = { path = "../protocol-substrate" } +protocol-substrate-chronicle = { path = "../protocol-substrate-chronicle" } +protocol-substrate-opa = { path = "../protocol-substrate-opa" } +tempfile = { workspace = true } +tokio = { workspace = true } diff --git a/crates/chronicle-domain-test/src/test.rs b/crates/chronicle-domain-test/src/test.rs index 9d692e748..285fa7a5d 100644 --- a/crates/chronicle-domain-test/src/test.rs +++ b/crates/chronicle-domain-test/src/test.rs @@ -63,31 +63,28 @@ pub async fn main() { #[cfg(test)] mod test { - use super::{Mutation, Query}; - use async_stl_client::prost::Message; use chronicle::{ api::{ chronicle_graphql::{OpaCheck, Store, Subscription}, - inmem::EmbeddedChronicleTp, Api, UuidGen, }, async_graphql::{Request, Response, Schema}, + bootstrap::opa::CliPolicyLoader, chrono::{NaiveDate, TimeZone, Utc}, - common::{ - database::TemporaryDatabase, - identity::AuthId, - k256::sha2::{Digest, Sha256}, - opa::{CliPolicyLoader, ExecutorContext}, - }, - serde_json, tokio, - uuid::Uuid, + common::opa::std::ExecutorContext, }; use chronicle_signing::{ chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, CHRONICLE_NAMESPACE, }; + use chronicle_test_infrastructure::substitutes::{embed_substrate, TemporaryDatabase}; + use common::identity::AuthId; + use protocol_substrate::PolkadotConfig; + use uuid::Uuid; + + use super::{Mutation, Query}; + use core::future::Future; - use opa_tp_protocol::state::{policy_address, policy_meta_address, PolicyMeta}; use std::time::Duration; #[derive(Debug, Clone)] @@ -127,73 +124,30 @@ mod test { ) -> (Schema, TemporaryDatabase<'a>) { chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); - let signing = ChronicleSigning::new( + let secrets = ChronicleSigning::new( chronicle_secret_names(), vec![ - (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::test_keys()), - (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::test_keys()), + (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), + (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), ], ) .await .unwrap(); - let buf = async_stl_client::messages::Setting { - entries: vec![async_stl_client::messages::setting::Entry { - key: "chronicle.opa.policy_name".to_string(), - value: "allow_transactions".to_string(), - }], - } - .encode_to_vec(); - - let setting_id = ( - chronicle_protocol::settings::sawtooth_settings_address("chronicle.opa.policy_name"), - buf, - ); - let buf = async_stl_client::messages::Setting { - entries: vec![async_stl_client::messages::setting::Entry { - key: "chronicle.opa.entrypoint".to_string(), - value: "allow_transactions.allowed_users".to_string(), - }], - } - .encode_to_vec(); - - let setting_entrypoint = ( - chronicle_protocol::settings::sawtooth_settings_address("chronicle.opa.entrypoint"), - buf, - ); - - let d = env!("CARGO_MANIFEST_DIR").to_owned() + "/../../policies/bundle.tar.gz"; - let bin = std::fs::read(d).unwrap(); - - let meta = PolicyMeta { - id: "allow_transactions".to_string(), - hash: hex::encode(Sha256::digest(&bin)), - policy_address: policy_address("allow_transactions"), - }; - - let tp = EmbeddedChronicleTp::new_with_state( - vec![ - setting_id, - setting_entrypoint, - (policy_address("allow_transactions"), bin), - (policy_meta_address("allow_transactions"), serde_json::to_vec(&meta).unwrap()), - ] - .into_iter() - .collect(), - ) - .unwrap(); - - let ledger = tp.ledger.clone(); - + let embed_substrate = embed_substrate().await; let database = TemporaryDatabase::default(); let pool = database.connection_pool().unwrap(); + let liveness_check_interval = None; + //Do not keep these live once used by test + embedded_substrate::remove_shared_substrate(&embed_substrate); + let dispatch = Api::new( pool.clone(), - ledger, + embed_substrate.connect_chronicle::().await.unwrap(), SameUuid, - signing, + secrets, vec![], None, liveness_check_interval, diff --git a/crates/chronicle-domain/Cargo.toml b/crates/chronicle-domain/Cargo.toml index 7a288ec1e..fec4c69ae 100644 --- a/crates/chronicle-domain/Cargo.toml +++ b/crates/chronicle-domain/Cargo.toml @@ -20,9 +20,8 @@ chronicle = { path = "../chronicle" } chronicle = { path = "../chronicle" } [features] -strict = [] -# Use an in memory stub ledger -inmem = ["chronicle/inmem"] +devmode = ["chronicle/devmode"] +strict = [] [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/chronicle-protocol/Cargo.toml b/crates/chronicle-protocol/Cargo.toml deleted file mode 100644 index 332b23fc5..000000000 --- a/crates/chronicle-protocol/Cargo.toml +++ /dev/null @@ -1,57 +0,0 @@ -[package] -build = "build.rs" -edition = "2021" -name = "chronicle-protocol" -version = "0.7.5" - -[lib] -name = "chronicle_protocol" -path = "src/lib.rs" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -async-stl-client = { workspace = true } -async-trait = { workspace = true } -bytes = { workspace = true } -chronicle-signing = { path = "../chronicle-signing" } -common = { path = "../common" } -custom_error = { workspace = true } -derivative = { workspace = true } -futures = { workspace = true } -glob = { workspace = true } -hex = { workspace = true } -k256 = { workspace = true, features = [ - "default", - "arithmetic", - "ecdsa", - "pkcs8", - "sha256", - "std", - "pem", -] } -lazy_static = { workspace = true } -opa-tp-protocol = { path = "../opa-tp-protocol" } -openssl = { workspace = true } -prost = { workspace = true } -prost-types = { workspace = true } -rand = { workspace = true, features = ["getrandom"] } -rand_core = { workspace = true } -serde = { workspace = true } -serde_derive = { workspace = true } -serde_json = { workspace = true } -tempfile = { workspace = true } -thiserror = { workspace = true } -tokio = { workspace = true, features = ["time", "macros", "rt-multi-thread"] } -tracing = { workspace = true } -url = { workspace = true } -uuid = { workspace = true, features = ["serde", "v4"] } -zmq = { workspace = true } - -[build-dependencies] -glob = { workspace = true } -prost-build = { workspace = true } - -[dev-dependencies] -chrono = { workspace = true } -tempfile = { workspace = true } diff --git a/crates/chronicle-protocol/build.rs b/crates/chronicle-protocol/build.rs deleted file mode 100644 index 109764ea7..000000000 --- a/crates/chronicle-protocol/build.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::io::Result; - -fn main() -> Result<()> { - let protos = glob::glob("./src/protos/*.proto") - .unwrap() - .map(|x| x.unwrap()) - .collect::>(); - prost_build::compile_protos(&protos, &["./src/protos"])?; - Ok(()) -} diff --git a/crates/chronicle-protocol/src/address.rs b/crates/chronicle-protocol/src/address.rs deleted file mode 100644 index 59e43701a..000000000 --- a/crates/chronicle-protocol/src/address.rs +++ /dev/null @@ -1,47 +0,0 @@ -use core::fmt::Display; - -use common::{ - ledger::{LedgerAddress, NameSpacePart, ResourcePart}, - prov::AsCompact, -}; -use lazy_static::lazy_static; -use openssl::sha::Sha256; - -lazy_static! { - pub static ref PREFIX: String = { - let mut sha = Sha256::new(); - sha.update("chronicle".as_bytes()); - hex::encode(sha.finish())[..6].to_string() - }; -} - -pub static VERSION: &str = "1.0"; -pub static FAMILY: &str = "chronicle"; - -#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub struct SawtoothAddress(String); - -impl SawtoothAddress { - pub fn new(address: String) -> Self { - SawtoothAddress(address) - } -} - -/// Our sawtooth addresses use hash(chronicle)[..6] as the prefix, -/// followed by a 256 bit hash of the resource Iri and namespace Iri. -impl From<&LedgerAddress> for SawtoothAddress { - fn from(addr: &LedgerAddress) -> Self { - let mut sha = Sha256::new(); - if let Some(ns) = addr.namespace_part().as_ref() { - sha.update(ns.compact().as_bytes()) - } - sha.update(addr.resource_part().compact().as_bytes()); - SawtoothAddress(format!("{}{}", &*PREFIX, hex::encode(sha.finish()))) - } -} - -impl Display for SawtoothAddress { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(&self.0) - } -} diff --git a/crates/chronicle-protocol/src/lib.rs b/crates/chronicle-protocol/src/lib.rs deleted file mode 100644 index d3a550778..000000000 --- a/crates/chronicle-protocol/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -use async_stl_client::{ - ledger::SawtoothLedger, - zmq_client::{RetryingRequestResponseChannel, ZmqRequestResponseSawtoothChannel}, -}; -use messages::ChronicleSubmitTransaction; - -pub mod address; -pub mod messages; -pub mod protocol; -pub mod settings; - -pub use async_stl_client; -use protocol::ChronicleOperationEvent; - -static PROTOCOL_VERSION: &str = "2"; -const SUBMISSION_BODY_VERSION: u16 = 1; - -pub type ChronicleLedger = SawtoothLedger< - RetryingRequestResponseChannel, - ChronicleOperationEvent, - ChronicleSubmitTransaction, ->; - -pub mod sawtooth { - #![allow(clippy::derive_partial_eq_without_eq)] - - include!(concat!(env!("OUT_DIR"), "/_.rs")); -} diff --git a/crates/chronicle-protocol/src/messages.rs b/crates/chronicle-protocol/src/messages.rs deleted file mode 100644 index e48ff1aed..000000000 --- a/crates/chronicle-protocol/src/messages.rs +++ /dev/null @@ -1,135 +0,0 @@ -use std::sync::Arc; - -use chronicle_signing::{BatcherKnownKeyNamesSigner, ChronicleSigning, SecretError}; -use common::prov::{to_json_ld::ToJson, ChronicleTransaction}; -use k256::ecdsa::VerifyingKey; -use opa_tp_protocol::state::{policy_address, policy_meta_address}; -use serde_json::json; - -use crate::{ - address::SawtoothAddress, - protocol::ProtocolError, - sawtooth::submission::{BodyVariant, IdentityVariant}, - settings::sawtooth_settings_address, - PROTOCOL_VERSION, SUBMISSION_BODY_VERSION, -}; - -use super::sawtooth::*; -use async_stl_client::{ - ledger::{LedgerTransaction, TransactionId}, - sawtooth::{MessageBuilder, TransactionPayload}, -}; -use prost::Message; - -#[derive(Debug, Clone)] -pub struct ChronicleSubmitTransaction { - pub tx: ChronicleTransaction, - pub signer: ChronicleSigning, - pub policy_name: Option, -} - -#[async_trait::async_trait] -impl TransactionPayload for ChronicleSubmitTransaction { - type Error = ProtocolError; - - /// Envelope a payload of `ChronicleOperations` and `SignedIdentity` in a `Submission` protocol - /// buffer, along with placeholders for protocol version info and a tracing span id. - async fn to_bytes(&self) -> Result, ProtocolError> { - let mut submission = Submission { - version: PROTOCOL_VERSION.to_string(), - span_id: 0u64, - ..Default::default() - }; - - let mut ops = Vec::with_capacity(self.tx.tx.len()); - for op in &self.tx.tx { - let op_json = op.to_json(); - let compact_json = op_json.compact_stable_order().await?; - ops.push(compact_json); - } - - let ops_json = - serde_json::to_string(&json!({"version": SUBMISSION_BODY_VERSION, "ops": ops}))?; - let identity_json = serde_json::to_string(&self.tx.identity)?; - tracing::debug!(ops_json = %ops_json, identity_json = %identity_json); - - submission.body_variant = Some(BodyVariant::Body(BodyMessageV1 { payload: ops_json })); - submission.identity_variant = - Some(IdentityVariant::Identity(IdentityMessageV1 { payload: identity_json })); - Ok(submission.encode_to_vec()) - } -} - -impl ChronicleSubmitTransaction { - pub fn new( - tx: ChronicleTransaction, - signer: ChronicleSigning, - policy_name: Option, - ) -> Self { - Self { tx, signer, policy_name } - } -} - -#[async_trait::async_trait] -impl LedgerTransaction for ChronicleSubmitTransaction { - type Error = SecretError; - - async fn sign(&self, bytes: Arc>) -> Result, SecretError> { - self.signer.batcher_sign(&bytes).await - } - - async fn verifying_key(&self) -> Result { - self.signer.batcher_verifying().await - } - - fn addresses(&self) -> Vec { - self.tx - .tx - .iter() - .flat_map(|op| op.dependencies()) - .map(|dep| SawtoothAddress::from(&dep).to_string()) - .collect::>() - .into_iter() - .collect() - } - - async fn as_sawtooth_tx( - &self, - message_builder: &MessageBuilder, - ) -> Result<(async_stl_client::messages::Transaction, TransactionId), Self::Error> { - //Ensure we append any opa policy binary address and meta address to the - //list of addresses, along with the settings address - let mut addresses: Vec<_> = self - .addresses() - .into_iter() - .chain(vec![ - sawtooth_settings_address("chronicle.opa.policy_name"), - sawtooth_settings_address("chronicle.opa.entrypoint"), - ]) - .collect(); - - if self.policy_name.is_some() { - addresses = addresses - .into_iter() - .chain(vec![ - policy_address(self.policy_name.as_ref().unwrap()), - policy_meta_address(self.policy_name.as_ref().unwrap()), - ]) - .collect(); - } - message_builder - .make_sawtooth_transaction( - addresses.clone(), - addresses, - vec![], - self, - self.signer.batcher_verifying().await?, - |bytes| { - let signer = self.signer.clone(); - let bytes = bytes.to_vec(); - async move { signer.batcher_sign(&bytes).await } - }, - ) - .await - } -} diff --git a/crates/chronicle-protocol/src/perf.md b/crates/chronicle-protocol/src/perf.md deleted file mode 100644 index 73e9f7af6..000000000 --- a/crates/chronicle-protocol/src/perf.md +++ /dev/null @@ -1,32 +0,0 @@ -# Chronicle on sawtooth performance - -## Environment - -4 node sawtooth cluster backed onto a 4x 4X Large AWS node Kubernetes cluster -using our default helm settings. This creates a 4 node sawtooth network with a -validator and transaction processor per AWS node, and a single chronicle service -using persistent Postgres. - -## Testing methodology - -Sequences of 10000 chronicle mutations (the creation of an activity and the -setting of multiple attributes) were sent from a task, through the Chronicle API -at increasing rates of transactions per-second to find the rate where system -performance begins to break down and discover failure modes. - -## Results - -The maximum throughput for the whole system is between 50-60 transactions per -second. This throughput is constrained by Sawtooth consensus, and there are ways -this could be significantly raised if Chronicle can increase batch sizes at high throughput -rates. Failure modes over the saturation points are resumable - Sawtooth will -eventually report its queue to be full to Chronicle, and Chronicle will send -errors to connected clients. - -No data will be lost due to errors running Chronicle beyond its saturation point - -## Future actions - -Chronicle 0.8 has some minor performance improvements that could be back ported -to .7. Batching of transactions at high throughput rates would significantly -improve the total throughput of the network - 2 orders of magnitude is possible. diff --git a/crates/chronicle-protocol/src/protocol.rs b/crates/chronicle-protocol/src/protocol.rs deleted file mode 100644 index 3384ba077..000000000 --- a/crates/chronicle-protocol/src/protocol.rs +++ /dev/null @@ -1,308 +0,0 @@ -use std::io::Cursor; - -use async_stl_client::{ - error::SawtoothCommunicationError, - ledger::{LedgerEvent, Span}, -}; -use common::{ - identity::SignedIdentity, - prov::{ - operations::ChronicleOperation, to_json_ld::ToJson, CompactionError, Contradiction, - PayloadError, ProcessorError, ProvModel, - }, -}; -use prost::Message; -use tracing::span; - -use thiserror::Error; - -use self::messages::event::OptionContradiction; - -#[derive(Debug)] -pub struct ChronicleOperationEvent(pub Result, pub SignedIdentity); - -impl From for Result { - fn from(val: ChronicleOperationEvent) -> Self { - val.0 - } -} - -#[async_trait::async_trait] -impl LedgerEvent for ChronicleOperationEvent { - async fn deserialize( - buf: &[u8], - ) -> Result<(Self, Span), async_stl_client::error::SawtoothCommunicationError> - where - Self: Sized, - { - let event = messages::Event::decode(buf) - .map_err(|e| SawtoothCommunicationError::LedgerEventParse { source: e.into() })?; - // Spans of zero panic, so assign a dummy value until we thread the span correctly - let span_id = { - if event.span_id == 0 { - span::Id::from_u64(0xffffffffffffffff) - } else { - span::Id::from_u64(event.span_id) - } - }; - let model = match (event.delta, event.option_contradiction) { - (_, Some(OptionContradiction::Contradiction(contradiction))) => - Err(serde_json::from_str::(&contradiction).map_err(|e| { - SawtoothCommunicationError::LedgerEventParse { source: e.into() } - })?), - (delta, None) => { - let mut model = ProvModel::default(); - model.apply_json_ld_str(&delta).await.map_err(|e| { - SawtoothCommunicationError::LedgerEventParse { source: e.into() } - })?; - - Ok(model) - }, - }; - - let identity = { - if event.identity.is_empty() { - SignedIdentity::new_no_identity() - } else { - serde_json::from_str(&event.identity).map_err(|e| { - SawtoothCommunicationError::LedgerEventParse { source: e.into() } - })? - } - }; - Ok((Self(model, identity), Span::Span(span_id.into_u64()))) - } -} - -#[derive(Error, Debug)] -pub enum ProtocolError { - #[error("Protobuf deserialization error {source}")] - ProtobufDeserialize { - #[from] - source: prost::DecodeError, - }, - #[error("Protobuf serialization error {source}")] - ProtobufSerialize { - #[from] - source: prost::EncodeError, - }, - #[error("Serde de/serialization error {source}")] - JsonSerialize { - #[from] - source: serde_json::Error, - }, - #[error("Problem applying delta {source}")] - ProcessorError { - #[from] - source: ProcessorError, - }, - #[error("Could not compact json {source}")] - Compaction { - #[from] - source: CompactionError, - }, -} - -static PROTOCOL_VERSION: &str = "2"; - -// Include the `submission` module, which is -// generated from ./protos/submission.proto. -pub mod messages { - #![allow(clippy::derive_partial_eq_without_eq)] - - include!(concat!(env!("OUT_DIR"), "/_.rs")); -} - -pub async fn chronicle_committed( - span: u64, - delta: ProvModel, - identity: &SignedIdentity, -) -> Result { - Ok(messages::Event { - version: PROTOCOL_VERSION.to_owned(), - delta: serde_json::to_string(&delta.to_json().compact_stable_order().await?)?, - span_id: span, - identity: serde_json::to_string(identity)?, - ..Default::default() - }) -} - -pub fn chronicle_contradicted( - span: u64, - contradiction: &Contradiction, - identity: &SignedIdentity, -) -> Result { - Ok(messages::Event { - version: PROTOCOL_VERSION.to_owned(), - span_id: span, - option_contradiction: Some(OptionContradiction::Contradiction(serde_json::to_string( - &contradiction, - )?)), - identity: serde_json::to_string(identity)?, - ..Default::default() - }) -} - -impl messages::Event { - pub async fn get_contradiction(&self) -> Result, ProtocolError> { - Ok(self - .option_contradiction - .as_ref() - .map(|OptionContradiction::Contradiction(s)| serde_json::from_str(s)) - .transpose()?) - } - - pub async fn get_delta(&self) -> Result { - let mut model = ProvModel::default(); - model.apply_json_ld_str(&self.delta).await?; - - Ok(model) - } -} - -pub fn serialize_submission(submission: &messages::Submission) -> Vec { - let mut buf = Vec::with_capacity(submission.encoded_len()); - submission.encode(&mut buf).unwrap(); - buf -} - -/// `Submission` protocol buffer deserializer -pub fn deserialize_submission(buf: &[u8]) -> Result { - messages::Submission::decode(&mut Cursor::new(buf)) -} - -/// Convert a `Submission` payload from a vector of -/// strings to a vector of `ChronicleOperation`s. -/// Operates for version 1 of the protocol. -pub async fn chronicle_operations_from_submission_v1( - submission_body: Vec, -) -> Result, ProcessorError> { - let mut ops = Vec::with_capacity(submission_body.len()); - for op in submission_body.iter() { - let json = serde_json::from_str(op)?; - // The inner json value should be in compacted form, - // wrapping in `ExpandedJson`, as required by `ChronicleOperation::from_json` - let op = ChronicleOperation::from_json(&json).await?; - ops.push(op); - } - Ok(ops) -} - -/// Convert a `Submission` payload from a vector of -/// strings to a vector of `ChronicleOperation`s. -/// Operates for version 2 of the protocol. -pub async fn chronicle_operations_from_submission_v2( - submission_body: String, -) -> Result, ProcessorError> { - use serde_json::{json, Value}; - let json = serde_json::from_str(&submission_body)?; - - if let Value::Object(map) = json { - if let Some(version) = map.get("version") { - if version == &json!(1) { - if let Some(ops_json) = map.get("ops").and_then(|x| x.as_array()) { - let mut ops = Vec::with_capacity(ops_json.len()); - for op in ops_json { - ops.push(ChronicleOperation::from_json(op).await?); - } - Ok(ops) - } else { - Err(PayloadError::OpsNotAList.into()) - } - } else { - Err(PayloadError::VersionUnknown.into()) - } - } else { - Err(PayloadError::VersionMissing.into()) - } - } else { - Err(PayloadError::NotAnObject.into()) - } -} - -/// Convert a `Submission` identity from a String -/// to a `SignedIdentity` -pub async fn chronicle_identity_from_submission( - submission_identity: String, -) -> Result { - Ok(serde_json::from_str(&submission_identity)?) -} - -#[cfg(test)] -mod test { - use crate::protocol::{ - chronicle_operations_from_submission_v1, chronicle_operations_from_submission_v2, - ChronicleOperation, - }; - use chrono::{NaiveDateTime, TimeZone, Utc}; - use common::prov::{ - operations::{EndActivity, StartActivity}, - to_json_ld::ToJson, - ActivityId, NamespaceId, - }; - use serde_json::{json, Value}; - use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, - }; - use uuid::Uuid; - - fn construct_operations() -> Vec { - let mut hasher = DefaultHasher::new(); - "foo".hash(&mut hasher); - let n1 = hasher.finish(); - "bar".hash(&mut hasher); - let n2 = hasher.finish(); - let uuid = Uuid::from_u64_pair(n1, n2); - - let base_ms = 1234567654321; - let activity_start = - Utc.from_utc_datetime(&NaiveDateTime::from_timestamp_millis(base_ms).unwrap()); - let activity_end = - Utc.from_utc_datetime(&NaiveDateTime::from_timestamp_millis(base_ms + 12345).unwrap()); - - let start = ChronicleOperation::StartActivity(StartActivity { - namespace: NamespaceId::from_external_id("test-namespace", uuid), - id: ActivityId::from_external_id("test-activity"), - time: activity_start, - }); - let end = ChronicleOperation::EndActivity(EndActivity { - namespace: NamespaceId::from_external_id("test-namespace", uuid), - id: ActivityId::from_external_id("test-activity"), - time: activity_end, - }); - - vec![start, end] - } - - #[tokio::test] - async fn deserialize_submission_v1() { - let operations_expected = construct_operations(); - - let submission_body = operations_expected - .iter() - .map(|operation| serde_json::to_string(&operation.to_json().0).unwrap()) - .collect(); - - let operations_actual = - chronicle_operations_from_submission_v1(submission_body).await.unwrap(); - - assert_eq!(operations_expected, operations_actual); - } - - #[tokio::test] - async fn deserialize_submission_v2() { - let operations_expected = construct_operations(); - - let submission_body = - serde_json::to_string(&json!({"version": 1, "ops": operations_expected - .iter() - .map(|operation| operation.to_json().0) - .collect::>()})) - .unwrap(); - - let operations_actual = - chronicle_operations_from_submission_v2(submission_body).await.unwrap(); - - assert_eq!(operations_expected, operations_actual); - } -} diff --git a/crates/chronicle-protocol/src/protos/event.proto b/crates/chronicle-protocol/src/protos/event.proto deleted file mode 100644 index 166bc0ac4..000000000 --- a/crates/chronicle-protocol/src/protos/event.proto +++ /dev/null @@ -1,14 +0,0 @@ - -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "sawtooth.sdk.protobuf"; -option go_package = "batch_pb2"; - -message Event { - string version = 1; - uint64 span_id = 2; - oneof option_contradiction { string contradiction = 3; } - string delta = 4; - string identity = 5; -} diff --git a/crates/chronicle-protocol/src/protos/submission.proto b/crates/chronicle-protocol/src/protos/submission.proto deleted file mode 100644 index dc3ae4c82..000000000 --- a/crates/chronicle-protocol/src/protos/submission.proto +++ /dev/null @@ -1,37 +0,0 @@ -// a place to keep protocol version information (that’s not the address space) -// and send along an opentelemetry distributed span id -- a leverage point for -// future protocol versioning and a way of sneaking in a OTEL span id -// for distributed tracing as there’s no sawtooth native way of smuggling in -// metadata - -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "sawtooth.sdk.protobuf"; -option go_package = "batch_pb2"; - -message OpaPolicy { - string id = 1; - string entrypoint = 2; -} - -message Submission { - string version = 1; - uint64 span_id = 2; - repeated string body_old = 3 [ deprecated = true ]; - oneof identity_variant { - string identity_old = 4 [ deprecated = true ]; - IdentityMessageV1 identity = 5; - } - oneof body_variant { - BodyMessageV1 body = 6; - } -} - -message BodyMessageV1 { - string payload = 1; -} - -message IdentityMessageV1 { - string payload = 1; -} diff --git a/crates/chronicle-protocol/src/settings.rs b/crates/chronicle-protocol/src/settings.rs deleted file mode 100644 index ad4071eef..000000000 --- a/crates/chronicle-protocol/src/settings.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::iter::repeat; - -use async_stl_client::{ - error::SawtoothCommunicationError, ledger::LedgerReader, messages::Setting, -}; -use k256::sha2::{Digest, Sha256}; -use prost::Message; -use tracing::error; - -use crate::ChronicleLedger; - -fn setting_key_to_address(key: &str) -> String { - let mut address = String::new(); - address.push_str("000000"); - address.push_str( - &key.splitn(4, '.') - .chain(repeat("")) - .map(short_hash) - .take(4) - .collect::>() - .join(""), - ); - - address -} - -fn short_hash(s: &str) -> String { - hex::encode(Sha256::digest(s.as_bytes()))[..16].to_string() -} - -/// Generates a Sawtooth address for a given setting key. -/// -/// The address is a hex string that is computed based on the input key, -/// according to the Sawtooth settings addressing algorithm. The key is -/// split into four parts based on the dots in the string. If there are -/// less than four parts, the remaining parts are filled with empty strings. -/// Each of these parts has a short hash computed (the first 16 characters -/// of its SHA256 hash in hex) and is joined into a single address, with the -/// settings namespace (`000000`) added at the beginning. -/// -/// Does not account for settings keys with more than 4 components -/// -/// # Arguments -/// -/// * `s` - A string representing the setting key to generate an address for. -/// -/// # Example -/// -/// ``` -/// use chronicle_protocol::settings::sawtooth_settings_address; -/// -/// let address = sawtooth_settings_address("sawtooth.config.vote.proposals"); -/// assert_eq!(address, "000000a87cb5eafdcca6a8b79606fb3afea5bdab274474a6aa82c1c0cbf0fbcaf64c0b"); -/// ``` -pub fn sawtooth_settings_address(s: &str) -> String { - setting_key_to_address(s) -} - -/// This `SettingsReader` struct is used for extracting particular configuration -/// settings from the Sawtooth settings TP given the key. -pub struct SettingsReader(ChronicleLedger); - -impl SettingsReader { - pub fn new(reader: ChronicleLedger) -> Self { - Self(reader) - } - - /// Async function that returns the value of a specific configuration setting, given its key. - /// - /// # Arguments - /// * `key` - a reference to a string that contains the key for the setting to retrieve. - /// - /// # Errors - /// If the value is not found, returns a `SawtoothCommunicationError`, which indicates that - /// there was an error in communicating with the Sawtooth network. - /// - /// Settings values are not uniform, so we return a `Vec` for further processing - pub async fn read_settings(&self, key: &str) -> Result { - let address = sawtooth_settings_address(key); - loop { - let res = self.0.get_state_entry(&address).await; - - if let Err(e) = res { - error!("Error reading settings: {}", e); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; - continue - } - - return Ok(Setting::decode(&*res.unwrap())?) - } - } -} - -#[derive(Debug, Clone)] -pub struct OpaSettings { - pub policy_name: String, - pub entrypoint: String, -} - -pub async fn read_opa_settings( - settings: &SettingsReader, -) -> Result { - let policy_id = settings.read_settings("chronicle.opa.policy_name").await?; - let entrypoint = settings.read_settings("chronicle.opa.entrypoint").await?; - let policy_id = policy_id - .entries - .first() - .ok_or_else(|| SawtoothCommunicationError::MalformedMessage)?; - let entrypoint = entrypoint - .entries - .first() - .ok_or_else(|| SawtoothCommunicationError::MalformedMessage)?; - Ok(OpaSettings { policy_name: policy_id.value.clone(), entrypoint: entrypoint.value.clone() }) -} diff --git a/crates/chronicle-signing/src/embedded_secret_manager_source.rs b/crates/chronicle-signing/src/embedded_secret_manager_source.rs index 6d4d964ae..d64d14fdc 100644 --- a/crates/chronicle-signing/src/embedded_secret_manager_source.rs +++ b/crates/chronicle-signing/src/embedded_secret_manager_source.rs @@ -6,7 +6,10 @@ use k256::{ use rand::{rngs::StdRng, SeedableRng}; use secret_vault::{Secret, SecretMetadata, SecretVaultRef, SecretVaultResult, SecretsSource}; use secret_vault_value::SecretValue; -use std::{collections::HashMap, sync::Arc}; +use std::{ + collections::{BTreeMap, HashMap}, + sync::Arc, +}; use tokio::sync::Mutex; use tracing::debug; @@ -14,22 +17,22 @@ use crate::SecretError; pub struct EmbeddedSecretManagerSource { secrets: Arc>>>, - deterministic: bool, + seeds: BTreeMap, } impl EmbeddedSecretManagerSource { pub fn new() -> Self { - Self { secrets: Arc::new(Mutex::new(HashMap::new())), deterministic: false } + Self { secrets: Arc::new(Mutex::new(HashMap::new())), seeds: BTreeMap::default() } } - pub fn new_deterministic() -> Self { - Self { secrets: Arc::new(Mutex::new(HashMap::new())), deterministic: true } + pub fn new_seeded(seeds: BTreeMap) -> Self { + Self { secrets: Arc::new(Mutex::new(HashMap::new())), seeds } } } -fn new_signing_key(deterministic: bool, index: usize) -> Result, SecretError> { - let secret = if deterministic { - SecretKey::random(StdRng::seed_from_u64(index as _)) +fn new_signing_key(name: &str, seeds: &BTreeMap) -> Result, SecretError> { + let secret = if let Some(seed) = seeds.get(name) { + SecretKey::from_be_bytes(seed).map_err(|_| SecretError::BadSeed)? } else { SecretKey::random(StdRng::from_entropy()) }; @@ -55,9 +58,10 @@ impl SecretsSource for EmbeddedSecretManagerSource { let mut result_map: HashMap = HashMap::new(); let mut secrets = self.secrets.lock().await; - for (index, secret_ref) in references.iter().enumerate() { + for secret_ref in references.iter() { let secret = secrets.entry(secret_ref.clone()).or_insert_with(|| { - let secret = new_signing_key(self.deterministic, index).unwrap(); + let secret = + new_signing_key(secret_ref.key.secret_name.as_ref(), &self.seeds).unwrap(); secret.to_vec() }); diff --git a/crates/chronicle-signing/src/lib.rs b/crates/chronicle-signing/src/lib.rs index f19657a76..ca9c864dd 100644 --- a/crates/chronicle-signing/src/lib.rs +++ b/crates/chronicle-signing/src/lib.rs @@ -10,6 +10,7 @@ use secret_vault::{ SecretNamespace, SecretVaultBuilder, SecretVaultRef, SecretVaultView, }; use std::{ + collections::BTreeMap, path::{Path, PathBuf}, sync::Arc, }; @@ -42,15 +43,19 @@ pub enum SecretError { #[from] source: SecretVaultError, }, + + #[error("Bad BIP39 seed")] + BadSeed, } pub enum ChronicleSecretsOptions { // Connect to hashicorp vault for secrets Vault(vault_secret_manager_source::VaultSecretManagerSourceOptions), - // Generate secrets in memory on demand + // Generate secrets from entropy in memory on demand Embedded, - //Deterministically generate secrets for testing - Test, + + //Seed secrets with name using a map of secret name to BIP39 seed phrase + Seeded(BTreeMap), //Filesystem based keys Filesystem(PathBuf), } @@ -81,9 +86,9 @@ impl ChronicleSecretsOptions { ChronicleSecretsOptions::Embedded } - // Generate deterministic secrets in memory on demand - pub fn test_keys() -> ChronicleSecretsOptions { - ChronicleSecretsOptions::Test + // Use supplied seeds, or fall back to entropy + pub fn seeded(seeds: BTreeMap) -> ChronicleSecretsOptions { + ChronicleSecretsOptions::Seeded(seeds) } } @@ -121,8 +126,11 @@ impl ChronicleSigning { multi_source = multi_source.add_source(&SecretNamespace::new(namespace), source); }, - (namespace, ChronicleSecretsOptions::Test) => { - let source = embedded_secret_manager_source::EmbeddedSecretManagerSource::new_deterministic(); + (namespace, ChronicleSecretsOptions::Seeded(seeds)) => { + let source = + embedded_secret_manager_source::EmbeddedSecretManagerSource::new_seeded( + seeds, + ); multi_source = multi_source.add_source(&SecretNamespace::new(namespace), source); }, @@ -184,6 +192,30 @@ pub trait WithSecret { ) -> Result; } +#[async_trait::async_trait] +pub trait OwnedSecret { + async fn copy_signing_key( + &self, + secret_namespace: &str, + secret_name: &str, + ) -> Result; +} + +#[async_trait::async_trait] +impl OwnedSecret for T { + async fn copy_signing_key( + &self, + secret_namespace: &str, + secret_name: &str, + ) -> Result { + let secret = + WithSecret::with_signing_key(self, secret_namespace, secret_name, |secret| secret) + .await?; + + Ok(secret) + } +} + #[async_trait::async_trait] impl WithSecret for ChronicleSigning { async fn with_signing_key( diff --git a/crates/chronicle-test-infrastructure/Cargo.toml b/crates/chronicle-test-infrastructure/Cargo.toml new file mode 100644 index 000000000..2b571c4ac --- /dev/null +++ b/crates/chronicle-test-infrastructure/Cargo.toml @@ -0,0 +1,34 @@ +[package] +edition = "2021" +name = "chronicle-test-infrastructure" +version = "0.1.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +api = { path = "../api" } +chronicle = { path = "../chronicle" } +chronicle-signing = { path = "../chronicle-signing" } +chronicle-telemetry = { path = "../chronicle-telemetry" } +chrono = { workspace = true } +common = { path = "../common", features = [ + "parity-encoding", + "json-ld", + "std", +] } +diesel = { workspace = true } +embedded-substrate = { path = "../embedded-substrate" } +insta = { workspace = true, features = ["json", "yaml"] } +lazy_static = { workspace = true } +protocol-abstract = { path = "../protocol-abstract" } +protocol-substrate = { path = "../protocol-substrate" } +protocol-substrate-chronicle = { path = "../protocol-substrate-chronicle" } +r2d2 = { workspace = true } +serde_json = { workspace = true } +tempfile = { workspace = true } +testcontainers = { workspace = true } +tokio = { workspace = true } +uuid = { workspace = true } + +[dev-dependencies] +assert_fs = { workspace = true } diff --git a/crates/chronicle-test-infrastructure/src/api_test.rs b/crates/chronicle-test-infrastructure/src/api_test.rs new file mode 100644 index 000000000..b56ab5e9a --- /dev/null +++ b/crates/chronicle-test-infrastructure/src/api_test.rs @@ -0,0 +1,1489 @@ +use api::commands::{ + ActivityCommand, AgentCommand, ApiCommand, EntityCommand, ImportCommand, NamespaceCommand, +}; +use chrono::{TimeZone, Utc}; +use common::{ + attributes::{Attribute, Attributes}, + identity::AuthId, + prov::{ + json_ld::ToJson, + operations::{ChronicleOperation, DerivationType}, + ActivityId, AgentId, DomaintypeId, EntityId, NamespaceId, + }, +}; +use uuid::Uuid; + +use crate::substitutes::test_api; + +// Creates a mock file containing JSON-LD of the ChronicleOperations +// that would be created by the given command, although not in any particular order. +fn test_create_agent_operations_import() -> assert_fs::NamedTempFile { + let file = assert_fs::NamedTempFile::new("import.json").unwrap(); + assert_fs::prelude::FileWriteStr::write_str( + &file, + r#" + [ + { + "@id": "_:n1", + "@type": [ + "http://btp.works/chronicleoperations/ns#SetAttributes" + ], + "http://btp.works/chronicleoperations/ns#agentName": [ + { + "@value": "testagent" + } + ], + "http://btp.works/chronicleoperations/ns#attributes": [ + { + "@type": "@json", + "@value": {} + } + ], + "http://btp.works/chronicleoperations/ns#domaintypeId": [ + { + "@value": "type" + } + ], + "http://btp.works/chronicleoperations/ns#namespaceName": [ + { + "@value": "testns" + } + ], + "http://btp.works/chronicleoperations/ns#namespaceUuid": [ + { + "@value": "6803790d-5891-4dfa-b773-41827d2c630b" + } + ] + }, + { + "@id": "_:n1", + "@type": [ + "http://btp.works/chronicleoperations/ns#CreateNamespace" + ], + "http://btp.works/chronicleoperations/ns#namespaceName": [ + { + "@value": "testns" + } + ], + "http://btp.works/chronicleoperations/ns#namespaceUuid": [ + { + "@value": "6803790d-5891-4dfa-b773-41827d2c630b" + } + ] + }, + { + "@id": "_:n1", + "@type": [ + "http://btp.works/chronicleoperations/ns#AgentExists" + ], + "http://btp.works/chronicleoperations/ns#agentName": [ + { + "@value": "testagent" + } + ], + "http://btp.works/chronicleoperations/ns#namespaceName": [ + { + "@value": "testns" + } + ], + "http://btp.works/chronicleoperations/ns#namespaceUuid": [ + { + "@value": "6803790d-5891-4dfa-b773-41827d2c630b" + } + ] + } + ] + "#, + ) + .unwrap(); + file +} + +#[tokio::test] +async fn test_import_operations() { + let mut api = test_api().await; + + let file = test_create_agent_operations_import(); + + let contents = std::fs::read_to_string(file.path()).unwrap(); + + let json_array = serde_json::from_str::>(&contents).unwrap(); + + let mut operations = Vec::with_capacity(json_array.len()); + for value in json_array.into_iter() { + let op = ChronicleOperation::from_json(&value) + .await + .expect("Failed to parse imported JSON-LD to ChronicleOperation"); + operations.push(op); + } + + let namespace = NamespaceId::from_external_id( + "testns", + Uuid::parse_str("6803790d-5891-4dfa-b773-41827d2c630b").unwrap(), + ); + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!(api + .dispatch(ApiCommand::Import(ImportCommand { namespace: namespace.clone(), operations: operations.clone() } ), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:type" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:6803790d-5891-4dfa-b773-41827d2c630b", + "value": {} + }, + { + "@id": "chronicle:ns:testns:6803790d-5891-4dfa-b773-41827d2c630b", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + // Check that the operations that do not result in data changes are not submitted + insta::assert_json_snapshot!(api + .dispatch(ApiCommand::Import(ImportCommand { namespace, operations } ), identity) + .await + .unwrap() + .unwrap() + .1, @r###""null""###); +} + +#[tokio::test] +async fn create_namespace() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!(api + .dispatch(ApiCommand::NameSpace(NamespaceCommand::Create { + external_id: "testns".into(), + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + "###); +} + +#[tokio::test] +async fn create_agent() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!(api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn create_system_activity() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!(api.dispatch(ApiCommand::Activity(ActivityCommand::Create { + external_id: "testactivity".into(), + namespace: common::prov::SYSTEM_ID.into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:test" + ], + "externalId": "testactivity", + "namespace": "chronicle:ns:chronicle%2Dsystem:00000000-0000-0000-0000-000000000001", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:chronicle%2Dsystem:00000000-0000-0000-0000-000000000001", + "@type": "chronicle:Namespace", + "externalId": "chronicle-system" + } + ] + } + "###); +} + +#[tokio::test] +async fn create_activity() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!(api.dispatch(ApiCommand::Activity(ActivityCommand::Create { + external_id: "testactivity".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:test" + ], + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn start_activity() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + api.dispatch( + ApiCommand::Agent(AgentCommand::UseInContext { + id: AgentId::from_external_id("testagent"), + namespace: "testns".into(), + }), + identity.clone(), + ) + .await + .unwrap(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Start { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "startTime": "2014-07-08T09:10:11+00:00", + "value": {}, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn contradict_attributes() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + let res = api + .dispatch( + ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test2".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), + identity, + ) + .await; + + insta::assert_snapshot!(res.err().unwrap().to_string(), @r###"Contradiction: Contradiction { attribute value change: test Attribute { typ: "test", value: String("test2") } Attribute { typ: "test", value: String("test") } }"###); +} + +#[tokio::test] +async fn contradict_start_time() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + api.dispatch( + ApiCommand::Agent(AgentCommand::UseInContext { + id: AgentId::from_external_id("testagent"), + namespace: "testns".into(), + }), + identity.clone(), + ) + .await + .unwrap(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Start { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "startTime": "2014-07-08T09:10:11+00:00", + "value": {}, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + // Should contradict + let res = api + .dispatch( + ApiCommand::Activity(ActivityCommand::Start { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2018, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), + identity, + ) + .await; + + insta::assert_snapshot!(res.err().unwrap().to_string(), @"Contradiction: Contradiction { start date alteration: 2014-07-08 09:10:11 UTC 2018-07-08 09:10:11 UTC }"); +} + +#[tokio::test] +async fn contradict_end_time() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + api.dispatch( + ApiCommand::Agent(AgentCommand::UseInContext { + id: AgentId::from_external_id("testagent"), + namespace: "testns".into(), + }), + identity.clone(), + ) + .await + .unwrap(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::End { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2018, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "endTime": "2018-07-08T09:10:11+00:00", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "value": {}, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + // Should contradict + let res = api + .dispatch( + ApiCommand::Activity(ActivityCommand::End { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2022, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), + identity, + ) + .await; + + insta::assert_snapshot!(res.err().unwrap().to_string(), @"Contradiction: Contradiction { end date alteration: 2018-07-08 09:10:11 UTC 2022-07-08 09:10:11 UTC }"); +} + +#[tokio::test] +async fn end_activity() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + api.dispatch( + ApiCommand::Agent(AgentCommand::UseInContext { + id: AgentId::from_external_id("testagent"), + namespace: "testns".into(), + }), + identity.clone(), + ) + .await + .unwrap(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Start { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "startTime": "2014-07-08T09:10:11+00:00", + "value": {}, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::End { + + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), + agent: None, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "endTime": "2014-07-08T09:10:11+00:00", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "startTime": "2014-07-08T09:10:11+00:00", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_use() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Agent(AgentCommand::Create { + external_id: "testagent".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:test" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + api.dispatch( + ApiCommand::Agent(AgentCommand::UseInContext { + id: AgentId::from_external_id("testagent"), + namespace: "testns".into(), + }), + identity.clone(), + ) + .await + .unwrap(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Create { + external_id: "testactivity".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:test" + ], + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Use { + id: EntityId::from_external_id("testentity"), + namespace: "testns".into(), + activity: ActivityId::from_external_id("testactivity"), + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:test" + ], + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "used": [ + "chronicle:entity:testentity" + ], + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:entity:testentity", + "@type": "prov:Entity", + "externalId": "testentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::End { + id: ActivityId::from_external_id("testactivity"), + namespace: "testns".into(), + time: Some(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap()), + agent: Some(AgentId::from_external_id("testagent")), + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:test" + ], + "endTime": "2014-07-08T09:10:11+00:00", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "used": [ + "chronicle:entity:testentity" + ], + "value": { + "test": "test" + }, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_generate() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Create { + external_id: "testactivity".into(), + namespace: "testns".into(), + attributes: Attributes { + typ: Some(DomaintypeId::from_external_id("test")), + attributes: [( + "test".to_owned(), + Attribute { + typ: "test".to_owned(), + value: serde_json::Value::String("test".to_owned()).into(), + }, + )] + .into_iter() + .collect(), + }, + }), identity.clone()) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:test" + ], + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "test": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Activity(ActivityCommand::Generate { + id: EntityId::from_external_id("testentity"), + namespace: "testns".into(), + activity: ActivityId::from_external_id("testactivity"), + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testentity", + "@type": "prov:Entity", + "externalId": "testentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasGeneratedBy": [ + "chronicle:activity:testactivity" + ] + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn derive_entity_abstract() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Entity(EntityCommand::Derive { + id: EntityId::from_external_id("testgeneratedentity"), + namespace: "testns".into(), + activity: None, + used_entity: EntityId::from_external_id("testusedentity"), + derivation: DerivationType::None, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasDerivedFrom": [ + "chronicle:entity:testusedentity" + ] + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn derive_entity_primary_source() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Entity(EntityCommand::Derive { + id: EntityId::from_external_id("testgeneratedentity"), + namespace: "testns".into(), + activity: None, + derivation: DerivationType::PrimarySource, + used_entity: EntityId::from_external_id("testusedentity"), + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "hadPrimarySource": [ + "chronicle:entity:testusedentity" + ], + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn derive_entity_revision() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Entity(EntityCommand::Derive { + id: EntityId::from_external_id("testgeneratedentity"), + namespace: "testns".into(), + activity: None, + used_entity: EntityId::from_external_id("testusedentity"), + derivation: DerivationType::Revision, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasRevisionOf": [ + "chronicle:entity:testusedentity" + ] + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn derive_entity_quotation() { + let mut api = test_api().await; + + let identity = AuthId::chronicle(); + + insta::assert_json_snapshot!( + api.dispatch(ApiCommand::Entity(EntityCommand::Derive { + id: EntityId::from_external_id("testgeneratedentity"), + namespace: "testns".into(), + activity: None, + used_entity: EntityId::from_external_id("testusedentity"), + derivation: DerivationType::Quotation, + }), identity) + .await + .unwrap() + .unwrap() + .0 + .to_json() + .compact_stable_order() + .await + .unwrap(), @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasQuotedFrom": [ + "chronicle:entity:testusedentity" + ] + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} diff --git a/crates/chronicle-test-infrastructure/src/cli_test.rs b/crates/chronicle-test-infrastructure/src/cli_test.rs new file mode 100644 index 000000000..fae005c26 --- /dev/null +++ b/crates/chronicle-test-infrastructure/src/cli_test.rs @@ -0,0 +1,796 @@ +use api::{ + commands::{ApiCommand}, +}; +use chronicle::{ + bootstrap::{CliModel, SubCommand}, + codegen::ChronicleDomainDef, + PrimitiveType, +}; + +use common::{ + identity::AuthId, + prov::{ + json_ld::ToJson, ActivityId, AgentId, ChronicleIri, EntityId, + ProvModel, + }, +}; + + +use crate::substitutes::test_api; + +fn get_api_cmd(command_line: &str) -> ApiCommand { + let cli = test_cli_model(); + let matches = cli.as_cmd().get_matches_from(command_line.split_whitespace()); + cli.matches(&matches).unwrap().unwrap() +} + +async fn parse_and_execute(command_line: &str, cli: CliModel) -> Box { + let mut api = test_api().await; + + let matches = cli.as_cmd().get_matches_from(command_line.split_whitespace()); + + let cmd = cli.matches(&matches).unwrap().unwrap(); + + let identity = AuthId::chronicle(); + + api.dispatch(cmd, identity).await.unwrap().unwrap().0 +} + +fn test_cli_model() -> CliModel { + CliModel::from( + ChronicleDomainDef::build("test") + .with_attribute_type("testString", None, PrimitiveType::String) + .unwrap() + .with_attribute_type("testBool", None, PrimitiveType::Bool) + .unwrap() + .with_attribute_type("testInt", None, PrimitiveType::Int) + .unwrap() + .with_attribute_type("testJSON", None, PrimitiveType::JSON) + .unwrap() + .with_activity("testActivity", None, |b| { + b.with_attribute("testString") + .unwrap() + .with_attribute("testBool") + .unwrap() + .with_attribute("testInt") + }) + .unwrap() + .with_agent("testAgent", None, |b| { + b.with_attribute("testString") + .unwrap() + .with_attribute("testBool") + .unwrap() + .with_attribute("testInt") + }) + .unwrap() + .with_entity("testEntity", None, |b| { + b.with_attribute("testString") + .unwrap() + .with_attribute("testBool") + .unwrap() + .with_attribute("testInt") + }) + .unwrap() + .build(), + ) +} + +#[tokio::test] +async fn agent_define() { + let command_line = r#"chronicle test-agent-agent define test_agent --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns "#; + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &parse_and_execute(command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:test%5Fagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:testAgent" + ], + "externalId": "test_agent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": false, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn agent_define_id() { + let id = ChronicleIri::from(common::prov::AgentId::from_external_id("test_agent")); + let command_line = format!( + r#"chronicle test-agent-agent define --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns --id {id} "# + ); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &parse_and_execute(&command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:test%5Fagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:testAgent" + ], + "externalId": "test_agent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": false, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn agent_use() { + let mut api = test_api().await; + + // note, if you don't supply all three types of attribute this won't run + let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 23 "#; + + let cmd = get_api_cmd(command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:agent:testagent", + "@type": [ + "prov:Agent", + "chronicle:domaintype:testAgent" + ], + "externalId": "testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": true, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); + + let id = AgentId::from_external_id("testagent"); + + let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); + let cmd = get_api_cmd(&command_line); + + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let id = ActivityId::from_external_id("testactivity"); + let command_line = format!( + r#"chronicle test-activity-activity start {id} --namespace testns --time 2014-07-08T09:10:11Z "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "startTime": "2014-07-08T09:10:11+00:00", + "value": {}, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn entity_define() { + let command_line = r#"chronicle test-entity-entity define test_entity --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns "#; + let _delta = parse_and_execute(command_line, test_cli_model()); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &parse_and_execute(command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:test%5Fentity", + "@type": [ + "prov:Entity", + "chronicle:domaintype:testEntity" + ], + "externalId": "test_entity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": false, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn entity_define_id() { + let id = ChronicleIri::from(common::prov::EntityId::from_external_id("test_entity")); + let command_line = format!( + r#"chronicle test-entity-entity define --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns --id {id} "# + ); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &parse_and_execute(&command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:test%5Fentity", + "@type": [ + "prov:Entity", + "chronicle:domaintype:testEntity" + ], + "externalId": "test_entity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": false, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn entity_derive_abstract() { + let mut api = test_api().await; + + let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); + let used_entity_id = EntityId::from_external_id("testusedentity"); + + let command_line = format!( + r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasDerivedFrom": [ + "chronicle:entity:testusedentity" + ] + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn entity_derive_primary_source() { + let mut api = test_api().await; + + let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); + let used_entity_id = EntityId::from_external_id("testusedentity"); + + let command_line = format!( + r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns --subtype primary-source "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "hadPrimarySource": [ + "chronicle:entity:testusedentity" + ], + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn entity_derive_revision() { + let mut api = test_api().await; + + let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); + let used_entity_id = EntityId::from_external_id("testusedentity"); + + let command_line = format!( + r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns --subtype revision "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasRevisionOf": [ + "chronicle:entity:testusedentity" + ] + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn entity_derive_quotation() { + let mut api = test_api().await; + + let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); + let used_entity_id = EntityId::from_external_id("testusedentity"); + + let command_line = format!( + r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns --subtype quotation "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testgeneratedentity", + "@type": "prov:Entity", + "externalId": "testgeneratedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasQuotedFrom": [ + "chronicle:entity:testusedentity" + ] + }, + { + "@id": "chronicle:entity:testusedentity", + "@type": "prov:Entity", + "externalId": "testusedentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_define() { + let command_line = r#"chronicle test-activity-activity define test_activity --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns "#; + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &parse_and_execute(command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:test%5Factivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:testActivity" + ], + "externalId": "test_activity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": false, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_define_id() { + let id = ChronicleIri::from(common::prov::ActivityId::from_external_id("test_activity")); + let command_line = format!( + r#"chronicle test-activity-activity define --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns --id {id} "# + ); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &parse_and_execute(&command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:test%5Factivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:testActivity" + ], + "externalId": "test_activity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": { + "TestBool": false, + "TestInt": 23, + "TestString": "test" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_start() { + let mut api = test_api().await; + + let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; + let cmd = get_api_cmd(command_line); + + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let id = ChronicleIri::from(AgentId::from_external_id("testagent")); + let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); + let cmd = get_api_cmd(&command_line); + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let id = ChronicleIri::from(ActivityId::from_external_id("testactivity")); + let command_line = format!( + r#"chronicle test-activity-activity start {id} --namespace testns --time 2014-07-08T09:10:11Z "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:qualifiedAssociation": { + "@id": "chronicle:association:testagent:testactivity:role=" + }, + "startTime": "2014-07-08T09:10:11+00:00", + "value": {}, + "wasAssociatedWith": [ + "chronicle:agent:testagent" + ] + }, + { + "@id": "chronicle:association:testagent:testactivity:role=", + "@type": "prov:Association", + "agent": "chronicle:agent:testagent", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "prov:hadActivity": { + "@id": "chronicle:activity:testactivity" + } + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_end() { + let mut api = test_api().await; + + let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; + let cmd = get_api_cmd(command_line); + + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let id = ChronicleIri::from(AgentId::from_external_id("testagent")); + let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); + let cmd = get_api_cmd(&command_line); + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let id = ChronicleIri::from(ActivityId::from_external_id("testactivity")); + let command_line = format!( + r#"chronicle test-activity-activity start {id} --namespace testns --time 2014-07-08T09:10:11Z "# + ); + let cmd = get_api_cmd(&command_line); + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + // Should end the last opened activity + let id = ActivityId::from_external_id("testactivity"); + let command_line = format!( + r#"chronicle test-activity-activity end --namespace testns --time 2014-08-09T09:10:12Z {id} "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": "prov:Activity", + "endTime": "2014-08-09T09:10:12+00:00", + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "startTime": "2014-07-08T09:10:11+00:00", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_generate() { + let mut api = test_api().await; + + let command_line = r#"chronicle test-activity-activity define testactivity --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; + let cmd = get_api_cmd(command_line); + + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let activity_id = ActivityId::from_external_id("testactivity"); + let entity_id = EntityId::from_external_id("testentity"); + let command_line = format!( + r#"chronicle test-activity-activity generate --namespace testns {entity_id} {activity_id} "# + ); + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:entity:testentity", + "@type": "prov:Entity", + "externalId": "testentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {}, + "wasGeneratedBy": [ + "chronicle:activity:testactivity" + ] + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} + +#[tokio::test] +async fn activity_use() { + let mut api = test_api().await; + + let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; + let cmd = get_api_cmd(command_line); + + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let id = ChronicleIri::from(AgentId::from_external_id("testagent")); + let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); + let cmd = get_api_cmd(&command_line); + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let command_line = r#"chronicle test-activity-activity define testactivity --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; + let cmd = get_api_cmd(command_line); + api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); + + let activity_id = ActivityId::from_external_id("testactivity"); + let entity_id = EntityId::from_external_id("testentity"); + let command_line = format!( + r#"chronicle test-activity-activity use --namespace testns {entity_id} {activity_id} "# + ); + + let cmd = get_api_cmd(&command_line); + + insta::assert_snapshot!( + serde_json::to_string_pretty( + &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() + ).unwrap() , @r###" + { + "@context": "https://btp.works/chr/1.0/c.jsonld", + "@graph": [ + { + "@id": "chronicle:activity:testactivity", + "@type": [ + "prov:Activity", + "chronicle:domaintype:testActivity" + ], + "externalId": "testactivity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "used": [ + "chronicle:entity:testentity" + ], + "value": { + "TestBool": true, + "TestInt": 40, + "TestString": "test" + } + }, + { + "@id": "chronicle:entity:testentity", + "@type": "prov:Entity", + "externalId": "testentity", + "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "value": {} + }, + { + "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", + "@type": "chronicle:Namespace", + "externalId": "testns" + } + ] + } + "###); +} diff --git a/crates/chronicle-test-infrastructure/src/lib.rs b/crates/chronicle-test-infrastructure/src/lib.rs new file mode 100644 index 000000000..4cf3d799e --- /dev/null +++ b/crates/chronicle-test-infrastructure/src/lib.rs @@ -0,0 +1,6 @@ +pub mod substitutes; + +#[cfg(test)] +mod api_test; +#[cfg(test)] +mod cli_test; diff --git a/crates/chronicle-test-infrastructure/src/substitutes.rs b/crates/chronicle-test-infrastructure/src/substitutes.rs new file mode 100644 index 000000000..4c2f7c792 --- /dev/null +++ b/crates/chronicle-test-infrastructure/src/substitutes.rs @@ -0,0 +1,153 @@ +use std::sync::Arc; + +use api::{ + commands::{ApiCommand, ApiResponse}, + Api, ApiDispatch, ApiError, UuidGen, +}; +use common::{ + identity::AuthId, + prov::{ChronicleTransactionId, ProvModel}, +}; +use embedded_substrate::EmbeddedSubstrate; +use protocol_substrate::PolkadotConfig; +use uuid::Uuid; + +use chronicle_signing::{ + chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, + CHRONICLE_NAMESPACE, +}; + +use diesel::{r2d2::ConnectionManager, Connection, PgConnection}; +use r2d2::Pool; +use testcontainers::{images::postgres::Postgres, Container}; + +use lazy_static::lazy_static; +use testcontainers::clients; + +lazy_static! { + static ref CLIENT: clients::Cli = clients::Cli::default(); +} + +pub struct TemporaryDatabase<'a> { + db_uris: Vec, + _container: Container<'a, Postgres>, +} + +impl<'a> TemporaryDatabase<'a> { + pub fn connection_pool(&self) -> Result>, r2d2::Error> { + let db_uri = self + .db_uris + .iter() + .find(|db_uri| PgConnection::establish(db_uri).is_ok()) + .expect("cannot establish connection"); + Pool::builder().build(ConnectionManager::::new(db_uri)) + } +} + +impl<'a> Default for TemporaryDatabase<'a> { + fn default() -> Self { + let container = CLIENT.run(Postgres::default()); + const PORT: u16 = 5432; + Self { + db_uris: vec![ + format!("postgresql://postgres@127.0.0.1:{}/", container.get_host_port_ipv4(PORT)), + format!("postgresql://postgres@{}:{}/", container.get_bridge_ip_address(), PORT), + ], + _container: container, + } + } +} + +pub struct TestDispatch<'a> { + api: ApiDispatch, + _db: TemporaryDatabase<'a>, + _substrate: Arc, +} + +impl<'a> TestDispatch<'a> { + pub async fn dispatch( + &mut self, + command: ApiCommand, + identity: AuthId, + ) -> Result, ChronicleTransactionId)>, ApiError> { + // We can sort of get final on chain state here by using a map of subject to model + match self.api.dispatch(command, identity).await? { + ApiResponse::Submission { .. } | ApiResponse::ImportSubmitted { .. } => { + // Recv until we get a commit notification + loop { + let commit = self.api.notify_commit.subscribe().recv().await.unwrap(); + match commit { + common::ledger::SubmissionStage::Submitted(Ok(_)) => continue, + common::ledger::SubmissionStage::Committed(commit, _id) => { + return Ok(Some((commit.delta, commit.tx_id))) + }, + common::ledger::SubmissionStage::Submitted(Err(e)) => panic!("{e:?}"), + common::ledger::SubmissionStage::NotCommitted((_, tx, _id)) => { + panic!("{tx:?}") + }, + } + } + }, + ApiResponse::AlreadyRecorded { subject: _, prov } => { + Ok(Some((prov, ChronicleTransactionId::default()))) + }, + _ => Ok(None), + } + } +} + +#[derive(Debug, Clone)] +struct SameUuid; + +impl UuidGen for SameUuid { + fn uuid() -> Uuid { + Uuid::parse_str("5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea").unwrap() + } +} + +pub async fn embed_substrate() -> Arc { + chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); + + embedded_substrate::shared_dev_node_rpc_on_arbitrary_port().await.unwrap() +} + +pub async fn test_api<'a>() -> TestDispatch<'a> { + chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); + + let secrets = ChronicleSigning::new( + chronicle_secret_names(), + vec![ + (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), + (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), + ], + ) + .await + .unwrap(); + + let embed_substrate = embed_substrate().await; + let database = TemporaryDatabase::default(); + let pool = database.connection_pool().unwrap(); + + let liveness_check_interval = None; + + //Do not keep these live once used by test + embedded_substrate::remove_shared_substrate(&embed_substrate); + + let dispatch = Api::new( + pool, + embed_substrate.connect_chronicle::().await.unwrap(), + SameUuid, + secrets, + vec![], + None, + liveness_check_interval, + ) + .await + .unwrap(); + + TestDispatch { + api: dispatch, + _db: database, // share the lifetime + _substrate: embed_substrate, + } +} diff --git a/crates/chronicle/Cargo.toml b/crates/chronicle/Cargo.toml index 53f5d52ed..7ae6ab020 100644 --- a/crates/chronicle/Cargo.toml +++ b/crates/chronicle/Cargo.toml @@ -7,61 +7,69 @@ version = "0.7.5" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -Inflector = { workspace = true } -api = { path = "../api" } -async-graphql = { workspace = true } -async-stl-client = { workspace = true } -cfg-if = { workspace = true } -chronicle-protocol = { path = "../chronicle-protocol" } -chronicle-signing = { workspace = true } +Inflector = { workspace = true } +api = { path = "../api" } +async-graphql = { workspace = true } +async-trait = { workspace = true } +cfg-if = { workspace = true } +chronicle-signing = { workspace = true } chronicle-telemetry = { path = "../chronicle-telemetry" } -chrono = { workspace = true, features = ["serde"] } -clap = { workspace = true, features = ["derive", "env"] } -clap_complete = { workspace = true } -colored_json = { workspace = true } -common = { path = "../common" } -const_format = { workspace = true } -diesel = { workspace = true } -dotenvy = { workspace = true } -futures = { workspace = true } -genco = { workspace = true } -hex = { workspace = true } -iref = { workspace = true } -is-terminal = { workspace = true } -jsonschema = { workspace = true } -opa = { workspace = true } -opentelemetry = { workspace = true } -percent-encoding = { workspace = true } -question = { workspace = true } -rand = { workspace = true } -rand_core = { workspace = true } -serde = { workspace = true } -serde_derive = { workspace = true } -serde_json = { workspace = true } -serde_yaml = { workspace = true } -shellexpand = { workspace = true } -thiserror = { workspace = true } -tokio = { workspace = true } -toml = { workspace = true } -tracing = { workspace = true } -tracing-log = { workspace = true } -url = { workspace = true, features = ["serde"] } -user-error = { workspace = true } -uuid = { workspace = true } -valico = { workspace = true } +chrono = { workspace = true, features = ["serde"] } +clap = { workspace = true, features = ["derive", "env"] } +clap_complete = { workspace = true } +colored_json = { workspace = true } +common = { path = "../common", features = [ + "json-ld", + "std", + "parity-encoding", +] } +const_format = { workspace = true } +diesel = { workspace = true } +dotenvy = { workspace = true } +embedded-substrate = { path = "../embedded-substrate", optional = true } +futures = { workspace = true } +genco = { workspace = true } +hex = { workspace = true } +iri-string = { version = "0.7", default-features = false, features = ["alloc"] } +is-terminal = { workspace = true } +jsonschema = { workspace = true } +opa = { workspace = true } +opentelemetry = { workspace = true } +percent-encoding = { workspace = true } +protocol-substrate = { path = "../protocol-substrate" } +protocol-substrate-chronicle = { path = "../protocol-substrate-chronicle" } +protocol-substrate-opa = { path = "../protocol-substrate-opa" } +question = { workspace = true } +rand = { workspace = true } +rand_core = { workspace = true } +serde = { workspace = true } +serde_derive = { workspace = true } +serde_json = { workspace = true } +serde_yaml = { workspace = true } +shellexpand = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +toml = { workspace = true } +tracing = { workspace = true } +tracing-log = { workspace = true } +url = { workspace = true, features = ["serde"] } +user-error = { workspace = true } +uuid = { workspace = true } +valico = { workspace = true } [features] -devmode = ["inmem"] -# Use an in-memory stub ledger -inmem = [] -strict = [] +devmode = ["dep:embedded-substrate"] +strict = [] [build-dependencies] [dev-dependencies] -assert_fs = { workspace = true } -chronicle-protocol = { path = "../chronicle-protocol" } -insta = { workspace = true, features = ["yaml"] } -opa-tp-protocol = { path = "../opa-tp-protocol" } -sawtooth-sdk = { workspace = true } -tempfile = { workspace = true } +assert_fs = { workspace = true } +embedded-substrate = { path = "../embedded-substrate" } +insta = { workspace = true, features = ["yaml"] } +mockito = { version = "*" } +protocol-abstract = { path = "../protocol-abstract" } +protocol-substrate = { path = "../protocol-substrate" } +protocol-substrate-chronicle = { path = "../protocol-substrate-chronicle" } +protocol-substrate-opa = { path = "../protocol-substrate-opa" } +tempfile = { workspace = true } diff --git a/crates/chronicle/src/bootstrap/cli.rs b/crates/chronicle/src/bootstrap/cli.rs index d7a934c78..b00d54418 100644 --- a/crates/chronicle/src/bootstrap/cli.rs +++ b/crates/chronicle/src/bootstrap/cli.rs @@ -1,7 +1,9 @@ use std::{collections::BTreeMap, convert::Infallible}; -use api::ApiError; -use chronicle_protocol::async_stl_client::error::SawtoothCommunicationError; +use api::{ + commands::{ActivityCommand, AgentCommand, ApiCommand, EntityCommand}, + ApiError, +}; use chronicle_signing::SecretError; use clap::{ builder::{PossibleValuesParser, StringValueParser}, @@ -9,15 +11,13 @@ use clap::{ }; use common::{ attributes::{Attribute, Attributes}, - commands::{ActivityCommand, AgentCommand, ApiCommand, EntityCommand}, - import::FromUrlError, - opa::{OpaExecutorError, PolicyLoaderError}, + opa::std::{FromUrlError, OpaExecutorError, PolicyLoaderError}, prov::{ - operations::DerivationType, ActivityId, AgentId, CompactionError, DomaintypeId, EntityId, - ExternalId, ExternalIdPart, ParseIriError, + json_ld::CompactionError, operations::DerivationType, ActivityId, AgentId, DomaintypeId, + EntityId, ExternalId, ExternalIdPart, ParseIriError, }, }; -use iref::Iri; +use protocol_substrate::SubxtClientError; use thiserror::Error; use tokio::sync::broadcast::error::RecvError; use tracing::info; @@ -42,7 +42,7 @@ pub enum CliError { ArgumentParsing(#[from] clap::Error), #[error("Invalid IRI: {0}")] - InvalidIri(#[from] iref::Error), + InvalidIri(#[from] iri_string::validate::Error), #[error("Invalid Chronicle IRI: {0}")] InvalidChronicleIri(#[from] ParseIriError), @@ -87,16 +87,19 @@ pub enum CliError { OpaExecutor(#[from] OpaExecutorError), #[error("Sawtooth communication error: {source}")] - SawtoothCommunicationError { + SubstrateError { #[from] - source: SawtoothCommunicationError, + source: SubxtClientError, }, - #[error("Error loading from URL: {0}")] - UrlError(#[from] FromUrlError), - #[error("UTF-8 error: {0}")] Utf8Error(#[from] std::str::Utf8Error), + + #[error("Url conversion: {0}")] + FromUrlError(#[from] FromUrlError), + + #[error("No on chain settings, but they are required by Chronicle")] + NoOnChainSettings, } impl CliError { @@ -114,7 +117,7 @@ impl From for CliError { impl UFE for CliError {} -pub(crate) trait SubCommand { +pub trait SubCommand { fn as_cmd(&self) -> Command; fn matches(&self, matches: &ArgMatches) -> Result, CliError>; } @@ -174,13 +177,12 @@ fn name_from<'a, Id>( id_param: &str, ) -> Result where - Id: 'a + TryFrom, Error = ParseIriError> + ExternalIdPart, + Id: 'a + TryFrom + ExternalIdPart, { if let Some(external_id) = args.get_one::(name_param) { Ok(ExternalId::from(external_id)) - } else if let Some(id) = args.get_one::(id_param) { - let iri = Iri::from_str(id)?; - let id = Id::try_from(iri)?; + } else if let Some(iri) = args.get_one::(id_param) { + let id = Id::try_from(iri.to_string())?; Ok(id.external_id_part().to_owned()) } else { Err(CliError::MissingArgument { arg: format!("Missing {name_param} and {id_param}") }) @@ -189,10 +191,10 @@ where fn id_from<'a, Id>(args: &'a ArgMatches, id_param: &str) -> Result where - Id: 'a + TryFrom, Error = ParseIriError> + ExternalIdPart, + Id: 'a + TryFrom + ExternalIdPart, { if let Some(id) = args.get_one::(id_param) { - Ok(Id::try_from(Iri::from_str(id)?)?) + Ok(Id::try_from(id.to_string())?) } else { Err(CliError::MissingArgument { arg: format!("Missing {id_param} ") }) } @@ -200,7 +202,7 @@ where fn id_from_option<'a, Id>(args: &'a ArgMatches, id_param: &str) -> Result, CliError> where - Id: 'a + TryFrom, Error = ParseIriError> + ExternalIdPart, + Id: 'a + TryFrom + ExternalIdPart, { match id_from(args, id_param) { Err(CliError::MissingArgument { .. }) => Ok(None), @@ -295,7 +297,7 @@ fn attributes_from( )?; Ok::<_, CliError>(( attr.attribute.as_type_name(), - Attribute { typ: attr.attribute.as_type_name(), value }, + Attribute { typ: attr.attribute.as_type_name(), value: value.into() }, )) }) .collect::, _>>()?, @@ -357,14 +359,14 @@ impl SubCommand for AgentCliModel { external_id: name_from::(matches, "external_id", "id")?, namespace: namespace_from(matches)?, attributes: attributes_from(matches, &self.agent.external_id, &self.attributes)?, - }))) + }))); } if let Some(matches) = matches.subcommand_matches("use") { return Ok(Some(ApiCommand::Agent(AgentCommand::UseInContext { id: id_from(matches, "id")?, namespace: namespace_from(matches)?, - }))) + }))); }; Ok(None) @@ -569,7 +571,7 @@ impl SubCommand for ActivityCliModel { external_id: name_from::(matches, "external_id", "id")?, namespace: namespace_from(matches)?, attributes: attributes_from(matches, &self.activity.external_id, &self.attributes)?, - }))) + }))); } if let Some(matches) = matches.subcommand_matches("start") { @@ -578,7 +580,7 @@ impl SubCommand for ActivityCliModel { namespace: namespace_from(matches)?, time: matches.get_one::("time").map(|t| t.parse()).transpose()?, agent: id_from_option(matches, "agent_id")?, - }))) + }))); }; if let Some(matches) = matches.subcommand_matches("end") { @@ -587,7 +589,7 @@ impl SubCommand for ActivityCliModel { namespace: namespace_from(matches)?, time: matches.get_one::("time").map(|t| t.parse()).transpose()?, agent: id_from_option(matches, "agent_id")?, - }))) + }))); }; if let Some(matches) = matches.subcommand_matches("instant") { @@ -596,7 +598,7 @@ impl SubCommand for ActivityCliModel { namespace: namespace_from(matches)?, time: matches.get_one::("time").map(|t| t.parse()).transpose()?, agent: id_from_option(matches, "agent_id")?, - }))) + }))); }; if let Some(matches) = matches.subcommand_matches("use") { @@ -604,7 +606,7 @@ impl SubCommand for ActivityCliModel { id: id_from(matches, "entity_id")?, namespace: namespace_from(matches)?, activity: id_from(matches, "activity_id")?, - }))) + }))); }; if let Some(matches) = matches.subcommand_matches("generate") { @@ -612,7 +614,7 @@ impl SubCommand for ActivityCliModel { id: id_from(matches, "entity_id")?, namespace: namespace_from(matches)?, activity: id_from(matches, "activity_id")?, - }))) + }))); }; Ok(None) @@ -725,7 +727,7 @@ impl SubCommand for EntityCliModel { external_id: name_from::(matches, "external_id", "id")?, namespace: namespace_from(matches)?, attributes: attributes_from(matches, &self.entity.external_id, &self.attributes)?, - }))) + }))); } if let Some(matches) = matches.subcommand_matches("derive") { @@ -743,7 +745,7 @@ impl SubCommand for EntityCliModel { .unwrap_or(DerivationType::None), activity: id_from_option(matches, "activity_id")?, used_entity: id_from(matches, "used_entity_id")?, - }))) + }))); } Ok(None) @@ -761,7 +763,7 @@ pub const LONG_VERSION: &str = const_format::formatcp!( "{}:{} ({})", env!("CARGO_PKG_VERSION"), include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../.VERSION")), - if cfg!(feature = "inmem") { "in memory" } else { "sawtooth" } + if cfg!(feature = "devmode") { "in memory" } else { "substrate" } ); impl From for CliModel { @@ -982,7 +984,7 @@ impl SubCommand for CliModel { app = app.subcommand(entity.as_cmd()); } - #[cfg(not(feature = "inmem"))] + #[cfg(not(feature = "devmode"))] { app = app.arg( Arg::new("batcher-key-from-path") @@ -1068,11 +1070,11 @@ impl SubCommand for CliModel { app.arg( // default is provided by cargo.toml - Arg::new("sawtooth") - .long("sawtooth") - .value_name("sawtooth") + Arg::new("validator") + .long("validator") + .value_name("validator") .value_hint(ValueHint::Url) - .help("Sets sawtooth validator address") + .help("Sets validator address") .takes_value(true), ) .arg( @@ -1084,7 +1086,7 @@ impl SubCommand for CliModel { ), ) } - #[cfg(feature = "inmem")] + #[cfg(feature = "devmode")] { app } @@ -1096,14 +1098,14 @@ impl SubCommand for CliModel { matches.subcommand_matches(&agent.external_id).map(|matches| (agent, matches)) }) { if let Some(cmd) = agent.matches(matches)? { - return Ok(Some(cmd)) + return Ok(Some(cmd)); } } for (entity, matches) in self.entities.iter().filter_map(|entity| { matches.subcommand_matches(&entity.external_id).map(|matches| (entity, matches)) }) { if let Some(cmd) = entity.matches(matches)? { - return Ok(Some(cmd)) + return Ok(Some(cmd)); } } for (activity, matches) in self.activities.iter().filter_map(|activity| { @@ -1112,7 +1114,7 @@ impl SubCommand for CliModel { .map(|matches| (activity, matches)) }) { if let Some(cmd) = activity.matches(matches)? { - return Ok(Some(cmd)) + return Ok(Some(cmd)); } } Ok(None) diff --git a/crates/chronicle/src/bootstrap/mod.rs b/crates/chronicle/src/bootstrap/mod.rs index c0b2c5fde..4423ce323 100644 --- a/crates/chronicle/src/bootstrap/mod.rs +++ b/crates/chronicle/src/bootstrap/mod.rs @@ -1,18 +1,24 @@ mod cli; -mod opa; - -#[cfg(feature = "inmem")] -use api::inmem::EmbeddedChronicleTp; +pub mod opa; use api::{ chronicle_graphql::{ChronicleApiServer, ChronicleGraphQl, JwksUri, SecurityConf, UserInfoUri}, + commands::ApiResponse, + database::{get_connection_with_retry, DatabaseConnector}, Api, ApiDispatch, ApiError, StoreError, UuidGen, }; use async_graphql::{async_trait, ObjectType}; -#[cfg(not(feature = "inmem"))] -use chronicle_protocol::{ - address::{FAMILY, VERSION}, - ChronicleLedger, +use common::{ + opa::{ + std::{load_bytes_from_stdin, load_bytes_from_url}, + PolicyAddress, + }, + prov::json_ld::ToJson, }; +#[cfg(feature = "devmode")] +use embedded_substrate::EmbeddedSubstrate; +#[cfg(not(feature = "devmode"))] +use protocol_substrate_chronicle::ChronicleSubstrateClient; + use chronicle_signing::{ chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, CHRONICLE_NAMESPACE, @@ -21,20 +27,12 @@ use clap::{ArgMatches, Command}; use clap_complete::{generate, Generator, Shell}; pub use cli::*; use common::{ - commands::ApiResponse, - database::{get_connection_with_retry, DatabaseConnector}, identity::AuthId, - import::{load_bytes_from_stdin, load_bytes_from_url}, - k256::{ - pkcs8::{EncodePrivateKey, LineEnding}, - SecretKey, - }, ledger::SubmissionStage, - opa::ExecutorContext, - prov::{operations::ChronicleOperation, to_json_ld::ToJson, NamespaceId}, + opa::{std::ExecutorContext, OpaSettings}, + prov::{operations::ChronicleOperation, NamespaceId}, }; -use rand::rngs::StdRng; -use rand_core::SeedableRng; + use std::io::IsTerminal; use tracing::{debug, error, info, instrument, warn}; use user_error::UFE; @@ -49,10 +47,8 @@ use url::Url; use std::{ collections::{BTreeSet, HashMap}, - fs::File, - io::{self, Write}, + io::{self}, net::{SocketAddr, ToSocketAddrs}, - path::PathBuf, str::FromStr, }; @@ -60,47 +56,47 @@ use crate::codegen::ChronicleDomainDef; use self::opa::opa_executor_from_embedded_policy; -#[cfg(not(feature = "inmem"))] -fn sawtooth_address(options: &ArgMatches) -> Result, CliError> { +#[cfg(not(feature = "devmode"))] +fn validator_address(options: &ArgMatches) -> Result, CliError> { Ok(options - .value_of("sawtooth") + .value_of("validator") .map(str::to_string) - .ok_or(CliError::MissingArgument { arg: "sawtooth".to_owned() }) + .ok_or(CliError::MissingArgument { arg: "validator".to_owned() }) .and_then(|s| Url::parse(&s).map_err(CliError::from)) .map(|u| u.socket_addrs(|| Some(4004))) .map_err(CliError::from)??) } #[allow(dead_code)] -#[cfg(not(feature = "inmem"))] -fn ledger(options: &ArgMatches) -> Result { - use async_stl_client::zmq_client::{ - HighestBlockValidatorSelector, ZmqRequestResponseSawtoothChannel, - }; +#[cfg(not(feature = "devmode"))] +async fn ledger( + options: &ArgMatches, +) -> Result, CliError> { + let url = options + .value_of("validator") + .map(str::to_string) + .ok_or_else(|| CliError::MissingArgument { arg: "validator".to_owned() })?; - Ok(ChronicleLedger::new( - ZmqRequestResponseSawtoothChannel::new( - "inmem", - &sawtooth_address(options)?, - HighestBlockValidatorSelector, - )? - .retrying(), - FAMILY, - VERSION, - )) -} + let url = Url::parse(&url).map_err(CliError::from)?; -#[allow(dead_code)] -fn in_mem_ledger( - _options: &ArgMatches, -) -> Result { - Ok(crate::api::inmem::EmbeddedChronicleTp::new()?) + let addrs = url.socket_addrs(|| Some(9944)).map_err(CliError::from)?; + + let client = ChronicleSubstrateClient::::connect( + addrs[0].to_string(), + ) + .await?; + + Ok(client) } -#[cfg(feature = "inmem")] #[allow(dead_code)] -fn ledger() -> Result { - Ok(EmbeddedChronicleTp::new()?) +#[cfg(feature = "devmode")] +async fn in_mem_ledger( + _options: &ArgMatches, +) -> Result, ApiError> { + embedded_substrate::shared_dev_node_rpc_on_arbitrary_port() + .await + .map_err(|e| ApiError::EmbeddedSubstrate(e.into())) } #[derive(Debug, Clone)] @@ -192,8 +188,11 @@ fn vault_secrets_options(options: &ArgMatches) -> Result Result { // Determine batcher configuration + + use std::path::PathBuf; let batcher_options = match ( options.get_one::("batcher-key-from-path"), options.get_flag("batcher-key-from-vault"), @@ -226,14 +225,26 @@ async fn chronicle_signing(options: &ArgMatches) -> Result Result { + Ok(ChronicleSigning::new( + chronicle_secret_names(), + vec![ + (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), + (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), + ], + ) + .await?) +} + +#[cfg(not(feature = "devmode"))] pub async fn api( pool: &ConnectionPool, options: &ArgMatches, - policy_name: Option, + policy_address: Option, liveness_check_interval: Option, ) -> Result { - let ledger = ledger(options)?; + let ledger = ledger(options).await?; Ok(Api::new( pool.clone(), @@ -241,24 +252,26 @@ pub async fn api( UniqueUuid, chronicle_signing(options).await?, namespace_bindings(options), - policy_name, + policy_address, liveness_check_interval, ) .await?) } -#[cfg(feature = "inmem")] +#[cfg(feature = "devmode")] pub async fn api( pool: &ConnectionPool, options: &ArgMatches, - remote_opa: Option, + remote_opa: Option, liveness_check_interval: Option, ) -> Result { - let embedded_tp = in_mem_ledger(options)?; + use protocol_substrate::PolkadotConfig; + + let embedded_tp = in_mem_ledger(options).await?; Ok(Api::new( pool.clone(), - embedded_tp.ledger, + embedded_tp.connect_chronicle::().await?, UniqueUuid, chronicle_signing(options).await?, vec![], @@ -302,7 +315,7 @@ fn construct_db_uri(matches: &ArgMatches) -> String { #[derive(Debug, Clone)] pub enum ConfiguredOpa { Embedded(ExecutorContext), - Remote(ExecutorContext, chronicle_protocol::settings::OpaSettings), + Remote(ExecutorContext, OpaSettings), Url(ExecutorContext), } @@ -315,19 +328,19 @@ impl ConfiguredOpa { } } - pub fn remote_settings(&self) -> Option { + pub fn remote_settings(&self) -> Option { match self { ConfiguredOpa::Embedded(_) => None, - ConfiguredOpa::Remote(_, settings) => Some(settings.policy_name.clone()), + ConfiguredOpa::Remote(_, settings) => Some(settings.policy_address), ConfiguredOpa::Url(_) => None, } } } /// If embedded-opa-policy is set, we will use the embedded policy, otherwise we -/// attempt to load it from sawtooth settings. If we are running in inmem mode, +/// attempt to load it from sawtooth settings. If we are running in development mode, /// then always use embedded policy -#[cfg(feature = "inmem")] +#[cfg(feature = "devmode")] #[allow(unused_variables)] async fn configure_opa(options: &ArgMatches) -> Result { let (default_policy_name, entrypoint) = @@ -336,7 +349,25 @@ async fn configure_opa(options: &ArgMatches) -> Result Ok(ConfiguredOpa::Embedded(opa)) } -#[cfg(not(feature = "inmem"))] +// Check if the `embedded-opa-policy` flag is present in the CLI options. +// If it is, this means the user wants to use an embedded OPA policy. +// We then define the default policy name and entrypoint to be used, +// and attempt to load the OPA executor with this embedded policy. +// A warning is logged to indicate that Chronicle is operating in an insecure mode +// with an embedded default OPA policy. +// If the `embedded-opa-policy` flag is not present, we then check if the `opa-bundle-address` +// is provided. If it is, this means the user wants to load the OPA policy from a specified URL. +// We extract the policy name and entrypoint from the CLI options and attempt to load the OPA +// executor from the provided URL. A log is recorded to indicate that Chronicle is operating +// with an OPA policy loaded from a URL. +// If neither `embedded-opa-policy` nor `opa-bundle-address` is provided, we attempt to load the +// OPA executor from the substrate state. This involves connecting to the substrate client using +// the validator address provided in the CLI options and loading the OPA executor and settings +// from there. If settings are found, a log is recorded to indicate that Chronicle is operating +// in a secure mode with an on-chain OPA policy. Otherwise, a warning is logged to indicate an +// insecure mode of operation, and an attempt is made to load the OPA executor with an embedded +// default policy. +#[cfg(not(feature = "devmode"))] #[instrument(skip(options))] async fn configure_opa(options: &ArgMatches) -> Result { if options.is_present("embedded-opa-policy") { @@ -357,11 +388,29 @@ async fn configure_opa(options: &ArgMatches) -> Result Ok(ConfiguredOpa::Url(opa)) } else { - let (opa, settings) = - self::opa::opa_executor_from_sawtooth_settings(&sawtooth_address(options)?).await?; - tracing::info!(use_on_chain_opa= ?settings, "Chronicle operating in secure mode with on chain OPA policy"); + let (opa, settings) = self::opa::opa_executor_from_substrate_state( + &ChronicleSubstrateClient::connect_socket_addr(validator_address(options)?[0]).await?, + &protocol_substrate_opa::OpaSubstrateClient::connect_socket_addr( + validator_address(options)?[0], + ) + .await?, + ) + .await?; - Ok(ConfiguredOpa::Remote(opa, settings)) + if let Some(settings) = settings { + tracing::info!(use_on_chain_opa= ?settings, "Chronicle operating in secure mode with on chain OPA policy"); + Ok(ConfiguredOpa::Remote(opa, settings)) + } else { + tracing::warn!( + "Chronicle operating in an insecure mode with an embedded default OPA policy" + ); + tracing::warn!(use_on_chain_opa= ?settings, "Chronicle operating in secure mode with on chain OPA policy"); + let (default_policy_name, entrypoint) = + ("allow_transactions", "allow_transactions.allowed_users"); + let opa = opa_executor_from_embedded_policy(default_policy_name, entrypoint).await?; + + Ok(ConfiguredOpa::Embedded(opa)) + } } } @@ -380,7 +429,7 @@ fn configure_depth_charge(matches: &ArgMatches) -> Option { } else { debug!("Using custom liveness health check interval value: {parsed_interval}"); } - return Some(parsed_interval) + return Some(parsed_interval); } } debug!("Liveness health check disabled"); @@ -498,7 +547,7 @@ where if data.trim().is_empty() { eprintln!("Import data is empty, nothing to import"); - return Ok((ApiResponse::Unit, ret_api)) + return Ok((ApiResponse::Unit, ret_api)); } let json_array = serde_json::from_str::>(data)?; @@ -714,21 +763,6 @@ pub async fn bootstrap( }, ); - if matches.subcommand_matches("generate-key").is_some() { - let key = SecretKey::random(StdRng::from_entropy()); - let key = key.to_pkcs8_pem(LineEnding::CRLF).unwrap(); - - if let Some(path) = matches.get_one::("output") { - //TODO - clean up these unwraps, they always come up with fs / cli - let mut file = File::create(path).unwrap(); - file.write_all(key.as_bytes()).unwrap(); - } else { - print!("{}", *key); - } - - std::process::exit(0); - } - config_and_exec(gql, domain.into()) .await .map_err(|e| { @@ -740,931 +774,3 @@ pub async fn bootstrap( std::process::exit(0); } - -/// We can only sensibly test subcommand parsing for the CLI's PROV actions, -/// configuration + server execution would get a little tricky in the context of a unit test. -#[cfg(test)] -pub mod test { - use api::{inmem::EmbeddedChronicleTp, Api, ApiDispatch, ApiError, UuidGen}; - use async_stl_client::prost::Message; - use chronicle_signing::{ - chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, - CHRONICLE_NAMESPACE, - }; - use common::{ - commands::{ApiCommand, ApiResponse}, - database::TemporaryDatabase, - identity::AuthId, - k256::sha2::{Digest, Sha256}, - ledger::SubmissionStage, - prov::{ - to_json_ld::ToJson, ActivityId, AgentId, ChronicleIri, ChronicleTransactionId, - EntityId, ProvModel, - }, - }; - use opa_tp_protocol::state::{policy_address, policy_meta_address, PolicyMeta}; - use uuid::Uuid; - - use super::{CliModel, SubCommand}; - use crate::codegen::ChronicleDomainDef; - - struct TestDispatch<'a> { - api: ApiDispatch, - _db: TemporaryDatabase<'a>, // share lifetime - _tp: EmbeddedChronicleTp, - } - - impl TestDispatch<'_> { - pub async fn dispatch( - &mut self, - command: ApiCommand, - identity: AuthId, - ) -> Result, ChronicleTransactionId)>, ApiError> { - // We can sort of get final on chain state here by using a map of subject to model - if let ApiResponse::Submission { .. } = self.api.dispatch(command, identity).await? { - loop { - let submission = self - .api - .notify_commit - .subscribe() - .recv() - .await - .expect("failed to receive response to submission"); - - if let SubmissionStage::Committed(commit, _) = submission { - break Ok(Some((commit.delta, commit.tx_id))) - } - if let SubmissionStage::NotCommitted((_, contradiction, _)) = submission { - panic!("Contradiction: {contradiction}"); - } - } - } else { - Ok(None) - } - } - } - - #[derive(Debug, Clone)] - struct SameUuid; - - impl UuidGen for SameUuid { - fn uuid() -> Uuid { - Uuid::parse_str("5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea").unwrap() - } - } - - async fn test_api<'a>() -> TestDispatch<'a> { - chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); - - let secrets = ChronicleSigning::new( - chronicle_secret_names(), - vec![ - (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), - (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::generate_in_memory()), - ], - ) - .await - .unwrap(); - - let buf = async_stl_client::messages::Setting { - entries: vec![async_stl_client::messages::setting::Entry { - key: "chronicle.opa.policy_name".to_string(), - value: "allow_transactions".to_string(), - }], - } - .encode_to_vec(); - let setting_id = ( - chronicle_protocol::settings::sawtooth_settings_address("chronicle.opa.policy_name"), - buf, - ); - let buf = async_stl_client::messages::Setting { - entries: vec![async_stl_client::messages::setting::Entry { - key: "chronicle.opa.entrypoint".to_string(), - value: "allow_transactions.allowed_users".to_string(), - }], - } - .encode_to_vec(); - - let setting_entrypoint = ( - chronicle_protocol::settings::sawtooth_settings_address("chronicle.opa.entrypoint"), - buf, - ); - - let d = env!("CARGO_MANIFEST_DIR").to_owned() + "/../../policies/bundle.tar.gz"; - let bin = std::fs::read(d).unwrap(); - - let meta = PolicyMeta { - id: "allow_transactions".to_string(), - hash: hex::encode(Sha256::digest(&bin)), - policy_address: policy_address("allow_transactions"), - }; - - let embedded_tp = EmbeddedChronicleTp::new_with_state( - vec![ - setting_id, - setting_entrypoint, - (policy_address("allow_transactions"), bin), - (policy_meta_address("allow_transactions"), serde_json::to_vec(&meta).unwrap()), - ] - .into_iter() - .collect(), - ) - .unwrap(); - - let database = TemporaryDatabase::default(); - let pool = database.connection_pool().unwrap(); - - let liveness_check_interval = None; - - let dispatch = Api::new( - pool, - embedded_tp.ledger.clone(), - SameUuid, - secrets, - vec![], - Some("allow_transactions".to_owned()), - liveness_check_interval, - ) - .await - .unwrap(); - - TestDispatch { api: dispatch, _db: database, _tp: embedded_tp } - } - - fn get_api_cmd(command_line: &str) -> ApiCommand { - let cli = test_cli_model(); - let matches = cli.as_cmd().get_matches_from(command_line.split_whitespace()); - cli.matches(&matches).unwrap().unwrap() - } - - async fn parse_and_execute(command_line: &str, cli: CliModel) -> Box { - let mut api = test_api().await; - - let matches = cli.as_cmd().get_matches_from(command_line.split_whitespace()); - - let cmd = cli.matches(&matches).unwrap().unwrap(); - - let identity = AuthId::chronicle(); - - api.dispatch(cmd, identity).await.unwrap().unwrap().0 - } - - fn test_cli_model() -> CliModel { - CliModel::from( - ChronicleDomainDef::build("test") - .with_attribute_type("testString", None, crate::PrimitiveType::String) - .unwrap() - .with_attribute_type("testBool", None, crate::PrimitiveType::Bool) - .unwrap() - .with_attribute_type("testInt", None, crate::PrimitiveType::Int) - .unwrap() - .with_attribute_type("testJSON", None, crate::PrimitiveType::JSON) - .unwrap() - .with_activity("testActivity", None, |b| { - b.with_attribute("testString") - .unwrap() - .with_attribute("testBool") - .unwrap() - .with_attribute("testInt") - }) - .unwrap() - .with_agent("testAgent", None, |b| { - b.with_attribute("testString") - .unwrap() - .with_attribute("testBool") - .unwrap() - .with_attribute("testInt") - }) - .unwrap() - .with_entity("testEntity", None, |b| { - b.with_attribute("testString") - .unwrap() - .with_attribute("testBool") - .unwrap() - .with_attribute("testInt") - }) - .unwrap() - .build(), - ) - } - - #[tokio::test] - async fn agent_define() { - let command_line = r#"chronicle test-agent-agent define test_agent --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns "#; - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &parse_and_execute(command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:test%5Fagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:testAgent" - ], - "externalId": "test_agent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": false, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn agent_define_id() { - let id = ChronicleIri::from(common::prov::AgentId::from_external_id("test_agent")); - let command_line = format!( - r#"chronicle test-agent-agent define --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns --id {id} "# - ); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &parse_and_execute(&command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:test%5Fagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:testAgent" - ], - "externalId": "test_agent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": false, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn agent_use() { - let mut api = test_api().await; - - // note, if you don't supply all three types of attribute this won't run - let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 23 "#; - - let cmd = get_api_cmd(command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:agent:testagent", - "@type": [ - "prov:Agent", - "chronicle:domaintype:testAgent" - ], - "externalId": "testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": true, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - - let id = AgentId::from_external_id("testagent"); - - let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); - let cmd = get_api_cmd(&command_line); - - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let id = ActivityId::from_external_id("testactivity"); - let command_line = format!( - r#"chronicle test-activity-activity start {id} --namespace testns --time 2014-07-08T09:10:11Z "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "startTime": "2014-07-08T09:10:11+00:00", - "value": {}, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn entity_define() { - let command_line = r#"chronicle test-entity-entity define test_entity --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns "#; - let _delta = parse_and_execute(command_line, test_cli_model()); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &parse_and_execute(command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:test%5Fentity", - "@type": [ - "prov:Entity", - "chronicle:domaintype:testEntity" - ], - "externalId": "test_entity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": false, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn entity_define_id() { - let id = ChronicleIri::from(common::prov::EntityId::from_external_id("test_entity")); - let command_line = format!( - r#"chronicle test-entity-entity define --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns --id {id} "# - ); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &parse_and_execute(&command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:test%5Fentity", - "@type": [ - "prov:Entity", - "chronicle:domaintype:testEntity" - ], - "externalId": "test_entity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": false, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn entity_derive_abstract() { - let mut api = test_api().await; - - let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); - let used_entity_id = EntityId::from_external_id("testusedentity"); - - let command_line = format!( - r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasDerivedFrom": [ - "chronicle:entity:testusedentity" - ] - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn entity_derive_primary_source() { - let mut api = test_api().await; - - let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); - let used_entity_id = EntityId::from_external_id("testusedentity"); - - let command_line = format!( - r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns --subtype primary-source "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "hadPrimarySource": [ - "chronicle:entity:testusedentity" - ], - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn entity_derive_revision() { - let mut api = test_api().await; - - let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); - let used_entity_id = EntityId::from_external_id("testusedentity"); - - let command_line = format!( - r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns --subtype revision "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasRevisionOf": [ - "chronicle:entity:testusedentity" - ] - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn entity_derive_quotation() { - let mut api = test_api().await; - - let generated_entity_id = EntityId::from_external_id("testgeneratedentity"); - let used_entity_id = EntityId::from_external_id("testusedentity"); - - let command_line = format!( - r#"chronicle test-entity-entity derive {generated_entity_id} {used_entity_id} --namespace testns --subtype quotation "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testgeneratedentity", - "@type": "prov:Entity", - "externalId": "testgeneratedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasQuotedFrom": [ - "chronicle:entity:testusedentity" - ] - }, - { - "@id": "chronicle:entity:testusedentity", - "@type": "prov:Entity", - "externalId": "testusedentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_define() { - let command_line = r#"chronicle test-activity-activity define test_activity --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns "#; - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &parse_and_execute(command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:test%5Factivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:testActivity" - ], - "externalId": "test_activity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": false, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_define_id() { - let id = ChronicleIri::from(common::prov::ActivityId::from_external_id("test_activity")); - let command_line = format!( - r#"chronicle test-activity-activity define --test-bool-attr false --test-string-attr "test" --test-int-attr 23 --namespace testns --id {id} "# - ); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &parse_and_execute(&command_line, test_cli_model()).await.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:test%5Factivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:testActivity" - ], - "externalId": "test_activity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": { - "TestBool": false, - "TestInt": 23, - "TestString": "test" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_start() { - let mut api = test_api().await; - - let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; - let cmd = get_api_cmd(command_line); - - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let id = ChronicleIri::from(AgentId::from_external_id("testagent")); - let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); - let cmd = get_api_cmd(&command_line); - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let id = ChronicleIri::from(ActivityId::from_external_id("testactivity")); - let command_line = format!( - r#"chronicle test-activity-activity start {id} --namespace testns --time 2014-07-08T09:10:11Z "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:qualifiedAssociation": { - "@id": "chronicle:association:testagent:testactivity:role=" - }, - "startTime": "2014-07-08T09:10:11+00:00", - "value": {}, - "wasAssociatedWith": [ - "chronicle:agent:testagent" - ] - }, - { - "@id": "chronicle:association:testagent:testactivity:role=", - "@type": "prov:Association", - "agent": "chronicle:agent:testagent", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "prov:hadActivity": { - "@id": "chronicle:activity:testactivity" - } - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_end() { - let mut api = test_api().await; - - let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; - let cmd = get_api_cmd(command_line); - - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let id = ChronicleIri::from(AgentId::from_external_id("testagent")); - let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); - let cmd = get_api_cmd(&command_line); - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let id = ChronicleIri::from(ActivityId::from_external_id("testactivity")); - let command_line = format!( - r#"chronicle test-activity-activity start {id} --namespace testns --time 2014-07-08T09:10:11Z "# - ); - let cmd = get_api_cmd(&command_line); - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - // Should end the last opened activity - let id = ActivityId::from_external_id("testactivity"); - let command_line = format!( - r#"chronicle test-activity-activity end --namespace testns --time 2014-08-09T09:10:12Z {id} "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": "prov:Activity", - "endTime": "2014-08-09T09:10:12+00:00", - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "startTime": "2014-07-08T09:10:11+00:00", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_generate() { - let mut api = test_api().await; - - let command_line = r#"chronicle test-activity-activity define testactivity --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; - let cmd = get_api_cmd(command_line); - - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let activity_id = ActivityId::from_external_id("testactivity"); - let entity_id = EntityId::from_external_id("testentity"); - let command_line = format!( - r#"chronicle test-activity-activity generate --namespace testns {entity_id} {activity_id} "# - ); - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:entity:testentity", - "@type": "prov:Entity", - "externalId": "testentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {}, - "wasGeneratedBy": [ - "chronicle:activity:testactivity" - ] - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } - - #[tokio::test] - async fn activity_use() { - let mut api = test_api().await; - - let command_line = r#"chronicle test-agent-agent define testagent --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; - let cmd = get_api_cmd(command_line); - - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let id = ChronicleIri::from(AgentId::from_external_id("testagent")); - let command_line = format!(r#"chronicle test-agent-agent use --namespace testns {id} "#); - let cmd = get_api_cmd(&command_line); - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let command_line = r#"chronicle test-activity-activity define testactivity --namespace testns --test-string-attr "test" --test-bool-attr true --test-int-attr 40 "#; - let cmd = get_api_cmd(command_line); - api.dispatch(cmd, AuthId::chronicle()).await.unwrap(); - - let activity_id = ActivityId::from_external_id("testactivity"); - let entity_id = EntityId::from_external_id("testentity"); - let command_line = format!( - r#"chronicle test-activity-activity use --namespace testns {entity_id} {activity_id} "# - ); - - let cmd = get_api_cmd(&command_line); - - insta::assert_snapshot!( - serde_json::to_string_pretty( - &api.dispatch(cmd, AuthId::chronicle()).await.unwrap().unwrap().0.to_json().compact_stable_order().await.unwrap() - ).unwrap() , @r###" - { - "@context": "https://btp.works/chr/1.0/c.jsonld", - "@graph": [ - { - "@id": "chronicle:activity:testactivity", - "@type": [ - "prov:Activity", - "chronicle:domaintype:testActivity" - ], - "externalId": "testactivity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "used": [ - "chronicle:entity:testentity" - ], - "value": { - "TestBool": true, - "TestInt": 40, - "TestString": "test" - } - }, - { - "@id": "chronicle:entity:testentity", - "@type": "prov:Entity", - "externalId": "testentity", - "namespace": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "value": {} - }, - { - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea", - "@type": "chronicle:Namespace", - "externalId": "testns" - } - ] - } - "###); - } -} diff --git a/crates/chronicle/src/bootstrap/opa.rs b/crates/chronicle/src/bootstrap/opa.rs index 0522e3d92..dc2884d6d 100644 --- a/crates/chronicle/src/bootstrap/opa.rs +++ b/crates/chronicle/src/bootstrap/opa.rs @@ -1,128 +1,17 @@ -use std::net::SocketAddr; - -use async_stl_client::zmq_client::{ - HighestBlockValidatorSelector, ZmqRequestResponseSawtoothChannel, -}; -use chronicle_protocol::{ - address::{FAMILY, VERSION}, - async_stl_client::ledger::SawtoothLedger, - settings::{read_opa_settings, OpaSettings, SettingsReader}, -}; use clap::ArgMatches; + use common::opa::{ - CliPolicyLoader, ExecutorContext, PolicyLoader, SawtoothPolicyLoader, UrlPolicyLoader, + std::{load_bytes_from_url, ExecutorContext, PolicyLoader, PolicyLoaderError}, + OpaSettings, }; -use tracing::{debug, instrument}; +use opa::bundle::Bundle; +use protocol_substrate::SubxtClientError; +use protocol_substrate_chronicle::{ChronicleSubstrateClient, SettingsLoader}; +use protocol_substrate_opa::{loader::SubstratePolicyLoader, policy_hash, OpaSubstrateClient}; +use tracing::{debug, error, info, instrument}; use super::CliError; -pub struct SawtoothPolicyLoader { - policy_id: String, - address: String, - policy: Option>, - entrypoint: String, - ledger: OpaLedger, -} - -impl SawtoothPolicyLoader { - pub fn new( - address: &SocketAddr, - policy_id: &str, - entrypoint: &str, - ) -> Result { - Ok(Self { - policy_id: policy_id.to_owned(), - address: String::default(), - policy: None, - entrypoint: entrypoint.to_owned(), - ledger: OpaLedger::new( - ZmqRequestResponseSawtoothChannel::new( - "sawtooth_policy", - &[address.to_owned()], - HighestBlockValidatorSelector, - )? - .retrying(), - FAMILY, - VERSION, - ), - }) - } - - fn sawtooth_address(&self, policy: impl AsRef) -> String { - policy_address(policy) - } - - #[instrument(level = "debug", skip(self))] - async fn load_bundle_from_chain(&mut self) -> Result, SawtoothCommunicationError> { - if let Some(policy) = self.policy.as_ref() { - return Ok(policy.clone()) - } - let load_policy_from = self.sawtooth_address(&self.policy_id); - debug!(load_policy_from=?load_policy_from); - - loop { - let res = self.ledger.get_state_entry(&load_policy_from).await; - - if let Err(res) = &res { - error!(error=?res, "Failed to load policy from chain"); - tokio::time::sleep(std::time::Duration::from_secs(2)).await; - continue - } - - return Ok(res.unwrap()) - } - } -} - -#[async_trait::async_trait] -impl PolicyLoader for SawtoothPolicyLoader { - fn set_address(&mut self, address: &str) { - self.address = address.to_owned() - } - - fn set_rule_name(&mut self, name: &str) { - self.policy_id = name.to_owned() - } - - fn set_entrypoint(&mut self, entrypoint: &str) { - self.entrypoint = entrypoint.to_owned() - } - - fn get_address(&self) -> &str { - &self.address - } - - fn get_rule_name(&self) -> &str { - &self.policy_id - } - - fn get_entrypoint(&self) -> &str { - &self.entrypoint - } - - fn get_policy(&self) -> &[u8] { - self.policy.as_ref().unwrap() - } - - async fn load_policy(&mut self) -> Result<(), PolicyLoaderError> { - let bundle = self.load_bundle_from_chain().await?; - info!(fetched_policy_bytes=?bundle.len(), "Fetched policy"); - if bundle.is_empty() { - error!("Policy not found: {}", self.get_rule_name()); - return Err(PolicyLoaderError::MissingPolicy(self.get_rule_name().to_string())) - } - self.load_policy_from_bundle(&Bundle::from_bytes(&*bundle)?) - } - - fn load_policy_from_bytes(&mut self, policy: &[u8]) { - self.policy = Some(policy.to_vec()) - } - - fn hash(&self) -> String { - hex::encode(Sha256::digest(self.policy.as_ref().unwrap())) - } -} - /// OPA policy loader for policies passed via CLI or embedded in Chronicle #[derive(Clone, Default)] pub struct CliPolicyLoader { @@ -148,7 +37,7 @@ impl CliPolicyLoader { /// Create a loaded [`CliPolicyLoader`] from name of an embedded dev policy and entrypoint pub fn from_embedded_policy(policy: &str, entrypoint: &str) -> Result { - if let Some(file) = EmbeddedOpaPolicies::get("bundle.tar.gz") { + if let Some(file) = common::opa::std::EmbeddedOpaPolicies::get("bundle.tar.gz") { let bytes = file.data.as_ref(); let bundle = Bundle::from_bytes(bytes)?; let mut loader = CliPolicyLoader::new(); @@ -216,7 +105,7 @@ impl PolicyLoader for CliPolicyLoader { } fn hash(&self) -> String { - hex::encode(Sha256::digest(&self.policy)) + hex::encode(policy_hash(&self.policy)) } } @@ -281,14 +170,14 @@ impl PolicyLoader for UrlPolicyLoader { if bundle.is_empty() { error!("Policy not found: {}", self.get_rule_name()); - return Err(PolicyLoaderError::MissingPolicy(self.get_rule_name().to_string())) + return Err(PolicyLoaderError::MissingPolicy(self.get_rule_name().to_string())); } self.load_policy_from_bundle(&Bundle::from_bytes(&*bundle)?) } fn hash(&self) -> String { - hex::encode(Sha256::digest(&self.policy)) + hex::encode(policy_hash(&self.policy)) } } @@ -331,29 +220,27 @@ pub async fn opa_executor_from_embedded_policy( Ok(ExecutorContext::from_loader(&loader)?) } -#[instrument()] -pub async fn opa_executor_from_sawtooth_settings( - validator_address: &Vec, -) -> Result<(ExecutorContext, OpaSettings), CliError> { - let settings = SettingsReader::new(SawtoothLedger::new( - ZmqRequestResponseSawtoothChannel::new( - "opa_executor", - validator_address, - HighestBlockValidatorSelector, - )? - .retrying(), - FAMILY, - VERSION, - )); - let opa_settings = read_opa_settings(&settings).await?; +pub async fn read_opa_settings( + client: &ChronicleSubstrateClient, +) -> Result, SubxtClientError> { + client.load_settings_from_storage().await +} + +#[instrument(skip(chronicle_client, opa_client))] +pub async fn opa_executor_from_substrate_state( + chronicle_client: &ChronicleSubstrateClient, + opa_client: &OpaSubstrateClient, +) -> Result<(ExecutorContext, Option), CliError> { + let opa_settings = read_opa_settings(chronicle_client).await?; debug!(on_chain_opa_policy = ?opa_settings); - let mut loader = SawtoothPolicyLoader::new( - validator_address.get(0).unwrap(), - &opa_settings.policy_name, - &opa_settings.entrypoint, - )?; - loader.load_policy().await?; - Ok((ExecutorContext::from_loader(&loader)?, opa_settings)) + if let Some(opa_settings) = opa_settings { + let mut loader = SubstratePolicyLoader::new(opa_settings.clone(), opa_client); + loader.load_policy().await?; + + Ok((ExecutorContext::from_loader(&loader)?, Some(opa_settings))) + } else { + Err(CliError::NoOnChainSettings) + } } #[instrument()] @@ -370,7 +257,11 @@ pub async fn opa_executor_from_url( #[cfg(test)] mod tests { use super::*; - use crate::identity::IdentityContext; + use common::{ + identity::{AuthId, IdentityContext, JwtClaims, OpaData}, + opa::std::{EmbeddedOpaPolicies, OpaExecutor, OpaExecutorError, WasmtimeOpaExecutor}, + }; + use mockito::mock; use serde_json::Value; use std::{collections::BTreeSet, io::Write}; @@ -405,7 +296,7 @@ mod tests { } fn jwt_user() -> AuthId { - let claims = crate::identity::JwtClaims( + let claims = JwtClaims( serde_json::json!({ "sub": "abcdef", }) @@ -472,19 +363,15 @@ mod tests { let embedded_bundle = embedded_policy_bundle().unwrap(); let (rule, entrypoint) = allow_all_users(); - // Create a temporary HTTP server that serves a policy bundle - let mut server = mockito::Server::new_async().await; - // Start the mock server and define the response - let _m = server - .mock("GET", "/bundle.tar.gz") - .with_body(&embedded_bundle) - .create_async() - .await; + let _m = mock("GET", "/bundle.tar.gz").with_body(&embedded_bundle).create(); // Create the URL policy loader - let mut loader = - UrlPolicyLoader::new(&format!("{}/bundle.tar.gz", server.url()), &rule, &entrypoint); + let mut loader = UrlPolicyLoader::new( + &format!("{}/bundle.tar.gz", mockito::server_url()), + &rule, + &entrypoint, + ); // Load the policy let result = loader.load_policy().await; diff --git a/crates/chronicle/src/codegen/mod.rs b/crates/chronicle/src/codegen/mod.rs index 9be8a630f..0aec5ff01 100644 --- a/crates/chronicle/src/codegen/mod.rs +++ b/crates/chronicle/src/codegen/mod.rs @@ -816,7 +816,7 @@ fn gen_attribute_definition(typ: impl TypeName, attributes: &[AttributeDef]) -> let serde_value = &rust::import("chronicle::serde_json", "Value"); if attributes.is_empty() { - return quote! {} + return quote! {}; } quote! { @@ -1612,6 +1612,8 @@ fn gen_graphql_type(domain: &ChronicleDomainDef) -> rust::Tokens { #[#tokio::main] pub async fn main() { + + let model = #chronicledomaindef::from_input_string(#_(#(&domain.to_json_string().unwrap()))).unwrap(); #bootstrap(model, #chronicle_graphql::new(Query, Mutation)).await diff --git a/crates/chronicle/src/codegen/model.rs b/crates/chronicle/src/codegen/model.rs index 7f57f6aac..426305ca9 100644 --- a/crates/chronicle/src/codegen/model.rs +++ b/crates/chronicle/src/codegen/model.rs @@ -70,6 +70,7 @@ impl AttributeDef { } /// A external_id formatted for CLI use - kebab-case, singular, lowercase + pub trait CliName { fn as_cli_name(&self) -> String; } @@ -364,7 +365,7 @@ impl<'a> From> for AgentDef { pub struct EntityBuilder<'a>(&'a ChronicleDomainDef, EntityDef); impl<'a> EntityBuilder<'a> { - pub(crate) fn new( + pub fn new( domain: &'a ChronicleDomainDef, external_id: impl AsRef, doc: Option, @@ -372,7 +373,7 @@ impl<'a> EntityBuilder<'a> { Self(domain, EntityDef::new(external_id, doc, vec![])) } - pub(crate) fn with_attribute(mut self, typ: impl AsRef) -> Result { + pub fn with_attribute(mut self, typ: impl AsRef) -> Result { let attr = self .0 .attribute(typ.as_ref()) @@ -391,7 +392,7 @@ impl<'a> From> for EntityDef { pub struct ActivityBuilder<'a>(&'a ChronicleDomainDef, ActivityDef); impl<'a> ActivityBuilder<'a> { - pub(crate) fn new( + pub fn new( domain: &'a ChronicleDomainDef, external_id: impl AsRef, doc: Option, @@ -399,7 +400,7 @@ impl<'a> ActivityBuilder<'a> { Self(domain, ActivityDef::new(external_id, doc, vec![])) } - pub(crate) fn with_attribute(mut self, typ: impl AsRef) -> Result { + pub fn with_attribute(mut self, typ: impl AsRef) -> Result { let attr = self .0 .attribute(typ.as_ref()) @@ -418,11 +419,11 @@ impl<'a> From> for ActivityDef { pub struct Builder(ChronicleDomainDef); impl Builder { - pub(crate) fn new(name: impl AsRef) -> Self { + pub fn new(name: impl AsRef) -> Self { Builder(ChronicleDomainDef { name: name.as_ref().to_string(), ..Default::default() }) } - pub(crate) fn with_attribute_type( + pub fn with_attribute_type( mut self, external_id: impl AsRef, doc: Option, @@ -437,7 +438,7 @@ impl Builder { Ok(self) } - pub(crate) fn with_agent( + pub fn with_agent( mut self, external_id: impl AsRef, doc: Option, @@ -449,7 +450,7 @@ impl Builder { Ok(self) } - pub(crate) fn with_entity( + pub fn with_entity( mut self, external_id: impl AsRef, doc: Option, @@ -461,7 +462,7 @@ impl Builder { Ok(self) } - pub(crate) fn with_activity( + pub fn with_activity( mut self, external_id: impl AsRef, doc: Option, @@ -474,7 +475,7 @@ impl Builder { Ok(self) } - pub(crate) fn with_role(mut self, external_id: impl AsRef) -> Result { + pub fn with_role(mut self, external_id: impl AsRef) -> Result { self.0.roles.push(RoleDef::new(external_id)); Ok(self) @@ -611,7 +612,7 @@ impl From<&ChronicleDomainDef> for DomainFileInput { } impl ChronicleDomainDef { - pub(crate) fn build(external_id: &str) -> Builder { + pub fn build(external_id: &str) -> Builder { Builder::new(external_id) } diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 897936e57..acdd358f4 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -7,45 +7,81 @@ version = "0.7.5" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = { version="1", default-features=false} -async-graphql = { version="5.0.9", features = [ +anyhow = { version = "1", default-features = false } +async-graphql = { version = "5.0.9", features = [ "opentelemetry", "chrono", "unblock", "default", - "uuid"], optional=true } -sp-std= {version="11.0.0", optional=true} + "uuid", +], optional = true } async-trait = { workspace = true } -chrono = { version="0.4", default-features=false,features=["serde","alloc"] } -diesel = { version="2.0.0-rc.0",features = [ +chrono = { version = "0.4", default-features = false, features = [ + "serde", + "alloc", +] } +diesel = { version = "2.0.0-rc.0", features = [ "postgres", "uuid", "chrono", "r2d2", -], optional=true} -iref= {version="2.2", optional = true} -futures = { version="0.3", default-features=false} -hex = { version="0.4", default-features=false, features=["alloc"]} -rdf-types={ version="0.14", optional=true} -json-ld = { version="0.14", optional=true} -hashbrown = {version="0.13", optional=true} -json-syntax = { version="0.9", features=["serde","serde_json"], optional = true } -k256 = { version="0.11.3",default-features=false,features=["ecdsa","pkcs8"] } -lazy_static = { version="1.4" } -locspan = { version="0.7", optional=true} -mime = { version="0.3", optional=true } -scale-info = {version="2.10.0", default-features=false, features=["derive"]} -parity-scale-codec = {version = "3.6.5", default-features=false,features=["derive","max-encoded-len"]} -newtype-derive-2018 = {workspace=true} -macro-attr-2018 = {workspace=true} -serde = { version="1.0", default-features=false } -serde_derive = { version="1.0",default-features=false } -serde_json = { version="1.0", default-features=false } -iri-string = {version="0.7",default-features=false, features=["alloc"]} +], optional = true } +futures = { version = "0.3", default-features = false } +hashbrown = { version = "0.13", optional = true } +hex = { version = "0.4", default-features = false, features = ["alloc"] } +iref = { version = "2.2", optional = true } +iri-string = { version = "0.7", default-features = false, features = ["alloc"] } +json-ld = { version = "0.14", optional = true } +json-syntax = { version = "0.9", features = [ + "serde", + "serde_json", +], optional = true } +k256 = { version = "0.11.3", default-features = false, features = [ + "ecdsa", + "pkcs8", +] } +lazy_static = { version = "1.4" } +locspan = { version = "0.7", optional = true } +macro-attr-2018 = { workspace = true } +mime = { version = "0.3", optional = true } +newtype-derive-2018 = { workspace = true } +opa = { git = "https://github.com/chronicleworks/opa-rs", rev = "9fa2fbce", optional = true } +parity-scale-codec = { version = "3.6.5", default-features = false, features = [ + "derive", + "max-encoded-len", +], optional = true } +rdf-types = { version = "0.14", optional = true } +reqwest = { version = "0.11", optional = true } +rust-embed = { version = "6", features = [ + "debug-embed", + "include-exclude", +], optional = true } +scale-decode = { version = "0.9", default-features = false, features = [ + "derive", +], optional = true } +scale-encode = { version = "0.5", default-features = false, features = [ + "derive", + "primitive-types", + "bits", +], optional = true } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +], optional = true } +serde = { version = "1.0", default-features = false, features = [ + "rc", + "derive", +] } +serde_derive = { version = "1.0", default-features = false } +serde_json = { version = "1.0", default-features = false } +sp-core = { version = "25.0.0", default-features = false } +sp-std = { version = "11.0.0", optional = true } thiserror = { workspace = true } -thiserror-no-std = {version="2.0.2" } -tracing = { version="0.1.40", default-features=false, features=["attributes"]} -uuid = {version="1.5.0", default-features=false, features=["serde"]} +thiserror-no-std = { version = "2.0.2" } +tracing = { version = "0.1", default-features = false, features = [ + "attributes", +] } +url = { version = "2", optional = true } +uuid = { version = "1.5.0", default-features = false, features = ["serde"] } [build-dependencies] glob = { workspace = true } @@ -53,20 +89,54 @@ lazy_static = { workspace = true } serde_json = { workspace = true } [dev-dependencies] -tokio={workspace=true} +criterion = { workspace = true } +insta = { workspace = true, features = ["json"] } +mockito = { workspace = true } +proptest = { workspace = true } +tempfile = { workspace = true } testcontainers = { workspace = true } -criterion = { workspace = true } -insta = { workspace = true, features = ["json"] } -mockito = { workspace = true } -proptest = { workspace = true } -tempfile = { workspace = true } +tokio = { workspace = true } [features] -std = ["k256/std","tracing/std","serde/std","serde_json/std","hex/std","futures/std","iri-string/std","chrono/std","anyhow/std"] -default = ["std","graphql-bindings","diesel-bindings","json-ld"] +default = [] +std = [ + "k256/std", + "sp-core/std", + "tracing/std", + "serde/std", + "serde_json/std", + "hex/std", + "scale-encode/std", + "futures/std", + "iri-string/std", + "chrono/std", + "anyhow/std", + "dep:opa", + "sp-core/full_crypto", + "uuid/getrandom", + "dep:url", + "dep:reqwest", + "dep:rust-embed", + "scale-encode/std", + "scale-decode/std", +] # Enable parity support, annoyingly lazy_static has a non standard way of enabling non_std -parity = ["lazy_static/spin_no_std"] +parity-encoding = [ + "lazy_static/spin_no_std", + "parity-scale-codec", + "scale-info", + "scale-encode", + "scale-decode", +] # At this point, LD should be a seperate crate -json-ld = ["dep:json-ld","dep:json-syntax","dep:rdf-types","dep:hashbrown","dep:mime","dep:locspan","dep:iref"] +diesel-bindings = ["diesel"] graphql-bindings = ["async-graphql"] -diesel-bindings = ["diesel"] +json-ld = [ + "dep:json-ld", + "dep:json-syntax", + "dep:rdf-types", + "dep:hashbrown", + "dep:mime", + "dep:locspan", + "dep:iref", +] diff --git a/crates/common/src/attributes.rs b/crates/common/src/attributes.rs index b7e67c892..72fef2c19 100644 --- a/crates/common/src/attributes.rs +++ b/crates/common/src/attributes.rs @@ -1,13 +1,14 @@ #[cfg(feature = "std")] use std::collections::BTreeMap; +#[cfg(feature = "parity-encoding")] +use parity_scale_codec::Encode; #[cfg(not(feature = "std"))] use parity_scale_codec::{alloc::collections::BTreeMap, alloc::string::String}; +use scale_encode::error::Kind; #[cfg(not(feature = "std"))] use scale_info::{prelude::borrow::ToOwned, prelude::string::ToString, prelude::*}; -use parity_scale_codec::{Decode, Encode}; -use scale_info::{build::Fields, Path, Type, TypeInfo}; use serde_json::Value; use crate::prov::DomaintypeId; @@ -27,27 +28,46 @@ impl core::fmt::Display for SerdeWrapper { } } -impl Encode for SerdeWrapper { - fn encode_to(&self, dest: &mut T) { - let json_string = - serde_json::to_string(&self.0).expect("Failed to serialize Value to JSON string"); - json_string.encode_to(dest); - } -} - impl From for SerdeWrapper { fn from(value: Value) -> Self { SerdeWrapper(value) } } -impl From for Value { - fn from(wrapper: SerdeWrapper) -> Self { - wrapper.0 +#[cfg(feature = "parity-encoding")] +impl scale_encode::EncodeAsType for SerdeWrapper { + fn encode_as_type_to( + &self, + type_id: u32, + _types: &scale_info::PortableRegistry, + out: &mut scale_encode::Vec, + ) -> Result<(), scale_encode::Error> { + let json_string = match serde_json::to_string(&self.0) { + Ok(json_string) => json_string, + Err(e) => { + tracing::error!("Failed to serialize Value to JSON string: {}", e); + return Err(scale_encode::Error::new(scale_encode::error::ErrorKind::WrongShape { + actual: Kind::Str, + expected: type_id, + })); + }, + }; + json_string.encode_to(out); + Ok(()) } } -impl Decode for SerdeWrapper { +#[cfg(feature = "parity-encoding")] +impl parity_scale_codec::Encode for SerdeWrapper { + fn encode_to(&self, dest: &mut T) { + let json_string = + serde_json::to_string(&self.0).expect("Failed to serialize Value to JSON string"); + json_string.encode_to(dest); + } +} + +#[cfg(feature = "parity-encoding")] +impl parity_scale_codec::Decode for SerdeWrapper { fn decode( input: &mut I, ) -> Result { @@ -59,16 +79,33 @@ impl Decode for SerdeWrapper { } } -impl TypeInfo for SerdeWrapper { +#[cfg(feature = "parity-encoding")] +impl scale_info::TypeInfo for SerdeWrapper { type Identity = Self; - fn type_info() -> Type { - Type::builder() - .path(Path::new("SerdeWrapper", module_path!())) - .composite(Fields::unnamed().field(|f| f.ty::().type_name("Json"))) + + fn type_info() -> scale_info::Type { + scale_info::Type::builder() + .path(scale_info::Path::new("SerdeWrapper", module_path!())) + .composite(scale_info::build::Fields::unnamed().field(|f| f.ty::())) + } +} + +impl From for Value { + fn from(wrapper: SerdeWrapper) -> Self { + wrapper.0 } } -#[derive(Debug, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, PartialEq, Eq)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Attribute { pub typ: String, pub value: SerdeWrapper, @@ -93,14 +130,22 @@ impl Attribute { pub fn get_value(&self) -> &Value { &self.value.0 } + pub fn new(typ: impl AsRef, value: Value) -> Self { Self { typ: typ.as_ref().to_owned(), value: value.into() } } } -#[derive( - Debug, Clone, Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Default, +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct Attributes { pub typ: Option, pub attributes: BTreeMap, diff --git a/crates/common/src/identity.rs b/crates/common/src/identity.rs index 9147603fd..0667a2bd9 100644 --- a/crates/common/src/identity.rs +++ b/crates/common/src/identity.rs @@ -1,19 +1,16 @@ use crate::prov::AgentId; -use k256::{ - ecdsa::VerifyingKey, - sha2::{Digest, Sha512}, -}; +use k256::sha2::{Digest, Sha512}; use serde_json::{Map, Value}; use tracing::warn; #[cfg(not(feature = "std"))] use parity_scale_codec::{ alloc::collections::BTreeMap, alloc::collections::BTreeSet, alloc::string::String, - alloc::vec::Vec, + alloc::vec::Vec, Decode, Encode, }; #[cfg(not(feature = "std"))] -use scale_info::{prelude::borrow::ToOwned, prelude::string::ToString, prelude::*}; +use scale_info::{prelude::borrow::ToOwned, prelude::string::ToString, prelude::*, TypeInfo}; #[cfg(feature = "std")] use std::collections::BTreeMap; @@ -31,16 +28,13 @@ pub enum IdentityError { JwtClaims, #[error("Signer : {0}")] - KeyStore(#[from] anyhow::Error), + Signing(#[from] anyhow::Error), #[error("Malformed JSON: {0}")] SerdeJson(#[from] serde_json::Error), #[error("Serialization error: {0}")] SerdeJsonSerialize(String), - - #[error("Signing error: {0}")] - Signing(#[from] k256::ecdsa::Error), } /// Contains the scalar ID and identity claims for a user established via JWT @@ -192,22 +186,26 @@ impl OpaData { )) } } - /// Signed user identity containing the serialized identity, signature, and /// verifying key. Implements `TryFrom` to deserialize to the user identity object +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] #[derive(Clone, Debug, Eq, PartialEq)] pub struct SignedIdentity { pub identity: String, pub signature: Option>, - pub verifying_key: Option, + pub verifying_key: Option>, } impl SignedIdentity { - fn new( - id: &AuthId, - signature: Vec, - verifying_key: VerifyingKey, - ) -> Result { + fn new(id: &AuthId, signature: Vec, verifying_key: Vec) -> Result { Ok(Self { identity: serde_json::to_string(&id)?, signature: Some(signature), diff --git a/crates/common/src/json_ld.rs b/crates/common/src/json_ld.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/crates/common/src/json_ld.rs @@ -0,0 +1 @@ + diff --git a/crates/common/src/ledger.rs b/crates/common/src/ledger.rs index f4edf1fb6..38e393fec 100644 --- a/crates/common/src/ledger.rs +++ b/crates/common/src/ledger.rs @@ -1,5 +1,5 @@ -use scale_info::TypeInfo; use tracing::instrument; +use uuid::Uuid; use crate::{ identity::SignedIdentity, @@ -19,7 +19,8 @@ use core::str::FromStr; #[cfg(not(feature = "std"))] use parity_scale_codec::{ alloc::boxed::Box, alloc::collections::btree_map::Entry, alloc::collections::BTreeMap, - alloc::collections::BTreeSet, alloc::string::String, alloc::sync::Arc, alloc::vec::Vec, + alloc::collections::BTreeSet, alloc::string::String, alloc::sync::Arc, alloc::vec::Vec, Decode, + Encode, }; #[cfg(not(feature = "std"))] use scale_info::prelude::*; @@ -36,6 +37,9 @@ pub enum SubmissionError { Contradiction { source: Contradiction, tx_id: ChronicleTransactionId }, } +#[cfg(feature = "std")] +impl std::error::Error for SubmissionError {} + impl SubmissionError { pub fn tx_id(&self) -> &ChronicleTransactionId { match self { @@ -46,15 +50,15 @@ impl SubmissionError { } pub fn processor(tx_id: &ChronicleTransactionId, source: ProcessorError) -> SubmissionError { - SubmissionError::Processor { source: Arc::new(source), tx_id: tx_id.clone() } + SubmissionError::Processor { source: Arc::new(source), tx_id: *tx_id } } pub fn contradiction(tx_id: &ChronicleTransactionId, source: Contradiction) -> SubmissionError { - SubmissionError::Contradiction { source, tx_id: tx_id.clone() } + SubmissionError::Contradiction { source, tx_id: *tx_id } } pub fn communication(tx_id: &ChronicleTransactionId, source: anyhow::Error) -> SubmissionError { - SubmissionError::Communication { source: Arc::new(source), tx_id: tx_id.clone() } + SubmissionError::Communication { source: Arc::new(source), tx_id: *tx_id } } } @@ -81,6 +85,36 @@ impl core::fmt::Display for SubmissionError { } } +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + scale_encode::EncodeAsType, + parity_scale_codec::Encode, + parity_scale_codec::Decode + ) +)] +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct OperationSubmission { + pub correlation_id: [u8; 16], + pub operations: Arc>, + pub identity: Arc, +} + +impl OperationSubmission { + pub fn new(uuid: Uuid, identity: SignedIdentity, operations: Vec) -> Self { + OperationSubmission { + correlation_id: uuid.into_bytes(), + identity: identity.into(), + operations: operations.into(), + } + } + + pub fn new_anonymous(uuid: Uuid, operations: Vec) -> Self { + Self::new(uuid, SignedIdentity::new_no_identity(), operations) + } +} + pub type SubmitResult = Result; #[derive(Debug, Clone)] @@ -111,7 +145,7 @@ impl SubmissionStage { } pub fn submitted(r: &ChronicleTransactionId) -> Self { - SubmissionStage::Submitted(Ok(r.clone())) + SubmissionStage::Submitted(Ok(*r)) } pub fn committed(commit: Commit, identity: SignedIdentity) -> Self { @@ -138,30 +172,25 @@ impl SubmissionStage { } } -#[derive( - parity_scale_codec::Encode, - parity_scale_codec::Decode, - TypeInfo, - PartialEq, - Eq, - PartialOrd, - Ord, - Debug, - Clone, +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] -pub struct LedgerAddress { +pub struct ChronicleAddress { // Namespaces do not have a namespace namespace: Option, resource: ChronicleIri, } -impl parity_scale_codec::MaxEncodedLen for LedgerAddress { +#[cfg(feature = "parity-encoding")] +impl parity_scale_codec::MaxEncodedLen for ChronicleAddress { fn max_encoded_len() -> usize { 2048usize } } -impl core::fmt::Display for LedgerAddress { +impl core::fmt::Display for ChronicleAddress { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if let Some(namespace) = &self.namespace { write!(f, "{}:{}", namespace, self.resource) @@ -175,7 +204,7 @@ pub trait NameSpacePart { fn namespace_part(&self) -> Option; } -impl NameSpacePart for LedgerAddress { +impl NameSpacePart for ChronicleAddress { fn namespace_part(&self) -> Option { self.namespace.clone() } @@ -185,24 +214,13 @@ pub trait ResourcePart { fn resource_part(&self) -> ChronicleIri; } -impl ResourcePart for LedgerAddress { +impl ResourcePart for ChronicleAddress { fn resource_part(&self) -> ChronicleIri { self.resource.clone() } } -impl LedgerAddress { - fn from_ld(ns: Option<&str>, resource: &str) -> Result { - Ok(Self { - namespace: if let Some(ns) = ns { - Some(ChronicleIri::from_str(ns)?.namespace()?) - } else { - None - }, - resource: ChronicleIri::from_str(resource)?, - }) - } - +impl ChronicleAddress { fn namespace(ns: &NamespaceId) -> Self { Self { namespace: None, resource: ns.clone().into() } } @@ -344,16 +362,16 @@ impl StateInput { #[derive(Debug)] pub struct StateOutput { - pub address: LedgerAddress, + pub address: ChronicleAddress, pub data: ProvModel, } impl StateOutput { - pub fn new(address: LedgerAddress, data: ProvModel) -> Self { + pub fn new(address: ChronicleAddress, data: ProvModel) -> Self { Self { address, data } } - pub fn address(&self) -> &LedgerAddress { + pub fn address(&self) -> &ChronicleAddress { &self.address } @@ -379,7 +397,7 @@ impl Version { /// Hold a cache of `LedgerWriter::submit` input and output address data pub struct OperationState { - state: BTreeMap, + state: BTreeMap, } impl Default for OperationState { @@ -396,10 +414,11 @@ impl OperationState { pub fn update_state_from_output(&mut self, output: impl Iterator) { self.update_state(output.map(|output| (output.address, Some(output.data)))) } + /// Load input values into `OperationState` pub fn update_state( &mut self, - input: impl Iterator)>, + input: impl Iterator)>, ) { input.for_each(|(address, value)| { let entry = self.state.entry(address); @@ -438,7 +457,7 @@ impl OperationState { } /// Return the input data held in `OperationState` for `addresses` as a vector of `StateInput`s - pub fn opa_context(&self, addresses: BTreeSet) -> Vec { + pub fn opa_context(&self, addresses: BTreeSet) -> Vec { self.state .iter() .filter(|(addr, _data)| addresses.iter().any(|a| &a == addr)) @@ -451,23 +470,26 @@ impl OperationState { impl ChronicleOperation { /// Compute dependencies for a chronicle operation, input and output addresses are always /// symmetric - pub fn dependencies(&self) -> Vec { + pub fn dependencies(&self) -> Vec { match self { ChronicleOperation::CreateNamespace(CreateNamespace { id, .. }) => { - vec![LedgerAddress::namespace(id)] + vec![ChronicleAddress::namespace(id)] }, ChronicleOperation::AgentExists(AgentExists { namespace, external_id, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, AgentId::from_external_id(external_id)), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace( + namespace, + AgentId::from_external_id(external_id), + ), ] }, ChronicleOperation::ActivityExists(ActivityExists { namespace, external_id, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace( + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace( namespace, ActivityId::from_external_id(external_id), ), @@ -475,8 +497,8 @@ impl ChronicleOperation { }, ChronicleOperation::StartActivity(StartActivity { namespace, id, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), ] }, ChronicleOperation::WasAssociatedWith(WasAssociatedWith { @@ -486,10 +508,10 @@ impl ChronicleOperation { agent_id, .. }) => vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), - LedgerAddress::in_namespace(namespace, activity_id.clone()), - LedgerAddress::in_namespace(namespace, agent_id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::in_namespace(namespace, activity_id.clone()), + ChronicleAddress::in_namespace(namespace, agent_id.clone()), ], ChronicleOperation::WasAttributedTo(WasAttributedTo { id, @@ -498,34 +520,37 @@ impl ChronicleOperation { agent_id, .. }) => vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), - LedgerAddress::in_namespace(namespace, entity_id.clone()), - LedgerAddress::in_namespace(namespace, agent_id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::in_namespace(namespace, entity_id.clone()), + ChronicleAddress::in_namespace(namespace, agent_id.clone()), ], ChronicleOperation::EndActivity(EndActivity { namespace, id, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), ] }, ChronicleOperation::ActivityUses(ActivityUses { namespace, id, activity }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, activity.clone()), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, activity.clone()), + ChronicleAddress::in_namespace(namespace, id.clone()), ] }, ChronicleOperation::EntityExists(EntityExists { namespace, external_id }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, EntityId::from_external_id(external_id)), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace( + namespace, + EntityId::from_external_id(external_id), + ), ] }, ChronicleOperation::WasGeneratedBy(WasGeneratedBy { namespace, id, activity }) => vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, activity.clone()), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, activity.clone()), + ChronicleAddress::in_namespace(namespace, id.clone()), ], ChronicleOperation::WasInformedBy(WasInformedBy { namespace, @@ -533,9 +558,9 @@ impl ChronicleOperation { informing_activity, }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, activity.clone()), - LedgerAddress::in_namespace(namespace, informing_activity.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, activity.clone()), + ChronicleAddress::in_namespace(namespace, informing_activity.clone()), ] }, ChronicleOperation::AgentActsOnBehalfOf(ActsOnBehalfOf { @@ -546,13 +571,13 @@ impl ChronicleOperation { responsible_id, .. }) => vec![ - Some(LedgerAddress::namespace(namespace)), - activity_id - .as_ref() - .map(|activity_id| LedgerAddress::in_namespace(namespace, activity_id.clone())), - Some(LedgerAddress::in_namespace(namespace, delegate_id.clone())), - Some(LedgerAddress::in_namespace(namespace, responsible_id.clone())), - Some(LedgerAddress::in_namespace(namespace, id.clone())), + Some(ChronicleAddress::namespace(namespace)), + activity_id.as_ref().map(|activity_id| { + ChronicleAddress::in_namespace(namespace, activity_id.clone()) + }), + Some(ChronicleAddress::in_namespace(namespace, delegate_id.clone())), + Some(ChronicleAddress::in_namespace(namespace, responsible_id.clone())), + Some(ChronicleAddress::in_namespace(namespace, id.clone())), ] .into_iter() .flatten() @@ -564,34 +589,34 @@ impl ChronicleOperation { activity_id, .. }) => vec![ - Some(LedgerAddress::namespace(namespace)), - activity_id - .as_ref() - .map(|activity_id| LedgerAddress::in_namespace(namespace, activity_id.clone())), - Some(LedgerAddress::in_namespace(namespace, used_id.clone())), - Some(LedgerAddress::in_namespace(namespace, id.clone())), + Some(ChronicleAddress::namespace(namespace)), + activity_id.as_ref().map(|activity_id| { + ChronicleAddress::in_namespace(namespace, activity_id.clone()) + }), + Some(ChronicleAddress::in_namespace(namespace, used_id.clone())), + Some(ChronicleAddress::in_namespace(namespace, id.clone())), ] .into_iter() .flatten() .collect(), ChronicleOperation::SetAttributes(SetAttributes::Agent { id, namespace, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), ] }, ChronicleOperation::SetAttributes(SetAttributes::Entity { id, namespace, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), ] }, ChronicleOperation::SetAttributes(SetAttributes::Activity { id, namespace, .. }) => { vec![ - LedgerAddress::namespace(namespace), - LedgerAddress::in_namespace(namespace, id.clone()), + ChronicleAddress::namespace(namespace), + ChronicleAddress::in_namespace(namespace, id.clone()), ] }, } @@ -615,7 +640,7 @@ impl ChronicleOperation { .to_snapshot() .into_iter() .map(|((namespace, resource), prov)| { - StateOutput::new(LedgerAddress { namespace, resource }, prov) + StateOutput::new(ChronicleAddress { namespace, resource }, prov) }) .collect::>(), model, diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 1065a21fe..8651e2898 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -7,6 +7,7 @@ pub mod attributes; pub mod context; pub mod identity; pub mod ledger; +pub mod opa; pub mod prov; pub use k256; diff --git a/crates/common/src/opa/core.rs b/crates/common/src/opa/core.rs new file mode 100644 index 000000000..d5fa29915 --- /dev/null +++ b/crates/common/src/opa/core.rs @@ -0,0 +1,666 @@ +use core::fmt; +#[cfg(not(feature = "std"))] +use parity_scale_codec::alloc::string::String; + +#[cfg(not(feature = "std"))] +use scale_info::{prelude::vec, prelude::vec::Vec}; + +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + scale_decode::DecodeAsType, + parity_scale_codec::MaxEncodedLen + ) +)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)] +pub struct H128([u8; 16]); + +impl H128 { + pub fn new(value: [u8; 16]) -> Self { + H128(value) + } + + pub fn into(self) -> [u8; 16] { + self.0 + } +} + +#[cfg(not(feature = "std"))] +use scale_info::prelude::format; +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + scale_decode::DecodeAsType, + parity_scale_codec::MaxEncodedLen + ) +)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)] +pub struct PolicyAddress(H128); + +impl fmt::Display for PolicyAddress { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "PolicyAddress({})", hex::encode(self.0.into())) + } +} + +impl From<[u8; 16]> for PolicyAddress { + fn from(value: [u8; 16]) -> Self { + tracing::debug!("Converting [u8; 16] to PolicyAddress"); + PolicyAddress(H128::new(value)) + } +} + +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + parity_scale_codec::MaxEncodedLen + ) +)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct PolicyMetaAddress(H128); + +impl PolicyMetaAddress { + pub fn new(value: H128) -> Self { + PolicyMetaAddress(value) + } + + pub fn into(self) -> H128 { + self.0 + } +} + +impl From<[u8; 16]> for H128 { + fn from(value: [u8; 16]) -> Self { + H128(value) + } +} + +impl From<[u8; 16]> for PolicyMetaAddress { + fn from(value: [u8; 16]) -> Self { + PolicyMetaAddress(H128::new(value)) + } +} + +impl From<[u8; 16]> for KeyAddress { + fn from(value: [u8; 16]) -> Self { + KeyAddress(H128::new(value)) + } +} + +impl From for PolicyMetaAddress { + fn from(value: H128) -> Self { + PolicyMetaAddress(value) + } +} + +impl From for PolicyAddress { + fn from(value: H128) -> Self { + PolicyAddress(value) + } +} + +impl From for KeyAddress { + fn from(value: H128) -> Self { + KeyAddress(value) + } +} + +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + parity_scale_codec::MaxEncodedLen + ) +)] +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct KeyAddress(H128); + +#[derive(Debug, Clone, Eq, PartialEq)] +// This message is used to bootstrap the root key for a newly created authz tp, +// it can only be executed once +pub struct BootstrapRoot { + pub public_key: PemEncoded, +} +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + ) +)] +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct PemEncoded(String); + +impl PemEncoded { + pub fn as_str(&self) -> &str { + &self.0 + } + + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } +} + +impl PemEncoded { + pub fn new(encoded: String) -> Self { + PemEncoded(encoded) + } +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct RegisterKey { + pub public_key: PemEncoded, + pub id: String, + pub overwrite_existing: bool, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct NewPublicKey { + pub public_key: PemEncoded, + pub id: String, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +// Rotate the key with name to the new public key, the SignedOperation for this +// message must be signed by the old key. The signature must be valid for +// the new one, to demonstrate ownership of both keys +pub struct RotateKey { + pub payload: NewPublicKey, + pub previous_signing_key: PemEncoded, + pub previous_signature: Vec, + pub new_signing_key: PemEncoded, + pub new_signature: Vec, +} +#[derive(Debug, Clone, Eq, PartialEq)] +// Set the policy with name to the new policy, the SignedOperation for this must +// be signed by the root key +pub struct SetPolicy { + pub id: String, + pub policy: Policy, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct SignedOperationPayload { + pub operation: Operation, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +// An OPA TP operation and its signature +pub struct SignedOperation { + pub payload: SignedOperationPayload, + pub verifying_key: PemEncoded, + pub signature: Vec, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum Operation { + RegisterKey(RegisterKey), + RotateKey(RotateKey), + SetPolicy(SetPolicy), +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct OpaSubmission { + pub version: String, + pub correlation_id: [u8; 16], + pub span_id: u64, + pub payload: Payload, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum Payload { + BootstrapRoot(BootstrapRoot), + SignedOperation(SignedOperation), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct KeyRegistration { + pub key: PemEncoded, + pub version: u64, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Keys { + pub id: String, + pub current: KeyRegistration, + pub expired: Option, +} + +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + ) +)] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Policy(Vec); + +impl Policy { + pub fn new(data: Vec) -> Self { + Policy(data) + } + + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PolicyMeta { + pub id: String, + pub hash: H128, + pub policy_address: PolicyAddress, +} + +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType, + scale_decode::DecodeAsType + ) +)] +#[derive(Debug, Clone)] +pub struct OpaSettings { + pub policy_address: PolicyAddress, + pub policy_name: String, + pub entrypoint: String, +} + +#[cfg(feature = "parity-encoding")] +use parity_scale_codec::MaxEncodedLen; + +#[cfg(feature = "parity-encoding")] +impl MaxEncodedLen for OpaSettings { + fn max_encoded_len() -> usize { + PolicyAddress::max_encoded_len() + 1024 + } +} + +#[cfg(feature = "parity-encoding")] +pub mod codec { + use super::*; + use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; + + use scale_encode::EncodeAsType; + #[cfg(not(feature = "std"))] + use scale_info::prelude::vec::Vec; + + use scale_info::TypeInfo; + + #[derive(Encode, EncodeAsType, Decode, Debug, Eq, PartialEq, TypeInfo, Clone)] + pub struct KeysV1 { + pub id: String, + pub current: KeyRegistrationV1, + pub expired: Option, + } + + impl MaxEncodedLen for KeysV1 { + fn max_encoded_len() -> usize { + 1024 + KeyRegistrationV1::max_encoded_len() + + Option::::max_encoded_len() + } + } + + #[derive(Encode, EncodeAsType, Decode, Debug, Eq, PartialEq, TypeInfo, Clone)] + pub struct KeyRegistrationV1 { + // Der encoded public key + pub key: PemEncoded, + pub version: u64, + } + + impl MaxEncodedLen for KeyRegistrationV1 { + fn max_encoded_len() -> usize { + 1024 + u64::max_encoded_len() + } + } + + impl From for KeysV1 { + fn from(keys: super::Keys) -> Self { + Self { + id: keys.id, + current: KeyRegistrationV1 { key: keys.current.key, version: keys.current.version }, + expired: keys.expired.map(|expired_key| KeyRegistrationV1 { + key: expired_key.key, + version: expired_key.version, + }), + } + } + } + + impl core::convert::TryFrom for super::Keys { + type Error = core::convert::Infallible; + + fn try_from(keys_v1: KeysV1) -> Result { + Ok(Self { + id: keys_v1.id, + current: super::KeyRegistration { + key: keys_v1.current.key, + version: keys_v1.current.version, + }, + expired: keys_v1.expired.map(|expired_key_v1| super::KeyRegistration { + key: expired_key_v1.key, + version: expired_key_v1.version, + }), + }) + } + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct BootstrapRootV1 { + pub public_key: PemEncoded, + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct RegisterKeyV1 { + pub public_key: PemEncoded, + pub id: String, + pub overwrite_existing: bool, + } + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct NewPublicKeyV1 { + pub public_key: PemEncoded, + pub id: String, + } + + impl From for NewPublicKeyV1 { + fn from(new_public_key: super::NewPublicKey) -> Self { + Self { public_key: new_public_key.public_key, id: new_public_key.id } + } + } + + impl core::convert::TryFrom for super::NewPublicKey { + type Error = core::convert::Infallible; + + fn try_from(new_public_key_v1: NewPublicKeyV1) -> Result { + Ok(Self { public_key: new_public_key_v1.public_key, id: new_public_key_v1.id }) + } + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct RotateKeyV1 { + pub payload: NewPublicKeyV1, + pub previous_signing_key: PemEncoded, + pub previous_signature: Vec, + pub new_signing_key: PemEncoded, + pub new_signature: Vec, + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct SetPolicyV1 { + pub id: String, + pub policy: Policy, + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct SignedOperationPayloadV1 { + pub operation: OperationV1, + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct SignedOperationV1 { + pub payload: SignedOperationPayloadV1, + pub verifying_key: PemEncoded, + pub signature: Vec, + } + + impl From for SignedOperationV1 { + fn from(signed_operation: super::SignedOperation) -> Self { + Self { + payload: SignedOperationPayloadV1 { + operation: signed_operation.payload.operation.into(), + }, + verifying_key: signed_operation.verifying_key, + signature: signed_operation.signature, + } + } + } + + impl From for OperationV1 { + fn from(operation: super::Operation) -> Self { + match operation { + super::Operation::RegisterKey(register_key) => + OperationV1::RegisterKey(register_key.into()), + super::Operation::RotateKey(rotate_key) => + OperationV1::RotateKey(rotate_key.into()), + super::Operation::SetPolicy(set_policy) => + OperationV1::SetPolicy(set_policy.into()), + } + } + } + + impl From for RegisterKeyV1 { + fn from(register_key: super::RegisterKey) -> Self { + Self { + public_key: register_key.public_key, + id: register_key.id, + overwrite_existing: register_key.overwrite_existing, + } + } + } + + impl From for RotateKeyV1 { + fn from(rotate_key: super::RotateKey) -> Self { + Self { + payload: rotate_key.payload.into(), + previous_signing_key: rotate_key.previous_signing_key, + previous_signature: rotate_key.previous_signature, + new_signing_key: rotate_key.new_signing_key, + new_signature: rotate_key.new_signature, + } + } + } + + impl From for SetPolicyV1 { + fn from(set_policy: super::SetPolicy) -> Self { + Self { id: set_policy.id, policy: set_policy.policy } + } + } + + #[derive(Encode, EncodeAsType, Decode, Debug, Clone, TypeInfo, PartialEq, Eq)] + pub enum OperationV1 { + RegisterKey(RegisterKeyV1), + RotateKey(RotateKeyV1), + SetPolicy(SetPolicyV1), + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub struct OpaSubmissionV1 { + pub version: String, + pub correlation_id: [u8; 16], + pub span_id: u64, + pub payload: PayloadV1, + } + + #[derive(Encode, EncodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)] + pub enum PayloadV1 { + BootstrapRoot(BootstrapRootV1), + SignedOperation(SignedOperationV1), + } + + #[derive( + Encode, EncodeAsType, scale_decode::DecodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, + )] + pub struct PolicyV1(Vec); + + impl PolicyV1 { + pub fn into_vec(self) -> Vec { + self.0 + } + } + + impl MaxEncodedLen for PolicyV1 { + fn max_encoded_len() -> usize { + 1024 * 1024 * 10 + } + } + + impl From for codec::PolicyV1 { + fn from(item: Policy) -> Self { + Self(item.0) + } + } + + impl core::convert::TryFrom for Policy { + type Error = core::convert::Infallible; + + fn try_from(value: codec::PolicyV1) -> Result { + Ok(Self(value.0)) + } + } + + #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)] + pub struct PolicyMetaV1 { + pub id: String, + pub hash: H128, + pub policy_address: PolicyAddress, + } + + impl MaxEncodedLen for PolicyMetaV1 { + fn max_encoded_len() -> usize { + 1024 + H128::max_encoded_len() + PolicyAddress::max_encoded_len() + } + } + + impl From for codec::PolicyMetaV1 { + fn from(item: super::PolicyMeta) -> Self { + Self { id: item.id, hash: item.hash, policy_address: item.policy_address } + } + } + + impl core::convert::TryFrom for super::PolicyMeta { + type Error = core::convert::Infallible; + + fn try_from(value: codec::PolicyMetaV1) -> Result { + Ok(Self { id: value.id, hash: value.hash, policy_address: value.policy_address }) + } + } + + impl From for BootstrapRoot { + fn from(item: codec::BootstrapRootV1) -> Self { + Self { public_key: item.public_key } + } + } + + impl From for codec::BootstrapRootV1 { + fn from(item: BootstrapRoot) -> Self { + tracing::debug!(target: "codec_conversion", "Converting BootstrapRoot to BootstrapRootV1"); + Self { public_key: item.public_key } + } + } + + impl From for Payload { + fn from(item: codec::PayloadV1) -> Self { + match item { + codec::PayloadV1::BootstrapRoot(v) => Self::BootstrapRoot(v.into()), + codec::PayloadV1::SignedOperation(v) => Self::SignedOperation(v.into()), + } + } + } + + impl From for OpaSubmission { + fn from(item: codec::OpaSubmissionV1) -> Self { + Self { + correlation_id: item.correlation_id, + version: item.version, + span_id: item.span_id, + payload: item.payload.into(), + } + } + } + + impl From for codec::OpaSubmissionV1 { + fn from(item: OpaSubmission) -> Self { + tracing::debug!(target: "codec_conversion", "Converting OpaSubmission to OpaSubmissionV1"); + Self { + version: item.version, + correlation_id: item.correlation_id, + span_id: item.span_id, + payload: match item.payload { + Payload::BootstrapRoot(v) => { + tracing::trace!(target: "codec_conversion", "Payload is BootstrapRoot"); + codec::PayloadV1::BootstrapRoot(v.into()) + }, + Payload::SignedOperation(v) => { + tracing::trace!(target: "codec_conversion", "Payload is SignedOperation"); + codec::PayloadV1::SignedOperation(v.into()) + }, + }, + } + } + } + + impl From for Operation { + fn from(item: codec::OperationV1) -> Self { + match item { + codec::OperationV1::RegisterKey(v) => Self::RegisterKey(v.into()), + codec::OperationV1::RotateKey(v) => Self::RotateKey(v.into()), + codec::OperationV1::SetPolicy(v) => Self::SetPolicy(v.into()), + } + } + } + + impl From for SignedOperation { + fn from(item: codec::SignedOperationV1) -> Self { + Self { + payload: SignedOperationPayload { operation: item.payload.operation.into() }, + verifying_key: item.verifying_key, + signature: item.signature, + } + } + } + + impl From for RotateKey { + fn from(item: codec::RotateKeyV1) -> Self { + Self { + payload: NewPublicKey { public_key: item.payload.public_key, id: item.payload.id }, + previous_signing_key: item.previous_signing_key, + previous_signature: item.previous_signature, + new_signing_key: item.new_signing_key, + new_signature: item.new_signature, + } + } + } + + impl From for RegisterKey { + fn from(item: codec::RegisterKeyV1) -> Self { + Self { + public_key: item.public_key, + id: item.id, + overwrite_existing: item.overwrite_existing, + } + } + } + + impl From for SetPolicy { + fn from(item: codec::SetPolicyV1) -> Self { + Self { id: item.id, policy: item.policy } + } + } +} diff --git a/crates/common/src/opa/mod.rs b/crates/common/src/opa/mod.rs new file mode 100644 index 000000000..78afeb577 --- /dev/null +++ b/crates/common/src/opa/mod.rs @@ -0,0 +1,6 @@ +mod core; + +pub use core::*; + +#[cfg(feature = "std")] +pub mod std; diff --git a/crates/common/src/opa/std.rs b/crates/common/src/opa/std.rs new file mode 100644 index 000000000..baeb4d493 --- /dev/null +++ b/crates/common/src/opa/std.rs @@ -0,0 +1,221 @@ +use futures::lock::Mutex; +use opa::{bundle::Bundle, wasm::Opa}; +use rust_embed::RustEmbed; +use url::Url; + +use std::{fs::File, io::Read, path::PathBuf, sync::Arc}; + +use thiserror::Error; +use tracing::{error, instrument}; + +use crate::identity::{AuthId, IdentityError, OpaData}; + +use super::{KeyAddress, PolicyAddress, PolicyMetaAddress}; + +#[derive(RustEmbed)] +#[folder = "../../policies"] +#[include = "bundle.tar.gz"] +pub struct EmbeddedOpaPolicies; + +// Prefer these functions over the core ones in std, as they are more efficient +pub fn policy_address(id: impl AsRef) -> PolicyAddress { + sp_core::blake2_128(format!("opa:policy:binary:{}", id.as_ref()).as_bytes()).into() +} + +// Prefer these functions over the core ones in std, as they are more efficient +pub fn policy_meta_address(id: impl AsRef) -> PolicyMetaAddress { + sp_core::blake2_128(format!("opa:policy:meta:{}", id.as_ref()).as_bytes()).into() +} + +// Prefer these functions over the core ones in std, as they are more efficient +pub fn key_address(id: impl AsRef) -> KeyAddress { + sp_core::blake2_128(format!("opa:keys:{}", id.as_ref()).as_bytes()).into() +} + +#[derive(Error, Debug)] +pub enum FromUrlError { + #[error("HTTP error while attempting to read from URL: {0}")] + HTTP(#[from] reqwest::Error), + + #[error("Invalid URL scheme: {0}")] + InvalidUrlScheme(String), + + #[error("IO error while attempting to read from URL: {0}")] + IO(#[from] std::io::Error), +} + +pub enum PathOrUrl { + File(PathBuf), + Url(Url), +} + +pub async fn load_bytes_from_url(url: &str) -> Result, FromUrlError> { + let path_or_url = match url.parse::() { + Ok(url) => PathOrUrl::Url(url), + Err(_) => PathOrUrl::File(PathBuf::from(url)), + }; + + let content = match path_or_url { + PathOrUrl::File(path) => { + let mut file = File::open(path)?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + Ok(buf) + }, + PathOrUrl::Url(url) => match url.scheme() { + "file" => { + let mut file = File::open(url.path())?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + Ok(buf) + }, + "http" | "https" => Ok(reqwest::get(url).await?.bytes().await?.into()), + _ => Err(FromUrlError::InvalidUrlScheme(url.scheme().to_owned())), + }, + }?; + + Ok(content) +} + +pub fn load_bytes_from_stdin() -> Result, std::io::Error> { + let mut buffer = Vec::new(); + let mut stdin = std::io::stdin(); + let _ = stdin.read_to_end(&mut buffer)?; + Ok(buffer) +} +#[derive(Debug, Error)] +pub enum OpaExecutorError { + #[error("Access denied")] + AccessDenied, + + #[error("Identity error: {0}")] + IdentityError(#[from] IdentityError), + + #[error("Error loading OPA policy: {0}")] + PolicyLoaderError(#[from] PolicyLoaderError), + + #[error("Error evaluating OPA policy: {0}")] + OpaEvaluationError(#[from] anyhow::Error), +} + +#[async_trait::async_trait] +pub trait OpaExecutor { + /// Evaluate the loaded OPA instance against the provided identity and context + async fn evaluate(&mut self, id: &AuthId, context: &OpaData) -> Result<(), OpaExecutorError>; +} + +#[derive(Clone, Debug)] +pub struct ExecutorContext { + executor: Arc>, + hash: String, +} + +impl ExecutorContext { + #[instrument(skip(self), level = "trace", ret(Debug))] + pub async fn evaluate(&self, id: &AuthId, context: &OpaData) -> Result<(), OpaExecutorError> { + self.executor.lock().await.evaluate(id, context).await + } + + pub fn from_loader(loader: &L) -> Result { + Ok(Self { + executor: Arc::new(Mutex::new(WasmtimeOpaExecutor::from_loader(loader)?)), + hash: loader.hash(), + }) + } + + pub fn hash(&self) -> &str { + &self.hash + } +} + +#[derive(Debug)] +pub struct WasmtimeOpaExecutor { + opa: Opa, + entrypoint: String, +} + +impl WasmtimeOpaExecutor { + /// Build a `WasmtimeOpaExecutor` from the `PolicyLoader` provided + pub fn from_loader(loader: &L) -> Result { + Ok(Self { opa: loader.build_opa()?, entrypoint: loader.get_entrypoint().to_owned() }) + } +} + +#[async_trait::async_trait] +impl OpaExecutor for WasmtimeOpaExecutor { + #[instrument(level = "trace", skip(self))] + async fn evaluate(&mut self, id: &AuthId, context: &OpaData) -> Result<(), OpaExecutorError> { + self.opa.set_data(context)?; + let input = id.identity()?; + match self.opa.eval(&self.entrypoint, &input)? { + true => Ok(()), + false => Err(OpaExecutorError::AccessDenied), + } + } +} + +#[derive(Debug, Error)] +pub enum PolicyLoaderError { + #[error("Failed to read embedded OPA policies")] + EmbeddedOpaPolicies, + + #[error("Policy not found: {0}")] + MissingPolicy(String), + + #[error("OPA bundle I/O error: {0}")] + OpaBundleError(#[from] opa::bundle::Error), + + #[error("Error loading OPA policy: {0}")] + Substrate(#[from] anyhow::Error), + + #[error("Error loading from URL: {0}")] + FromUrl(#[from] FromUrlError), +} + +#[async_trait::async_trait] +pub trait PolicyLoader { + /// Set address of OPA policy + fn set_address(&mut self, address: &str); + + /// Set OPA policy + fn set_rule_name(&mut self, policy: &str); + + /// Set entrypoint for OPA policy + fn set_entrypoint(&mut self, entrypoint: &str); + + fn get_address(&self) -> &str; + + fn get_rule_name(&self) -> &str; + + fn get_entrypoint(&self) -> &str; + + fn get_policy(&self) -> &[u8]; + + /// Load OPA policy from address set in `PolicyLoader` + async fn load_policy(&mut self) -> Result<(), PolicyLoaderError>; + + /// Load OPA policy from provided bytes + fn load_policy_from_bytes(&mut self, policy: &[u8]); + + /// Return a built OPA instance from the cached policy + #[instrument(level = "trace", skip(self), ret)] + fn build_opa(&self) -> Result { + Ok(Opa::new().build(self.get_policy())?) + } + + /// Load OPA policy from provided policy bundle + fn load_policy_from_bundle(&mut self, bundle: &Bundle) -> Result<(), PolicyLoaderError> { + let rule = self.get_rule_name(); + self.load_policy_from_bytes( + bundle + .wasm_policies + .iter() + .find(|p| p.entrypoint == rule) + .map(|p| p.bytes.as_ref()) + .ok_or(PolicyLoaderError::MissingPolicy(rule.to_string()))?, + ); + Ok(()) + } + + fn hash(&self) -> String; +} diff --git a/crates/common/src/prov/id/graphlql_scalars.rs b/crates/common/src/prov/id/graphlql_scalars.rs index 47a78a6d9..d6d9b1706 100644 --- a/crates/common/src/prov/id/graphlql_scalars.rs +++ b/crates/common/src/prov/id/graphlql_scalars.rs @@ -1,5 +1,4 @@ use async_graphql::{InputValueError, InputValueResult, Scalar, ScalarType, Value}; -use iref::Iri; use super::{ActivityId, AgentId, ChronicleJSON, DomaintypeId, EntityId}; diff --git a/crates/common/src/prov/id/mod.rs b/crates/common/src/prov/id/mod.rs index 8e3492f5a..20a05bfb3 100644 --- a/crates/common/src/prov/id/mod.rs +++ b/crates/common/src/prov/id/mod.rs @@ -2,12 +2,8 @@ mod graphlql_scalars; #[cfg(feature = "graphql-bindings")] use async_graphql::OneofObject; -#[cfg(feature = "graphql-bindings")] -pub use graphlql_scalars::*; -use iri_string::types::{IriAbsoluteString, UriAbsoluteString, UriRelativeStr}; -use parity_scale_codec::{Decode, Encode}; -use scale_info::{build::Fields, Path, Type, TypeInfo}; +use iri_string::types::{IriString, UriString}; use tracing::trace; #[cfg(feature = "diesel-bindings")] @@ -47,20 +43,20 @@ pub enum ParseIriError { } // Percent decoded, and has the correct authority -pub struct ProbableChronicleIri(iri_string::types::IriAbsoluteString); +pub struct ProbableChronicleIri(iri_string::types::IriString); impl ProbableChronicleIri { fn from_string(str: String) -> Result { - let uri = iri_string::types::UriAbsoluteString::try_from(str) + let uri = iri_string::types::UriString::try_from(str) .map_err(|e| ParseIriError::NotAnIri(e.into_source()))?; Self::from_uri(uri) } - fn from_uri(uri: UriAbsoluteString) -> Result { - let iri: IriAbsoluteString = uri.into(); - if iri.authority_str() != Some(Chronicle::PREFIX) - && iri.authority_str() != Some(Chronicle::LONG_PREFIX) + fn from_uri(uri: UriString) -> Result { + let iri: IriString = uri.into(); + if iri.authority_str() != Some(Chronicle::PREFIX) && + iri.authority_str() != Some(Chronicle::LONG_PREFIX) { return Err(ParseIriError::IncorrectIriKind(iri.to_string())); } @@ -68,7 +64,7 @@ impl ProbableChronicleIri { Ok(Self(iri)) } - fn path_components<'a>(&'a self) -> impl Iterator { + fn path_components(&self) -> impl Iterator { self.0.path_str().split(':') } } @@ -79,19 +75,15 @@ impl core::fmt::Display for ProbableChronicleIri { } } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] #[cfg_attr(feature = "diesel-bindings", derive(AsExpression, FromSqlRow))] #[cfg_attr(feature = "diesel-bindings", diesel(sql_type = diesel::sql_types::Text))] @@ -124,19 +116,15 @@ impl AsRef for &Role { } } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] #[cfg_attr(feature = "diesel-bindings", derive(AsExpression, FromSqlRow))] #[cfg_attr(feature = "diesel-bindings", diesel(sql_type = diesel::sql_types::Text))] @@ -174,7 +162,7 @@ pub trait ExternalIdPart { } pub trait UuidPart { - fn uuid_part(&self) -> &Uuid; + fn uuid_part(&self) -> Uuid; } /// Transform a chronicle IRI into its compact representation @@ -199,19 +187,15 @@ impl FromCompact for T { } } -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub enum ChronicleIri { Namespace(NamespaceId), @@ -224,6 +208,7 @@ pub enum ChronicleIri { Delegation(DelegationId), } +#[cfg(feature = "parity-encoding")] impl parity_scale_codec::MaxEncodedLen for ChronicleIri { fn max_encoded_len() -> usize { 2048usize @@ -343,19 +328,15 @@ fn optional_component(external_id: &str, component: &str) -> Result) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } @@ -410,10 +391,10 @@ impl TryFrom for DelegationId { } } -impl TryFrom for DelegationId { +impl TryFrom for DelegationId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -435,7 +416,7 @@ impl TryFrom for DelegationId { } } -impl From<&DelegationId> for UriAbsoluteString { +impl From<&DelegationId> for UriString { fn from(val: &DelegationId) -> Self { Chronicle::delegation( &AgentId::from_external_id(&val.delegate), @@ -443,24 +424,19 @@ impl From<&DelegationId> for UriAbsoluteString { &val.activity().map(|n| ActivityId::from_external_id(n.external_id_part())), &val.role, ) - .into() } } // A composite identifier of agent, activity and role -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct AssociationId { agent: ExternalId, @@ -470,7 +446,7 @@ pub struct AssociationId { impl core::fmt::Display for AssociationId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } @@ -504,10 +480,10 @@ impl TryFrom for AssociationId { } } -impl TryFrom for AssociationId { +impl TryFrom for AssociationId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -528,31 +504,26 @@ impl TryFrom for AssociationId { } } -impl From<&AssociationId> for UriAbsoluteString { +impl From<&AssociationId> for UriString { fn from(val: &AssociationId) -> Self { Chronicle::association( &AgentId::from_external_id(&val.agent), &ActivityId::from_external_id(&val.activity), &val.role, ) - .into() } } // A composite identifier of agent, entity, and role -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct AttributionId { agent: ExternalId, @@ -562,7 +533,7 @@ pub struct AttributionId { impl core::fmt::Display for AttributionId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } @@ -596,10 +567,10 @@ impl TryFrom for AttributionId { } } -impl TryFrom for AttributionId { +impl TryFrom for AttributionId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -620,36 +591,31 @@ impl TryFrom for AttributionId { } } -impl From<&AttributionId> for UriAbsoluteString { +impl From<&AttributionId> for UriString { fn from(val: &AttributionId) -> Self { Chronicle::attribution( &AgentId::from_external_id(&val.agent), &EntityId::from_external_id(&val.entity), &val.role, ) - .into() - } -} - -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, + } +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct DomaintypeId(ExternalId); impl core::fmt::Display for DomaintypeId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } @@ -673,10 +639,10 @@ impl TryFrom for DomaintypeId { } } -impl TryFrom for DomaintypeId { +impl TryFrom for DomaintypeId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -692,74 +658,36 @@ impl TryFrom for DomaintypeId { } } -impl From<&DomaintypeId> for UriAbsoluteString { +impl From<&DomaintypeId> for UriString { fn from(val: &DomaintypeId) -> Self { - Chronicle::domaintype(&val.0).into() - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)] -pub struct UuidWrapper(Uuid); - -impl From for UuidWrapper { - fn from(uuid: Uuid) -> Self { - Self(uuid) - } -} - -impl Encode for UuidWrapper { - fn encode_to(&self, dest: &mut T) { - self.0.as_bytes().encode_to(dest); + Chronicle::domaintype(&val.0) } } -impl Decode for UuidWrapper { - fn decode( - input: &mut I, - ) -> Result { - let uuid_bytes = <[u8; 16]>::decode(input)?; - let uuid = Uuid::from_slice(&uuid_bytes).map_err(|_| "Error decoding UUID")?; - Ok(Self(uuid)) - } -} - -impl TypeInfo for UuidWrapper { - type Identity = Self; - fn type_info() -> Type { - Type::builder() - .path(Path::new("UuidWrapper", module_path!())) - .composite(Fields::unnamed().field(|f| f.ty::<[u8; 16]>().type_name("Uuid"))) - } -} - -#[derive( - Serialize, - Deserialize, - Decode, - Encode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct NamespaceId { external_id: ExternalId, - uuid: UuidWrapper, + uuid: [u8; 16], } impl core::fmt::Display for NamespaceId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } impl NamespaceId { pub fn from_external_id(external_id: impl AsRef, uuid: Uuid) -> Self { - Self { external_id: external_id.as_ref().into(), uuid: uuid.into() } + Self { external_id: external_id.as_ref().into(), uuid: uuid.into_bytes() } } } @@ -770,8 +698,8 @@ impl ExternalIdPart for NamespaceId { } impl UuidPart for NamespaceId { - fn uuid_part(&self) -> &Uuid { - &self.uuid.0 + fn uuid_part(&self) -> Uuid { + Uuid::from_bytes(self.uuid) } } @@ -783,10 +711,10 @@ impl TryFrom for NamespaceId { } } -impl TryFrom for NamespaceId { +impl TryFrom for NamespaceId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -798,7 +726,7 @@ impl TryFrom for NamespaceId { match iri.path_components().collect::>().as_slice() { [_, external_id, uuid] => Ok(Self { external_id: ExternalId::from(external_id), - uuid: Uuid::parse_str(uuid).map_err(ParseIriError::UnparsableUuid)?.into(), + uuid: Uuid::parse_str(uuid).map_err(ParseIriError::UnparsableUuid)?.into_bytes(), }), _ => Err(ParseIriError::UnparsableIri(iri.to_string())), @@ -806,31 +734,27 @@ impl TryFrom for NamespaceId { } } -impl From<&NamespaceId> for UriAbsoluteString { +impl From<&NamespaceId> for UriString { fn from(val: &NamespaceId) -> Self { - Chronicle::namespace(&val.external_id, &val.uuid.0).into() - } -} - -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, + Chronicle::namespace(&val.external_id, &val.uuid_part()) + } +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct EntityId(ExternalId); impl core::fmt::Display for EntityId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } @@ -854,10 +778,10 @@ impl TryFrom for EntityId { } } -impl TryFrom for EntityId { +impl TryFrom for EntityId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -874,9 +798,9 @@ impl TryFrom for EntityId { } } -impl From<&EntityId> for UriAbsoluteString { +impl From<&EntityId> for UriString { fn from(val: &EntityId) -> Self { - Chronicle::entity(&val.0).into() + Chronicle::entity(&val.0) } } @@ -897,25 +821,21 @@ impl From for EntityId { } } -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct AgentId(ExternalId); impl core::fmt::Display for AgentId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(Into::::into(self).as_str()) + f.write_str(Into::::into(self).as_str()) } } @@ -939,16 +859,17 @@ impl TryFrom for AgentId { } } -impl TryFrom for AgentId { +impl TryFrom for AgentId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } impl TryFrom for AgentId { type Error = ParseIriError; + fn try_from(value: ProbableChronicleIri) -> Result { match value.path_components().collect::>().as_slice() { [_, external_id] => Ok(Self(ExternalId::from(external_id))), @@ -957,9 +878,9 @@ impl TryFrom for AgentId { } } -impl From<&AgentId> for UriAbsoluteString { +impl From<&AgentId> for UriString { fn from(val: &AgentId) -> Self { - UriAbsoluteString::from(Chronicle::agent(&val.0)) + UriString::from(Chronicle::agent(&val.0)) } } @@ -980,25 +901,21 @@ impl From for AgentId { } } -#[derive( - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, - PartialEq, - Eq, - Hash, - Debug, - Clone, - Ord, - PartialOrd, +#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Clone, Ord, PartialOrd)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] pub struct ActivityId(ExternalId); impl core::fmt::Display for ActivityId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(UriAbsoluteString::from(self).as_str()) + f.write_str(UriString::from(self).as_str()) } } @@ -1022,10 +939,10 @@ impl TryFrom for ActivityId { } } -impl TryFrom for ActivityId { +impl TryFrom for ActivityId { type Error = ParseIriError; - fn try_from(value: UriAbsoluteString) -> Result { + fn try_from(value: UriString) -> Result { ProbableChronicleIri::from_uri(value)?.try_into() } } @@ -1042,9 +959,9 @@ impl TryFrom for ActivityId { } } -impl From<&ActivityId> for UriAbsoluteString { +impl From<&ActivityId> for UriString { fn from(val: &ActivityId) -> Self { - Chronicle::activity(&val.0).into() + Chronicle::activity(&val.0) } } diff --git a/crates/common/src/prov/model/contradiction.rs b/crates/common/src/prov/model/contradiction.rs index 2ef602dfc..d5030a6b0 100644 --- a/crates/common/src/prov/model/contradiction.rs +++ b/crates/common/src/prov/model/contradiction.rs @@ -1,5 +1,4 @@ use chrono::{DateTime, Utc}; -use scale_info::TypeInfo; #[cfg(not(feature = "std"))] use parity_scale_codec::{alloc::string::String, alloc::vec::Vec}; @@ -12,9 +11,11 @@ use crate::{ prov::{operations::TimeWrapper, ChronicleIri, NamespaceId}, }; -use parity_scale_codec::{Decode, Encode}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Encode, Decode, TypeInfo)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] pub struct Contradiction { pub(crate) id: ChronicleIri, pub(crate) namespace: NamespaceId, @@ -113,7 +114,11 @@ impl Contradiction { } } -#[derive(Debug, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, Eq, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] pub enum ContradictionDetail { AttributeValueChange { name: String, value: Attribute, attempted: Attribute }, StartAlteration { value: TimeWrapper, attempted: TimeWrapper }, diff --git a/crates/common/src/prov/model/json_ld/from_json_ld.rs b/crates/common/src/prov/model/json_ld/from_json_ld.rs index b45f2fb76..d81b664ee 100644 --- a/crates/common/src/prov/model/json_ld/from_json_ld.rs +++ b/crates/common/src/prov/model/json_ld/from_json_ld.rs @@ -1,8 +1,8 @@ use chrono::{DateTime, Utc}; use futures::{future::BoxFuture, FutureExt}; -use iref::{Iri, IriBuf, IriRef}; -use iri_string::types::{IriAbsoluteString, UriAbsoluteStr, UriAbsoluteString}; +use iref::IriBuf; +use iri_string::types::IriString; use json_ld::{ syntax::IntoJsonWithContextMeta, Indexed, Loader, Node, Profile, RemoteDocument, Term, }; @@ -26,7 +26,7 @@ use crate::{ WasInformedBy, }, vocab::{Chronicle, ChronicleOperations, Prov}, - ActivityId, AgentId, DomaintypeId, EntityId, ExternalIdPart, NamespaceId, Role, UuidPart, + ActivityId, AgentId, DomaintypeId, EntityId, ExternalIdPart, NamespaceId, Role, }, }; @@ -74,11 +74,11 @@ fn as_json(node: &Node) -> serde_json::Value { } // Convert with coercion from our vocab iris, this is safe as sourced from constants -fn id_from_iri_string>(iri: I) -> json_ld::Id { +fn id_from_iri_string>(iri: I) -> json_ld::Id { json_ld::Id::Valid(json_ld::ValidId::Iri(IriBuf::try_from(iri.into().to_string()).unwrap())) } -fn extract_reference_ids>( +fn extract_reference_ids>( iri: I, node: &Node, ) -> Result, ProcessorError> { @@ -96,10 +96,10 @@ fn extract_reference_ids>( ids } -fn extract_scalar_prop<'a, I: Into + Clone>( +fn extract_scalar_prop + Clone>( iri: I, - node: &'a Node, -) -> Result<&'a Indexed, ()>, ProcessorError> { + node: &Node, +) -> Result<&Indexed, ()>, ProcessorError> { if let Some(object) = node.get_any(&id_from_iri_string(iri.clone())) { Ok(object) } else { @@ -192,7 +192,7 @@ impl ProvModel { if let serde_json::Value::Object(map) = as_json(node) { if let Some(serde_json::Value::Array(array)) = map.get(Chronicle::Value.as_str()) { if array.len() == 1 { - let o = array.get(0).unwrap(); + let o = array.first().unwrap(); let serde_object = &o["@value"]; if let serde_json::Value::Object(object) = serde_object { @@ -676,13 +676,7 @@ impl ChronicleOperation { object.value().inner().as_node().ok_or(ProcessorError::NotANode(json.clone()))?; if o.has_type(&id_from_iri_string(ChronicleOperations::CreateNamespace)) { let namespace = o.namespace(); - let external_id = namespace.external_id_part().to_owned(); - let uuid = namespace.uuid_part().to_owned(); - Ok(ChronicleOperation::CreateNamespace(CreateNamespace { - id: namespace, - external_id, - uuid: uuid.into(), - })) + Ok(ChronicleOperation::CreateNamespace(CreateNamespace { id: namespace })) } else if o.has_type(&id_from_iri_string(ChronicleOperations::AgentExists)) { let namespace = o.namespace(); let agent = o.agent(); @@ -802,7 +796,11 @@ impl ChronicleOperation { informing_activity, })) } else { - error!("Unknown operation: {:?}", o.type_entry()); + error!( + "Unknown operation: {:?} {:?}", + o.type_entry(), + id_from_iri_string(ChronicleOperations::SetAttributes) + ); unreachable!() } } else { diff --git a/crates/common/src/prov/model/json_ld/mod.rs b/crates/common/src/prov/model/json_ld/mod.rs index 8fc7d4c9b..066a143c4 100644 --- a/crates/common/src/prov/model/json_ld/mod.rs +++ b/crates/common/src/prov/model/json_ld/mod.rs @@ -32,6 +32,8 @@ pub enum CompactionError { #[error("Compacted document not a JSON object: {document}")] NoObject { document: Value }, } + +#[derive(Debug)] pub struct ExpandedJson(pub serde_json::Value); fn construct_context_definition( @@ -154,6 +156,7 @@ impl ExpandedJson { } // Sort @graph by json value, as they are unstable and we need deterministic output + #[tracing::instrument(skip(self), ret)] pub async fn compact(self) -> Result { let mut v: serde_json::Value = serde_json::from_str(&self.compact_unordered().await?.0.to_string())?; diff --git a/crates/common/src/prov/model/json_ld/to_json_ld.rs b/crates/common/src/prov/model/json_ld/to_json_ld.rs index 1c8a0dda0..97afe1b58 100644 --- a/crates/common/src/prov/model/json_ld/to_json_ld.rs +++ b/crates/common/src/prov/model/json_ld/to_json_ld.rs @@ -7,14 +7,12 @@ use parity_scale_codec::{ }; use super::ExpandedJson; -use crate::prov::operations::*; -use crate::prov::ProvModel; use crate::{ attributes::{Attribute, Attributes}, prov::{ - operations::{ChronicleOperation, CreateNamespace, DerivationType}, + operations::{ChronicleOperation, CreateNamespace, DerivationType, *}, vocab::{Chronicle, ChronicleOperations, Prov}, - ChronicleIri, ExternalIdPart, FromCompact, UuidPart, + ChronicleIri, ExternalIdPart, FromCompact, ProvModel, UuidPart, }, }; pub trait ToJson { @@ -23,6 +21,7 @@ pub trait ToJson { impl ToJson for ProvModel { /// Write the model out as a JSON-LD document in expanded form + #[tracing::instrument(skip(self), ret)] fn to_json(&self) -> ExpandedJson { let mut doc = Vec::new(); @@ -215,7 +214,7 @@ impl ToJson for ProvModel { for ((namespace, id), activity) in self.activities.iter() { let mut typ = vec![Prov::Activity.de_compact()]; - if let Some(x) = activity.domaintypeid.as_ref() { + if let Some(x) = activity.domaintype_id.as_ref() { typ.push(x.de_compact()) } @@ -276,7 +275,7 @@ impl ToJson for ProvModel { let mut values = Vec::new(); values.push(json!({ - "@id": Value::String(activity.namespaceid.de_compact()), + "@id": Value::String(activity.namespace_id.de_compact()), })); activitydoc.insert(Chronicle::HasNamespace.to_string(), Value::Array(values)); @@ -360,7 +359,7 @@ impl ToJson for ProvModel { entitydoc.insert(Prov::WasGeneratedBy.to_string(), Value::Array(ids)); } - let entity_key = (entity.namespaceid.clone(), entity.id.clone()); + let entity_key = (entity.namespace_id.clone(), entity.id.clone()); if let Some(attributions) = self.attribution.get(&entity_key) { let mut ids = Vec::new(); @@ -382,7 +381,7 @@ impl ToJson for ProvModel { let mut values = Vec::new(); values.push(json!({ - "@id": Value::String(entity.namespaceid.de_compact()), + "@id": Value::String(entity.namespace_id.de_compact()), })); entitydoc.insert(Chronicle::HasNamespace.to_string(), Value::Array(values)); diff --git a/crates/common/src/prov/model/mod.rs b/crates/common/src/prov/model/mod.rs index 9b48f76a5..28cfd45e9 100644 --- a/crates/common/src/prov/model/mod.rs +++ b/crates/common/src/prov/model/mod.rs @@ -1,10 +1,10 @@ mod contradiction; pub use contradiction::Contradiction; + #[cfg(feature = "json-ld")] pub mod json_ld; -pub mod transaction; - -use parity_scale_codec::{Decode, Encode}; +#[cfg(test)] +mod proptest; use core::{convert::Infallible, fmt::Debug}; #[cfg(not(feature = "std"))] @@ -13,7 +13,6 @@ use parity_scale_codec::{ alloc::string::String, alloc::vec::Vec, }; -use scale_info::TypeInfo; #[cfg(not(feature = "std"))] use scale_info::{ prelude::borrow::ToOwned, prelude::string::ToString, prelude::sync::Arc, prelude::*, @@ -31,7 +30,6 @@ use thiserror::Error; use thiserror_no_std::Error; use tracing::{instrument, trace}; -pub use transaction::ChronicleTransaction; use uuid::Uuid; use crate::{ @@ -48,14 +46,14 @@ use super::{ StartActivity, TimeWrapper, WasAssociatedWith, WasGeneratedBy, WasInformedBy, }, ActivityId, AgentId, AssociationId, AttributionId, ChronicleIri, DelegationId, DomaintypeId, - EntityId, ExternalId, ExternalIdPart, NamespaceId, Role, UuidPart, UuidWrapper, + EntityId, ExternalId, ExternalIdPart, NamespaceId, Role, UuidPart, }; +#[cfg(feature = "json-ld")] #[derive(Error, Debug)] pub enum ProcessorError { #[error("Invalid address")] Address, - #[cfg(feature = "json-ld")] #[error("Json Ld Error {0}")] Compaction(#[from] json_ld::CompactionError), #[error("Contradiction {0}")] @@ -64,7 +62,6 @@ pub enum ProcessorError { Expansion { inner: String }, #[error("IdentityError {0}")] Identity(#[from] IdentityError), - #[cfg(feature = "json-ld")] #[error("Invalid IRI {0}")] IRef(#[from] iref::Error), #[error("Not a Chronicle IRI {0}")] @@ -91,6 +88,39 @@ pub enum ProcessorError { Utf8(#[from] core::str::Utf8Error), } +#[cfg(not(feature = "json-ld"))] +#[derive(Error, Debug)] +pub enum ProcessorError { + #[error("Invalid address")] + Address, + #[error("Contradiction {0}")] + Contradiction(Contradiction), + #[error("IdentityError {0}")] + Identity(#[from] IdentityError), + #[error("Not a Chronicle IRI {0}")] + NotAChronicleIri(#[from] id::ParseIriError), + #[error("Missing @id {object:?}")] + MissingId { object: serde_json::Value }, + #[error("Missing property {iri}:{object:?}")] + MissingProperty { iri: String, object: serde_json::Value }, + #[error("Json LD object is not a node {0}")] + NotANode(serde_json::Value), + #[error("Chronicle value is not a JSON object")] + NotAnObject, + #[error("OpaExecutorError: {0}")] + OpaExecutor(#[from] anyhow::Error), + #[error("Malformed JSON {0}")] + SerdeJson(#[from] serde_json::Error), + #[error("Unparsable date/time {0}")] + SubmissionFormat(#[from] PayloadError), + #[error("Submission body format: {0}")] + Time(#[from] chrono::ParseError), + #[error("Tokio Error")] + Tokio, + #[error("State is not valid utf8 {0}")] + Utf8(#[from] core::str::Utf8Error), +} + #[derive(Error, Debug)] pub enum PayloadError { #[error("No list of Chronicle operations")] @@ -115,46 +145,80 @@ pub enum ChronicleTransactionIdError { InvalidTransactionId { id: String }, } -#[derive(Serialize, Deserialize, Encode, Decode, PartialEq, Eq, Debug, Clone)] -pub struct ChronicleTransactionId(String); +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy, Default)] +pub struct ChronicleTransactionId([u8; 16]); + +impl core::ops::Deref for ChronicleTransactionId { + type Target = [u8; 16]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} impl core::fmt::Display for ChronicleTransactionId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(&self.0) + f.write_str(&hex::encode(self.0)) } } + impl From for ChronicleTransactionId { fn from(u: Uuid) -> Self { - Self(u.to_string()) + Self(u.into_bytes()) } } -impl From<&str> for ChronicleTransactionId { - fn from(s: &str) -> Self { - Self(s.to_owned()) +impl From<[u8; 16]> for ChronicleTransactionId { + fn from(u: [u8; 16]) -> Self { + Self(u) } } -impl ChronicleTransactionId { - pub fn as_str(&self) -> &str { - &self.0 +impl core::convert::TryFrom for ChronicleTransactionId { + type Error = hex::FromHexError; + + fn try_from(s: String) -> Result { + Self::try_from(s.as_str()) } } -#[derive(Debug, Clone, Encode, Decode, TypeInfo, PartialEq, Eq, Serialize, Deserialize)] +impl core::convert::TryFrom<&str> for ChronicleTransactionId { + type Error = hex::FromHexError; + + fn try_from(s: &str) -> Result { + let bytes = hex::decode(s)?; + let mut array = [0; 16]; + array.copy_from_slice(&bytes[0..16]); + Ok(Self(array)) + } +} + +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Namespace { pub id: NamespaceId, - pub uuid: UuidWrapper, + pub uuid: [u8; 16], pub external_id: ExternalId, } impl Namespace { pub fn new(id: NamespaceId, uuid: Uuid, external_id: &ExternalId) -> Self { - Self { id, uuid: uuid.into(), external_id: external_id.to_owned() } + Self { id, uuid: uuid.into_bytes(), external_id: external_id.to_owned() } } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode, TypeInfo)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Agent { pub id: AgentId, pub namespaceid: NamespaceId, @@ -188,12 +252,16 @@ impl Agent { } } -#[derive(Debug, Clone, Encode, Decode, TypeInfo, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Activity { pub id: ActivityId, - pub namespaceid: NamespaceId, + pub namespace_id: NamespaceId, pub external_id: ExternalId, - pub domaintypeid: Option, + pub domaintype_id: Option, pub attributes: BTreeMap, pub started: Option, pub ended: Option, @@ -201,36 +269,40 @@ pub struct Activity { impl Activity { pub fn has_attributes(self, attributes: Attributes) -> Self { - let Self { id, namespaceid, external_id, started, ended, .. } = self; + let Self { id, namespace_id, external_id, started, ended, .. } = self; Self { id, - namespaceid, + namespace_id, external_id, started, ended, - domaintypeid: attributes.typ, + domaintype_id: attributes.typ, attributes: attributes.attributes, } } // Create a prototypical agent from its IRI, we can only determine external_id - pub fn exists(namespaceid: NamespaceId, id: ActivityId) -> Self { + pub fn exists(namespace_id: NamespaceId, id: ActivityId) -> Self { Self { - namespaceid, + namespace_id, external_id: id.external_id_part().to_owned(), id, started: None, ended: None, - domaintypeid: None, + domaintype_id: None, attributes: BTreeMap::new(), } } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode, TypeInfo)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Entity { pub id: EntityId, - pub namespaceid: NamespaceId, + pub namespace_id: NamespaceId, pub external_id: ExternalId, pub domaintypeid: Option, pub attributes: BTreeMap, @@ -238,10 +310,10 @@ pub struct Entity { impl Entity { pub fn has_attributes(self, attributes: Attributes) -> Self { - let Self { id, namespaceid, external_id, .. } = self; + let Self { id, namespace_id: namespaceid, external_id, .. } = self; Self { id, - namespaceid, + namespace_id: namespaceid, external_id, domaintypeid: attributes.typ, attributes: attributes.attributes, @@ -252,26 +324,17 @@ impl Entity { Self { external_id: id.external_id_part().to_owned(), id, - namespaceid, + namespace_id: namespaceid, domaintypeid: None, attributes: BTreeMap::new(), } } } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] pub struct Derivation { pub generated_id: EntityId, @@ -280,19 +343,10 @@ pub struct Derivation { pub typ: DerivationType, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] pub struct Delegation { pub namespace_id: NamespaceId, @@ -327,20 +381,12 @@ impl Delegation { } } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] + pub struct Association { pub namespace_id: NamespaceId, pub id: AssociationId, @@ -366,76 +412,40 @@ impl Association { } } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] pub struct Usage { pub activity_id: ActivityId, pub entity_id: EntityId, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] pub struct Generation { pub activity_id: ActivityId, pub generated_id: EntityId, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] pub struct GeneratedEntity { pub entity_id: EntityId, pub generated_id: ActivityId, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) )] pub struct Attribution { pub namespace_id: NamespaceId, @@ -467,7 +477,11 @@ type NamespacedAgent = NamespacedId; type NamespacedEntity = NamespacedId; type NamespacedActivity = NamespacedId; -#[derive(Debug, Default, Clone, PartialEq, Eq, Encode, Decode, TypeInfo)] +#[cfg_attr( + feature = "parity-encoding", + derive(scale_info::TypeInfo, parity_scale_codec::Encode, parity_scale_codec::Decode) +)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct ProvModel { pub namespaces: BTreeMap>, pub agents: BTreeMap>, @@ -484,6 +498,62 @@ pub struct ProvModel { pub usage: BTreeMap>>, } +#[cfg(feature = "parity-encoding")] +pub mod provmodel_protocol { + use super::*; + #[derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + Debug, + Default, + Clone, + Serialize, + Deserialize, + PartialEq, + Eq, + )] + pub struct ProvModelV1 { + pub namespaces: BTreeMap>, /* We need NamespaceIdV1 / + * NamespaceV1 etc, recursively + * until there are only primitive + * types */ + pub agents: BTreeMap>, + pub acted_on_behalf_of: BTreeMap>>, + pub delegation: BTreeMap>>, + pub entities: BTreeMap>, + pub derivation: BTreeMap>>, + pub generation: BTreeMap>>, + pub attribution: BTreeMap>>, + pub activities: BTreeMap>, + pub was_informed_by: BTreeMap>>, + pub generated: BTreeMap>>, + pub association: BTreeMap>>, + pub usage: BTreeMap>>, + } + + impl From for ProvModel { + fn from(value: ProvModelV1) -> Self { + ProvModel { + namespaces: value.namespaces, + agents: value.agents, + acted_on_behalf_of: value.acted_on_behalf_of, + delegation: value.delegation, + entities: value.entities, + derivation: value.derivation, + generation: value.generation, + attribution: value.attribution, + activities: value.activities, + was_informed_by: value.was_informed_by, + generated: value.generated, + association: value.association, + usage: value.usage, + } + } + } +} + +#[cfg(feature = "parity-encoding")] // TODO: We can make these structures reasonably bounded (and copy ids with interning) - though JSON // attributes may need some handwaving impl parity_scale_codec::MaxEncodedLen for ProvModel { @@ -509,6 +579,7 @@ impl ProvModel { self.association.extend(other.association.clone()); self.usage.extend(other.usage.clone()); } + /// Apply a sequence of `ChronicleTransaction` to an empty model, then return it pub fn from_tx<'a, I>(tx: I) -> Result where @@ -683,7 +754,7 @@ impl ProvModel { ns.clone(), Namespace { id: ns.clone(), - uuid: uuid.to_owned().into(), + uuid: uuid.into_bytes(), external_id: namespace_name.to_owned(), } .into(), @@ -701,6 +772,7 @@ impl ProvModel { pub fn get_agent(&mut self, ns: &NamespaceId, agent: &AgentId) -> Option<&Agent> { self.agents.get(&(ns.clone(), agent.clone())).map(|arc| arc.as_ref()) } + pub fn modify_agent( &mut self, ns: &NamespaceId, @@ -769,11 +841,7 @@ impl ProvModel { pub fn apply(&mut self, tx: &ChronicleOperation) -> Result<(), Contradiction> { let tx = tx.to_owned(); match tx { - ChronicleOperation::CreateNamespace(CreateNamespace { - id, - external_id: _, - uuid: _, - }) => { + ChronicleOperation::CreateNamespace(CreateNamespace { id }) => { self.namespace_context(&id); Ok(()) }, @@ -1025,7 +1093,7 @@ impl ProvModel { }; self.modify_activity(&namespace, &id, move |activity| { - activity.domaintypeid = attributes.typ.clone(); + activity.domaintype_id = attributes.typ.clone(); activity.attributes = attributes.attributes; }); @@ -1095,17 +1163,20 @@ impl ProvModel { } } + #[cfg(feature = "json-ld")] pub(crate) fn add_agent(&mut self, agent: Agent) { self.agents.insert((agent.namespaceid.clone(), agent.id.clone()), agent.into()); } + #[cfg(feature = "json-ld")] pub(crate) fn add_activity(&mut self, activity: Activity) { self.activities - .insert((activity.namespaceid.clone(), activity.id.clone()), activity.into()); + .insert((activity.namespace_id.clone(), activity.id.clone()), activity.into()); } + #[cfg(feature = "json-ld")] pub(crate) fn add_entity(&mut self, entity: Entity) { self.entities - .insert((entity.namespaceid.clone(), entity.id.clone()), entity.into()); + .insert((entity.namespace_id.clone(), entity.id.clone()), entity.into()); } } diff --git a/crates/common/src/prov/model/proptest.rs b/crates/common/src/prov/model/proptest.rs index 7d9d50459..c64243816 100644 --- a/crates/common/src/prov/model/proptest.rs +++ b/crates/common/src/prov/model/proptest.rs @@ -6,7 +6,7 @@ use uuid::Uuid; use crate::{ attributes::{Attribute, Attributes}, prov::{ - operations::*, to_json_ld::ToJson, ActivityId, AgentId, Association, AssociationId, + json_ld::ToJson, operations::*, ActivityId, AgentId, Association, AssociationId, Attribution, Contradiction, Delegation, DelegationId, Derivation, DomaintypeId, EntityId, ExternalId, ExternalIdPart, Generation, NamespaceId, ProvModel, Role, Usage, UuidPart, }, @@ -65,11 +65,9 @@ prop_compose! { prop_compose! { fn create_namespace()(id in namespace()) -> CreateNamespace { - let (external_id,uuid) = (id.external_id_part(), id.uuid_part()); + let (_external_id,_uuid) = (id.external_id_part(), id.uuid_part()); CreateNamespace { id: id.clone(), - uuid: (*uuid).into(), - external_id: external_id.to_owned(), } } } @@ -369,18 +367,16 @@ proptest! { // operation if let Some((_op,Contradiction {id: _,namespace: _,contradiction})) = contradiction { - let _contradiction = contradiction.get(0).unwrap(); + let _contradiction = contradiction.first().unwrap(); } // Now assert that the final prov object matches what we would expect from the input operations for op in applied_operations.iter() { match op { - ChronicleOperation::CreateNamespace(CreateNamespace{id,external_id,uuid}) => { + ChronicleOperation::CreateNamespace(CreateNamespace{id}) => { prop_assert!(prov.namespaces.contains_key(id)); let ns = prov.namespaces.get(id).unwrap(); prop_assert_eq!(&ns.id, id); - prop_assert_eq!(&ns.external_id, external_id); - prop_assert_eq!(&ns.uuid, uuid); }, ChronicleOperation::AgentExists( AgentExists { namespace, external_id}) => { @@ -425,7 +421,7 @@ proptest! { prop_assert!(activity.is_some()); let activity = activity.unwrap(); prop_assert_eq!(&activity.external_id, external_id); - prop_assert_eq!(&activity.namespaceid, namespace); + prop_assert_eq!(&activity.namespace_id, namespace); }, ChronicleOperation::StartActivity( StartActivity { namespace, id, time }) => { @@ -433,7 +429,7 @@ proptest! { prop_assert!(activity.is_some()); let activity = activity.unwrap(); prop_assert_eq!(&activity.external_id, id.external_id_part()); - prop_assert_eq!(&activity.namespaceid, namespace); + prop_assert_eq!(&activity.namespace_id, namespace); prop_assert!(activity.started == Some(time.to_owned())); }, @@ -443,7 +439,7 @@ proptest! { prop_assert!(activity.is_some()); let activity = activity.unwrap(); prop_assert_eq!(&activity.external_id, id.external_id_part()); - prop_assert_eq!(&activity.namespaceid, namespace); + prop_assert_eq!(&activity.namespace_id, namespace); prop_assert!(activity.ended == Some(time.to_owned())); } @@ -478,13 +474,13 @@ proptest! { prop_assert!(entity.is_some()); let entity = entity.unwrap(); prop_assert_eq!(&entity.external_id, id.external_id_part()); - prop_assert_eq!(&entity.namespaceid, namespace); + prop_assert_eq!(&entity.namespace_id, namespace); let activity = &prov.activities.get(&(namespace.to_owned(),activity_id.to_owned())); prop_assert!(activity.is_some()); let activity = activity.unwrap(); prop_assert_eq!(&activity.external_id, activity_id.external_id_part()); - prop_assert_eq!(&activity.namespaceid, namespace); + prop_assert_eq!(&activity.namespace_id, namespace); let has_usage = prov.usage.get(&(namespace.to_owned(), activity_id.to_owned())) .unwrap() @@ -501,7 +497,7 @@ proptest! { prop_assert!(entity.is_some()); let entity = entity.unwrap(); prop_assert_eq!(&entity.external_id, external_id); - prop_assert_eq!(&entity.namespaceid, namespace); + prop_assert_eq!(&entity.namespace_id, namespace); }, ChronicleOperation::WasGeneratedBy(WasGeneratedBy{namespace, id, activity}) => { let activity_id = activity; @@ -509,13 +505,13 @@ proptest! { prop_assert!(entity.is_some()); let entity = entity.unwrap(); prop_assert_eq!(&entity.external_id, id.external_id_part()); - prop_assert_eq!(&entity.namespaceid, namespace); + prop_assert_eq!(&entity.namespace_id, namespace); let activity = &prov.activities.get(&(namespace.to_owned(),activity.to_owned())); prop_assert!(activity.is_some()); let activity = activity.unwrap(); prop_assert_eq!(&activity.external_id, activity_id.external_id_part()); - prop_assert_eq!(&activity.namespaceid, namespace); + prop_assert_eq!(&activity.namespace_id, namespace); let has_generation = prov.generation.get( &(namespace.clone(),id.clone())) @@ -532,7 +528,7 @@ proptest! { prop_assert!(informed_activity.is_some()); let informed_activity = informed_activity.unwrap(); prop_assert_eq!(&informed_activity.external_id, activity.external_id_part()); - prop_assert_eq!(&informed_activity.namespaceid, namespace); + prop_assert_eq!(&informed_activity.namespace_id, namespace); let was_informed_by = prov.was_informed_by.get( &(namespace.clone(), activity.clone())) @@ -580,7 +576,7 @@ proptest! { prop_assert!(activity.is_some()); let activity = activity.unwrap(); - prop_assert_eq!(&activity.domaintypeid, &attributes.typ); + prop_assert_eq!(&activity.domaintype_id, &attributes.typ); }, ChronicleOperation::SetAttributes(SetAttributes::Agent { namespace, id, attributes}) => { let agent = &prov.agents.get(&(namespace.to_owned(),id.to_owned())); @@ -599,10 +595,22 @@ proptest! { let serialized_prov = prov_from_json_ld(lhs_json.clone()); - prop_assert_eq!(&prov, &serialized_prov, "Prov reserialisation compact: \n{} expanded \n {}", serde_json::to_string_pretty(&lhs_json).unwrap(), serde_json::to_string_pretty(&lhs_json_expanded).unwrap()); + + use parity_scale_codec::{Encode, Decode}; + // Test that serialization to and from parity_scale_codec is symmetric for operations + for op in applied_operations.iter() { + let encoded_op = op.encode(); + let decoded_op: Result = ChronicleOperation::decode(&mut &encoded_op[..]); + + prop_assert!(decoded_op.is_ok(), "Failed to decode operation: {:?}", op); + let decoded_op = decoded_op.expect("Failed to decode operation"); + + prop_assert_eq!(op, &decoded_op, "Parity scale codec reserialization: \nOriginal: {:?} \nDecoded: {:?}", op, decoded_op); + } + // Test that serialisation to JSON-LD is deterministic for _ in 0..10 { let lhs_json_2 = compact_json(&prov).clone(); diff --git a/crates/common/src/prov/model/transaction/mod.rs b/crates/common/src/prov/model/transaction/mod.rs deleted file mode 100644 index ffb3f159f..000000000 --- a/crates/common/src/prov/model/transaction/mod.rs +++ /dev/null @@ -1,70 +0,0 @@ -pub mod v1; -pub mod v2; - -// This is the current version. -pub use v2::ChronicleTransaction; - -impl From for v2::ChronicleTransaction { - fn from(transaction: v1::ChronicleTransaction) -> Self { - v2::ChronicleTransaction::new(transaction.tx, transaction.identity) - } -} - -pub trait HasVersion { - fn get_version(&self) -> u16; -} - -impl HasVersion for v1::ChronicleTransaction { - fn get_version(&self) -> u16 { - 1 - } -} - -impl HasVersion for v2::ChronicleTransaction { - fn get_version(&self) -> u16 { - 2 - } -} - -pub const CURRENT_VERSION: u16 = 2; - -pub trait ToChronicleTransaction { - fn to_current(self) -> ChronicleTransaction; -} - -impl ToChronicleTransaction for v1::ChronicleTransaction { - fn to_current(self) -> ChronicleTransaction { - self.into() - } -} - -impl ToChronicleTransaction for v2::ChronicleTransaction { - fn to_current(self) -> ChronicleTransaction { - self - } -} - -#[cfg(test)] -mod test { - use super::{HasVersion, ToChronicleTransaction}; - use crate::identity::SignedIdentity; - - #[test] - fn transaction_versions() { - let transaction_v1 = - super::v1::ChronicleTransaction::new(Vec::default(), SignedIdentity::new_no_identity()); - let transaction_v2: super::v2::ChronicleTransaction = transaction_v1.clone().into(); - let transaction_current = transaction_v2.clone(); - - // check that the above sequence ends at the current version - assert_eq!(super::CURRENT_VERSION, transaction_current.get_version()); - - // check the reported version numbers - assert_eq!(1, transaction_v1.get_version()); - assert_eq!(2, transaction_v2.get_version()); - - // check the conversions to current - assert_eq!(transaction_current, transaction_v1.to_current()); - assert_eq!(transaction_current, transaction_v2.to_current()); - } -} diff --git a/crates/common/src/prov/model/transaction/v1/mod.rs b/crates/common/src/prov/model/transaction/v1/mod.rs deleted file mode 100644 index fc5be7345..000000000 --- a/crates/common/src/prov/model/transaction/v1/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::{identity::SignedIdentity, prov::operations::ChronicleOperation}; -#[cfg(not(feature = "std"))] -use parity_scale_codec::alloc::vec::Vec; - -#[derive(PartialEq, Eq, Debug, Clone)] -pub struct ChronicleTransaction { - pub tx: Vec, - pub identity: SignedIdentity, -} - -impl ChronicleTransaction { - pub fn new(tx: Vec, identity: SignedIdentity) -> Self { - Self { tx, identity } - } -} diff --git a/crates/common/src/prov/model/transaction/v2/mod.rs b/crates/common/src/prov/model/transaction/v2/mod.rs deleted file mode 100644 index fc5be7345..000000000 --- a/crates/common/src/prov/model/transaction/v2/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::{identity::SignedIdentity, prov::operations::ChronicleOperation}; -#[cfg(not(feature = "std"))] -use parity_scale_codec::alloc::vec::Vec; - -#[derive(PartialEq, Eq, Debug, Clone)] -pub struct ChronicleTransaction { - pub tx: Vec, - pub identity: SignedIdentity, -} - -impl ChronicleTransaction { - pub fn new(tx: Vec, identity: SignedIdentity) -> Self { - Self { tx, identity } - } -} diff --git a/crates/common/src/prov/operations.rs b/crates/common/src/prov/operations.rs index 046973ddf..7df8cd708 100644 --- a/crates/common/src/prov/operations.rs +++ b/crates/common/src/prov/operations.rs @@ -13,31 +13,22 @@ use diesel::{ #[cfg(not(feature = "std"))] use parity_scale_codec::alloc::string::String; -use parity_scale_codec::{Decode, Encode, Error, Input}; -use scale_info::{build::Fields, Path, Type, TypeInfo}; -use uuid::Uuid; - use crate::attributes::Attributes; use super::{ ActivityId, AgentId, AssociationId, AttributionId, DelegationId, EntityId, ExternalId, - NamespaceId, Role, UuidWrapper, + NamespaceId, Role, }; -#[derive( - Debug, - Copy, - Clone, - PartialEq, - Ord, - PartialOrd, - Eq, - Hash, - Serialize, - Deserialize, - Encode, - Decode, - TypeInfo, +#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) )] #[cfg_attr(feature = "diesel-bindings", derive(AsExpression, SqlType, QueryId))] #[cfg_attr(feature = "diesel-bindings", diesel(sql_type = Integer))] @@ -112,20 +103,36 @@ impl DerivationType { } } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct CreateNamespace { pub id: NamespaceId, - pub external_id: ExternalId, - pub uuid: UuidWrapper, } impl CreateNamespace { - pub fn new(id: NamespaceId, external_id: impl AsRef, uuid: Uuid) -> Self { - Self { id, external_id: external_id.as_ref().into(), uuid: uuid.into() } + pub fn new(id: NamespaceId) -> Self { + Self { id } } } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct AgentExists { pub namespace: NamespaceId, pub external_id: ExternalId, @@ -137,7 +144,16 @@ impl AgentExists { } } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct ActsOnBehalfOf { pub id: DelegationId, pub role: Option, @@ -170,8 +186,16 @@ impl ActsOnBehalfOf { } } } - -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct ActivityExists { pub namespace: NamespaceId, pub external_id: ExternalId, @@ -184,6 +208,10 @@ impl TimeWrapper { pub fn to_rfc3339(&self) -> String { self.0.to_rfc3339() } + + pub fn naive_utc(&self) -> NaiveDateTime { + self.0.naive_utc() + } } impl core::fmt::Display for TimeWrapper { @@ -198,7 +226,22 @@ impl From> for TimeWrapper { } } -impl Encode for TimeWrapper { +#[cfg(feature = "parity-encoding")] +impl scale_encode::EncodeAsType for TimeWrapper { + fn encode_as_type_to( + &self, + type_id: u32, + types: &scale_info::PortableRegistry, + out: &mut scale_encode::Vec, + ) -> Result<(), scale_encode::Error> { + let timestamp = self.0.timestamp(); + let subsec_nanos = self.0.timestamp_subsec_nanos(); + (timestamp, subsec_nanos).encode_as_type_to(type_id, types, out) + } +} + +#[cfg(feature = "parity-encoding")] +impl parity_scale_codec::Encode for TimeWrapper { fn encode_to(&self, dest: &mut T) { let timestamp = self.0.timestamp(); let subsec_nanos = self.0.timestamp_subsec_nanos(); @@ -206,8 +249,11 @@ impl Encode for TimeWrapper { } } -impl Decode for TimeWrapper { - fn decode(input: &mut I) -> Result { +#[cfg(feature = "parity-encoding")] +impl parity_scale_codec::Decode for TimeWrapper { + fn decode( + input: &mut I, + ) -> Result { let (timestamp, subsec_nanos) = <(i64, u32)>::decode(input)?; let datetime = Utc.from_utc_datetime( @@ -219,53 +265,110 @@ impl Decode for TimeWrapper { } } -impl TypeInfo for TimeWrapper { +#[cfg(feature = "parity-encoding")] +impl scale_info::TypeInfo for TimeWrapper { type Identity = Self; - fn type_info() -> Type { - Type::builder().path(Path::new("TimeWrapper", module_path!())).composite( - Fields::unnamed() - .field(|f| f.ty::().type_name("Timestamp")) - .field(|f| f.ty::().type_name("SubsecNanos")), - ) + fn type_info() -> scale_info::Type { + scale_info::Type::builder() + .path(scale_info::Path::new("TimeWrapper", module_path!())) + .composite( + scale_info::build::Fields::unnamed() + .field(|f| f.ty::().type_name("Timestamp")) + .field(|f| f.ty::().type_name("SubsecNanos")), + ) } } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct StartActivity { pub namespace: NamespaceId, pub id: ActivityId, pub time: TimeWrapper, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct EndActivity { pub namespace: NamespaceId, pub id: ActivityId, pub time: TimeWrapper, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct ActivityUses { pub namespace: NamespaceId, pub id: EntityId, pub activity: ActivityId, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct EntityExists { pub namespace: NamespaceId, pub external_id: ExternalId, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct WasGeneratedBy { pub namespace: NamespaceId, pub id: EntityId, pub activity: ActivityId, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct EntityDerive { pub namespace: NamespaceId, pub id: EntityId, @@ -274,7 +377,16 @@ pub struct EntityDerive { pub typ: DerivationType, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct WasAssociatedWith { pub id: AssociationId, pub role: Option, @@ -300,7 +412,16 @@ impl WasAssociatedWith { } } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct WasAttributedTo { pub id: AttributionId, pub role: Option, @@ -326,21 +447,48 @@ impl WasAttributedTo { } } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct WasInformedBy { pub namespace: NamespaceId, pub activity: ActivityId, pub informing_activity: ActivityId, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub enum SetAttributes { Entity { namespace: NamespaceId, id: EntityId, attributes: Attributes }, Agent { namespace: NamespaceId, id: AgentId, attributes: Attributes }, Activity { namespace: NamespaceId, id: ActivityId, attributes: Attributes }, } -#[derive(Serialize, Deserialize, Encode, Decode, TypeInfo, PartialEq, Eq, Debug, Clone)] +#[cfg_attr( + feature = "parity-encoding", + derive( + scale_info::TypeInfo, + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_encode::EncodeAsType + ) +)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub enum ChronicleOperation { CreateNamespace(CreateNamespace), AgentExists(AgentExists), diff --git a/crates/common/src/prov/vocab.rs b/crates/common/src/prov/vocab.rs index 64228c57e..c105b7ca4 100644 --- a/crates/common/src/prov/vocab.rs +++ b/crates/common/src/prov/vocab.rs @@ -1,5 +1,4 @@ mod chronicle_operations { - use iri_string::types::{IriAbsoluteString, UriAbsoluteString}; #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub enum ChronicleOperations { @@ -39,89 +38,87 @@ mod chronicle_operations { Generated, } - const ACTIVITY_EXISTS: &str = "http://btp.works/chronicleoperation/ns#ActivityExists"; - const ACTIVITY_NAME: &str = "http://btp.works/chronicleoperation/ns#ActivityName"; - const START_ACTIVITY: &str = "http://btp.works/chronicleoperation/ns#StartActivity"; - const START_ACTIVITY_TIME: &str = "http://btp.works/chronicleoperation/ns#StartActivityTime"; - const END_ACTIVITY: &str = "http://btp.works/chronicleoperation/ns#EndActivity"; - const END_ACTIVITY_TIME: &str = "http://btp.works/chronicleoperation/ns#EndActivityTime"; - const WAS_ASSOCIATED_WITH: &str = "http://btp.works/chronicleoperation/ns#WasAssociatedWith"; - const WAS_ATTRIBUTED_TO: &str = "http://btp.works/chronicleoperation/ns#WasAttributedTo"; - const ACTIVITY_USES: &str = "http://btp.works/chronicleoperation/ns#ActivityUses"; - const ENTITY_NAME: &str = "http://btp.works/chronicleoperation/ns#EntityName"; - const LOCATOR: &str = "http://btp.works/chronicleoperation/ns#Locator"; - const ROLE: &str = "http://btp.works/chronicleoperation/ns#Role"; - const ENTITY_EXISTS: &str = "http://btp.works/chronicleoperation/ns#EntityExists"; - const WAS_GENERATED_BY: &str = "http://btp.works/chronicleoperation/ns#WasGeneratedBy"; - const ENTITY_DERIVE: &str = "http://btp.works/chronicleoperation/ns#EntityDerive"; - const DERIVATION_TYPE: &str = "http://btp.works/chronicleoperation/ns#DerivationType"; - const USED_ENTITY_NAME: &str = "http://btp.works/chronicleoperation/ns#UsedEntityName"; - const SET_ATTRIBUTES: &str = "http://btp.works/chronicleoperation/ns#SetAttributes"; - const ATTRIBUTES: &str = "http://btp.works/chronicleoperation/ns#Attributes"; - const ATTRIBUTE: &str = "http://btp.works/chronicleoperation/ns#Attribute"; - const DOMAINTYPE_ID: &str = "http://btp.works/chronicleoperation/ns#DomaintypeId"; - const WAS_INFORMED_BY: &str = "http://btp.works/chronicleoperation/ns#WasInformedBy"; + const ACTIVITY_EXISTS: &str = "http://btp.works/chronicleoperations/ns#ActivityExists"; + const ACTIVITY_NAME: &str = "http://btp.works/chronicleoperations/ns#ActivityName"; + const START_ACTIVITY: &str = "http://btp.works/chronicleoperations/ns#StartActivity"; + const START_ACTIVITY_TIME: &str = "http://btp.works/chronicleoperations/ns#StartActivityTime"; + const END_ACTIVITY: &str = "http://btp.works/chronicleoperations/ns#EndActivity"; + const END_ACTIVITY_TIME: &str = "http://btp.works/chronicleoperations/ns#EndActivityTime"; + const WAS_ASSOCIATED_WITH: &str = "http://btp.works/chronicleoperations/ns#WasAssociatedWith"; + const WAS_ATTRIBUTED_TO: &str = "http://btp.works/chronicleoperations/ns#WasAttributedTo"; + const ACTIVITY_USES: &str = "http://btp.works/chronicleoperations/ns#ActivityUses"; + const ENTITY_NAME: &str = "http://btp.works/chronicleoperations/ns#EntityName"; + const LOCATOR: &str = "http://btp.works/chronicleoperations/ns#Locator"; + const ROLE: &str = "http://btp.works/chronicleoperations/ns#Role"; + const ENTITY_EXISTS: &str = "http://btp.works/chronicleoperations/ns#EntityExists"; + const WAS_GENERATED_BY: &str = "http://btp.works/chronicleoperations/ns#WasGeneratedBy"; + const ENTITY_DERIVE: &str = "http://btp.works/chronicleoperations/ns#EntityDerive"; + const DERIVATION_TYPE: &str = "http://btp.works/chronicleoperations/ns#DerivationType"; + const USED_ENTITY_NAME: &str = "http://btp.works/chronicleoperations/ns#UsedEntityName"; + const SET_ATTRIBUTES: &str = "http://btp.works/chronicleoperations/ns#SetAttributes"; + const ATTRIBUTES: &str = "http://btp.works/chronicleoperations/ns#Attributes"; + const ATTRIBUTE: &str = "http://btp.works/chronicleoperations/ns#Attribute"; + const DOMAINTYPE_ID: &str = "http://btp.works/chronicleoperations/ns#DomaintypeId"; + const WAS_INFORMED_BY: &str = "http://btp.works/chronicleoperations/ns#WasInformedBy"; const INFORMING_ACTIVITY_NAME: &str = - "http://btp.works/chronicleoperation/ns#InformingActivityName"; - const GENERATED: &str = "http://btp.works/chronicleoperation/ns#Generated"; - const CREATE_NAMESPACE: &str = "http://btp.works/chronicleoperation/ns#CreateNamespace"; - const NAMESPACE_NAME: &str = "http://btp.works/chronicleoperation/ns#namespaceName"; - const NAMESPACE_UUID: &str = "http://btp.works/chronicleoperation/ns#namespaceUuid"; - const AGENT_EXISTS: &str = "http://btp.works/chronicleoperation/ns#AgentExists"; - const AGENT_NAME: &str = "http://btp.works/chronicleoperation/ns#agentName"; - const AGENT_UUID: &str = "http://btp.works/chronicleoperation/ns#agentUuid"; + "http://btp.works/chronicleoperations/ns#InformingActivityName"; + const GENERATED: &str = "http://btp.works/chronicleoperations/ns#Generated"; + const CREATE_NAMESPACE: &str = "http://btp.works/chronicleoperations/ns#CreateNamespace"; + const NAMESPACE_NAME: &str = "http://btp.works/chronicleoperations/ns#namespaceName"; + const NAMESPACE_UUID: &str = "http://btp.works/chronicleoperations/ns#namespaceUuid"; + const AGENT_EXISTS: &str = "http://btp.works/chronicleoperations/ns#AgentExists"; + const AGENT_NAME: &str = "http://btp.works/chronicleoperations/ns#agentName"; + const AGENT_UUID: &str = "http://btp.works/chronicleoperations/ns#agentUuid"; const AGENT_ACTS_ON_BEHALF_OF: &str = - "http://btp.works/chronicleoperation/ns#AgentActsOnBehalfOf"; - const DELEGATE_ID: &str = "http://btp.works/chronicleoperation/ns#delegateId"; - const RESPONSIBLE_ID: &str = "http://btp.works/chronicleoperation/ns#responsibleId"; + "http://btp.works/chronicleoperations/ns#AgentActsOnBehalfOf"; + const DELEGATE_ID: &str = "http://btp.works/chronicleoperations/ns#delegateId"; + const RESPONSIBLE_ID: &str = "http://btp.works/chronicleoperations/ns#responsibleId"; impl AsRef for ChronicleOperations { fn as_ref(&self) -> &'static str { match self { - ChronicleOperations::ActivityExists => &ACTIVITY_EXISTS, - ChronicleOperations::ActivityName => &ACTIVITY_NAME, - ChronicleOperations::StartActivity => &START_ACTIVITY, - ChronicleOperations::StartActivityTime => &START_ACTIVITY_TIME, - ChronicleOperations::EndActivity => &END_ACTIVITY, - ChronicleOperations::EndActivityTime => &END_ACTIVITY_TIME, - ChronicleOperations::WasAssociatedWith => &WAS_ASSOCIATED_WITH, - ChronicleOperations::WasAttributedTo => &WAS_ATTRIBUTED_TO, - ChronicleOperations::ActivityUses => &ACTIVITY_USES, - ChronicleOperations::EntityName => &ENTITY_NAME, - ChronicleOperations::Locator => &LOCATOR, - ChronicleOperations::Role => &ROLE, - ChronicleOperations::EntityExists => &ENTITY_EXISTS, - ChronicleOperations::WasGeneratedBy => &WAS_GENERATED_BY, - ChronicleOperations::EntityDerive => &ENTITY_DERIVE, - ChronicleOperations::DerivationType => &DERIVATION_TYPE, - ChronicleOperations::UsedEntityName => &USED_ENTITY_NAME, - ChronicleOperations::SetAttributes => &SET_ATTRIBUTES, - ChronicleOperations::Attributes => &ATTRIBUTES, - ChronicleOperations::Attribute => &ATTRIBUTE, - ChronicleOperations::DomaintypeId => &DOMAINTYPE_ID, - ChronicleOperations::WasInformedBy => &WAS_INFORMED_BY, - ChronicleOperations::InformingActivityName => &INFORMING_ACTIVITY_NAME, - ChronicleOperations::Generated => &GENERATED, - ChronicleOperations::CreateNamespace => &CREATE_NAMESPACE, - ChronicleOperations::NamespaceName => &NAMESPACE_NAME, - ChronicleOperations::NamespaceUuid => &NAMESPACE_UUID, - ChronicleOperations::AgentExists => &AGENT_EXISTS, - ChronicleOperations::AgentName => &AGENT_NAME, - ChronicleOperations::AgentUuid => &AGENT_UUID, - ChronicleOperations::AgentActsOnBehalfOf => &AGENT_ACTS_ON_BEHALF_OF, - ChronicleOperations::DelegateId => &DELEGATE_ID, - ChronicleOperations::ResponsibleId => &RESPONSIBLE_ID, + ChronicleOperations::ActivityExists => ACTIVITY_EXISTS, + ChronicleOperations::ActivityName => ACTIVITY_NAME, + ChronicleOperations::StartActivity => START_ACTIVITY, + ChronicleOperations::StartActivityTime => START_ACTIVITY_TIME, + ChronicleOperations::EndActivity => END_ACTIVITY, + ChronicleOperations::EndActivityTime => END_ACTIVITY_TIME, + ChronicleOperations::WasAssociatedWith => WAS_ASSOCIATED_WITH, + ChronicleOperations::WasAttributedTo => WAS_ATTRIBUTED_TO, + ChronicleOperations::ActivityUses => ACTIVITY_USES, + ChronicleOperations::EntityName => ENTITY_NAME, + ChronicleOperations::Locator => LOCATOR, + ChronicleOperations::Role => ROLE, + ChronicleOperations::EntityExists => ENTITY_EXISTS, + ChronicleOperations::WasGeneratedBy => WAS_GENERATED_BY, + ChronicleOperations::EntityDerive => ENTITY_DERIVE, + ChronicleOperations::DerivationType => DERIVATION_TYPE, + ChronicleOperations::UsedEntityName => USED_ENTITY_NAME, + ChronicleOperations::SetAttributes => SET_ATTRIBUTES, + ChronicleOperations::Attributes => ATTRIBUTES, + ChronicleOperations::Attribute => ATTRIBUTE, + ChronicleOperations::DomaintypeId => DOMAINTYPE_ID, + ChronicleOperations::WasInformedBy => WAS_INFORMED_BY, + ChronicleOperations::InformingActivityName => INFORMING_ACTIVITY_NAME, + ChronicleOperations::Generated => GENERATED, + ChronicleOperations::CreateNamespace => CREATE_NAMESPACE, + ChronicleOperations::NamespaceName => NAMESPACE_NAME, + ChronicleOperations::NamespaceUuid => NAMESPACE_UUID, + ChronicleOperations::AgentExists => AGENT_EXISTS, + ChronicleOperations::AgentName => AGENT_NAME, + ChronicleOperations::AgentUuid => AGENT_UUID, + ChronicleOperations::AgentActsOnBehalfOf => AGENT_ACTS_ON_BEHALF_OF, + ChronicleOperations::DelegateId => DELEGATE_ID, + ChronicleOperations::ResponsibleId => RESPONSIBLE_ID, } } } #[cfg(feature = "json-ld")] - impl Into for ChronicleOperations { - fn into(self) -> IriAbsoluteString { - UriAbsoluteString::try_from(self.as_str().to_string()) - .unwrap() - .try_into() - .unwrap() + impl From for iri_string::types::IriString { + fn from(val: ChronicleOperations) -> Self { + use iri_string::types::UriString; + UriString::try_from(val.as_str().to_string()).unwrap().into() } } @@ -141,9 +138,6 @@ mod chronicle_operations { pub use chronicle_operations::ChronicleOperations; mod prov { - use iri_string::types::{IriAbsoluteString, UriAbsoluteString}; - - use crate::prov::FromCompact; #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub enum Prov { @@ -207,44 +201,42 @@ mod prov { impl AsRef for Prov { fn as_ref(&self) -> &'static str { match self { - Prov::Agent => &AGENT, - Prov::Entity => &ENTITY, - Prov::Activity => &ACTIVITY, - Prov::WasAssociatedWith => &WAS_ASSOCIATED_WITH, - Prov::QualifiedAssociation => &QUALIFIED_ASSOCIATION, - Prov::QualifiedAttribution => &QUALIFIED_ATTRIBUTION, - Prov::Association => &ASSOCIATION, - Prov::Attribution => &ATTRIBUTION, - Prov::Responsible => &RESPONSIBLE, - Prov::WasGeneratedBy => &WAS_GENERATED_BY, - Prov::Used => &USED, - Prov::WasAttributedTo => &WAS_ATTRIBUTED_TO, - Prov::StartedAtTime => &STARTED_AT_TIME, - Prov::EndedAtTime => &ENDED_AT_TIME, - Prov::WasDerivedFrom => &WAS_DERIVED_FROM, - Prov::HadPrimarySource => &HAD_PRIMARY_SOURCE, - Prov::WasQuotedFrom => &WAS_QUOTED_FROM, - Prov::WasRevisionOf => &WAS_REVISION_OF, - Prov::ActedOnBehalfOf => &ACTED_ON_BEHALF_OF, - Prov::QualifiedDelegation => &QUALIFIED_DELEGATION, - Prov::Delegation => &DELEGATION, - Prov::Delegate => &DELEGATE, - Prov::HadRole => &HAD_ROLE, - Prov::HadActivity => &HAD_ACTIVITY, - Prov::HadEntity => &HAD_ENTITY, - Prov::WasInformedBy => &WAS_INFORMED_BY, - Prov::Generated => &GENERATED, + Prov::Agent => AGENT, + Prov::Entity => ENTITY, + Prov::Activity => ACTIVITY, + Prov::WasAssociatedWith => WAS_ASSOCIATED_WITH, + Prov::QualifiedAssociation => QUALIFIED_ASSOCIATION, + Prov::QualifiedAttribution => QUALIFIED_ATTRIBUTION, + Prov::Association => ASSOCIATION, + Prov::Attribution => ATTRIBUTION, + Prov::Responsible => RESPONSIBLE, + Prov::WasGeneratedBy => WAS_GENERATED_BY, + Prov::Used => USED, + Prov::WasAttributedTo => WAS_ATTRIBUTED_TO, + Prov::StartedAtTime => STARTED_AT_TIME, + Prov::EndedAtTime => ENDED_AT_TIME, + Prov::WasDerivedFrom => WAS_DERIVED_FROM, + Prov::HadPrimarySource => HAD_PRIMARY_SOURCE, + Prov::WasQuotedFrom => WAS_QUOTED_FROM, + Prov::WasRevisionOf => WAS_REVISION_OF, + Prov::ActedOnBehalfOf => ACTED_ON_BEHALF_OF, + Prov::QualifiedDelegation => QUALIFIED_DELEGATION, + Prov::Delegation => DELEGATION, + Prov::Delegate => DELEGATE, + Prov::HadRole => HAD_ROLE, + Prov::HadActivity => HAD_ACTIVITY, + Prov::HadEntity => HAD_ENTITY, + Prov::WasInformedBy => WAS_INFORMED_BY, + Prov::Generated => GENERATED, } } } #[cfg(feature = "json-ld")] - impl Into for Prov { - fn into(self) -> IriAbsoluteString { - UriAbsoluteString::try_from(self.as_str().to_string()) - .unwrap() - .try_into() - .unwrap() + impl From for iri_string::types::IriString { + fn from(val: Prov) -> Self { + use iri_string::types::UriString; + UriString::try_from(val.as_str().to_string()).unwrap().into() } } @@ -264,7 +256,7 @@ mod prov { pub use prov::Prov; mod chronicle { - use iri_string::types::{IriAbsoluteString, UriAbsoluteString}; + use iri_string::types::UriString; #[cfg(not(feature = "std"))] use parity_scale_codec::alloc::string::String; #[cfg(not(feature = "std"))] @@ -280,27 +272,24 @@ mod chronicle { Value, } - const NAMESPACE: &str = "chronicle:namespace"; - const HAS_NAMESPACE: &str = "chronicle:hasNamespace"; - const VALUE: &str = "chronicle:value"; + const NAMESPACE: &str = "http://btp.works/chronicle/ns#Namespace"; + const HAS_NAMESPACE: &str = "http://btp.works/chronicle/ns#hasNamespace"; + const VALUE: &str = "http://btp.works/chronicle/ns#Value"; impl AsRef for Chronicle { fn as_ref(&self) -> &'static str { match self { - Chronicle::Namespace => &NAMESPACE, - Chronicle::HasNamespace => &HAS_NAMESPACE, - Chronicle::Value => &VALUE, + Chronicle::Namespace => NAMESPACE, + Chronicle::HasNamespace => HAS_NAMESPACE, + Chronicle::Value => VALUE, } } } #[cfg(feature = "json-ld")] - impl Into for Chronicle { - fn into(self) -> IriAbsoluteString { - UriAbsoluteString::try_from(self.as_str().to_string()) - .unwrap() - .try_into() - .unwrap() + impl From for iri_string::types::IriString { + fn from(val: Chronicle) -> Self { + UriString::try_from(val.as_str().to_string()).unwrap().into() } } @@ -316,30 +305,31 @@ mod chronicle { } } - /// Operations to format specific Iri kinds, using percentage encoding to ensure they are infallible + /// Operations to format specific Iri kinds, using percentage encoding to ensure they are + /// infallible impl Chronicle { pub const LONG_PREFIX: &'static str = "http://btp.works/chronicle/ns#"; pub const PREFIX: &'static str = "chronicle:"; - pub fn namespace(external_id: &ExternalId, id: &Uuid) -> UriAbsoluteString { + pub fn namespace(external_id: &ExternalId, id: &Uuid) -> UriString { format!("{}ns:{}:{}", Self::PREFIX, external_id.as_str(), id) .try_into() .unwrap() } - pub fn agent(external_id: &ExternalId) -> UriAbsoluteString { + pub fn agent(external_id: &ExternalId) -> UriString { format!("{}agent:{}", Self::PREFIX, external_id.as_str()).try_into().unwrap() } - pub fn activity(external_id: &ExternalId) -> UriAbsoluteString { + pub fn activity(external_id: &ExternalId) -> UriString { format!("{}activity:{}", Self::PREFIX, external_id.as_str()).try_into().unwrap() } - pub fn entity(external_id: &ExternalId) -> UriAbsoluteString { + pub fn entity(external_id: &ExternalId) -> UriString { format!("{}entity:{}", Self::PREFIX, external_id.as_str()).try_into().unwrap() } - pub fn domaintype(external_id: &ExternalId) -> UriAbsoluteString { + pub fn domaintype(external_id: &ExternalId) -> UriString { format!("{}domaintype:{}", Self::PREFIX, external_id.as_str()) .try_into() .unwrap() @@ -349,7 +339,7 @@ mod chronicle { agent: &AgentId, activity: &ActivityId, role: &Option, - ) -> UriAbsoluteString { + ) -> UriString { format!( "{}association:{}:{}:role={}", Self::PREFIX, @@ -366,7 +356,7 @@ mod chronicle { responsible: &AgentId, activity: &Option, role: &Option, - ) -> UriAbsoluteString { + ) -> UriString { format!( "{}delegation:{}:{}:role={}:activity={}", Self::PREFIX, @@ -379,11 +369,7 @@ mod chronicle { .unwrap() } - pub fn attribution( - agent: &AgentId, - entity: &EntityId, - role: &Option, - ) -> UriAbsoluteString { + pub fn attribution(agent: &AgentId, entity: &EntityId, role: &Option) -> UriString { format!( "{}attribution:{}:{}:role={}", Self::PREFIX, @@ -401,6 +387,7 @@ pub use chronicle::*; /// As these operations are meant to be infallible, prop test them to ensure #[cfg(test)] +#[cfg(std)] #[allow(clippy::useless_conversion)] mod test { use crate::prov::{ActivityId, AgentId, EntityId, ExternalId, NamespaceId}; diff --git a/crates/common/tree.txt b/crates/common/tree.txt new file mode 100644 index 000000000..0f048f06f --- /dev/null +++ b/crates/common/tree.txt @@ -0,0 +1,465 @@ +common v0.7.5 (/Users/ryan/code/chronicle/crates/common) +├── anyhow v1.0.75 +├── async-trait v0.1.74 (proc-macro) +│ ├── proc-macro2 v1.0.69 +│ │ └── unicode-ident v1.0.12 +│ ├── quote v1.0.33 +│ │ └── proc-macro2 v1.0.69 (*) +│ └── syn v2.0.38 +│ ├── proc-macro2 v1.0.69 (*) +│ ├── quote v1.0.33 (*) +│ └── unicode-ident v1.0.12 +├── chrono v0.4.31 +│ ├── iana-time-zone v0.1.58 +│ │ └── core-foundation-sys v0.8.4 +│ ├── num-traits v0.2.17 +│ │ └── libm v0.2.8 +│ │ [build-dependencies] +│ │ └── autocfg v1.1.0 +│ └── serde v1.0.190 +│ └── serde_derive v1.0.190 (proc-macro) +│ ├── proc-macro2 v1.0.69 (*) +│ ├── quote v1.0.33 (*) +│ └── syn v2.0.38 (*) +├── futures v0.3.29 +│ ├── futures-channel v0.3.29 +│ │ ├── futures-core v0.3.29 +│ │ └── futures-sink v0.3.29 +│ ├── futures-core v0.3.29 +│ ├── futures-executor v0.3.29 +│ │ ├── futures-core v0.3.29 +│ │ ├── futures-task v0.3.29 +│ │ └── futures-util v0.3.29 +│ │ ├── futures-channel v0.3.29 (*) +│ │ ├── futures-core v0.3.29 +│ │ ├── futures-io v0.3.29 +│ │ ├── futures-macro v0.3.29 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── futures-sink v0.3.29 +│ │ ├── futures-task v0.3.29 +│ │ ├── memchr v2.6.4 +│ │ ├── pin-project-lite v0.2.13 +│ │ ├── pin-utils v0.1.0 +│ │ └── slab v0.4.9 +│ │ [build-dependencies] +│ │ └── autocfg v1.1.0 +│ ├── futures-io v0.3.29 +│ ├── futures-sink v0.3.29 +│ ├── futures-task v0.3.29 +│ └── futures-util v0.3.29 (*) +├── glob v0.3.1 +├── hex v0.4.3 +├── iref v2.2.3 +│ ├── pct-str v1.2.0 +│ │ └── utf8-decode v1.0.1 +│ └── smallvec v1.11.1 +├── iref-enum v2.1.0 (proc-macro) +│ ├── iref v2.2.3 (*) +│ ├── proc-macro2 v1.0.69 (*) +│ ├── quote v1.0.33 (*) +│ └── syn v1.0.109 +│ ├── proc-macro2 v1.0.69 (*) +│ ├── quote v1.0.33 (*) +│ └── unicode-ident v1.0.12 +├── k256 v0.11.6 +│ ├── cfg-if v1.0.0 +│ ├── ecdsa v0.14.8 +│ │ ├── der v0.6.1 +│ │ │ ├── const-oid v0.9.5 +│ │ │ ├── pem-rfc7468 v0.6.0 +│ │ │ │ └── base64ct v1.6.0 +│ │ │ └── zeroize v1.6.0 +│ │ ├── elliptic-curve v0.12.3 +│ │ │ ├── base16ct v0.1.1 +│ │ │ ├── crypto-bigint v0.4.9 +│ │ │ │ ├── generic-array v0.14.7 +│ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ └── getrandom v0.2.10 +│ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ └── libc v0.2.149 +│ │ │ │ ├── subtle v2.4.1 +│ │ │ │ └── zeroize v1.6.0 +│ │ │ ├── der v0.6.1 (*) +│ │ │ ├── digest v0.10.7 +│ │ │ │ ├── block-buffer v0.10.4 +│ │ │ │ │ └── generic-array v0.14.7 (*) +│ │ │ │ ├── crypto-common v0.1.6 +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ └── subtle v2.4.1 +│ │ │ ├── ff v0.12.1 +│ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ └── subtle v2.4.1 +│ │ │ ├── generic-array v0.14.7 (*) +│ │ │ ├── group v0.12.1 +│ │ │ │ ├── ff v0.12.1 (*) +│ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ └── subtle v2.4.1 +│ │ │ ├── pem-rfc7468 v0.6.0 (*) +│ │ │ ├── pkcs8 v0.9.0 +│ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ └── spki v0.6.0 +│ │ │ │ ├── base64ct v1.6.0 +│ │ │ │ └── der v0.6.1 (*) +│ │ │ ├── rand_core v0.6.4 (*) +│ │ │ ├── sec1 v0.3.0 +│ │ │ │ ├── base16ct v0.1.1 +│ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ ├── pkcs8 v0.9.0 (*) +│ │ │ │ ├── serdect v0.1.0 +│ │ │ │ │ ├── base16ct v0.1.1 +│ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ ├── subtle v2.4.1 +│ │ │ │ └── zeroize v1.6.0 +│ │ │ ├── serdect v0.1.0 (*) +│ │ │ ├── subtle v2.4.1 +│ │ │ └── zeroize v1.6.0 +│ │ ├── rfc6979 v0.3.1 +│ │ │ ├── crypto-bigint v0.4.9 (*) +│ │ │ ├── hmac v0.12.1 +│ │ │ │ └── digest v0.10.7 (*) +│ │ │ └── zeroize v1.6.0 +│ │ ├── serdect v0.1.0 (*) +│ │ └── signature v1.6.4 +│ │ ├── digest v0.10.7 (*) +│ │ └── rand_core v0.6.4 (*) +│ ├── elliptic-curve v0.12.3 (*) +│ ├── serdect v0.1.0 (*) +│ └── sha2 v0.10.8 +│ ├── cfg-if v1.0.0 +│ ├── cpufeatures v0.2.11 +│ │ └── libc v0.2.149 +│ └── digest v0.10.7 (*) +├── lazy_static v1.4.0 +├── locspan v0.7.16 +├── macro-attr-2018 v3.0.0 +├── mime v0.3.17 +├── newtype-derive-2018 v0.2.1 +│ └── generics v0.5.0 +├── parity-scale-codec v3.6.5 +│ ├── arrayvec v0.7.4 +│ ├── byte-slice-cast v1.2.2 +│ ├── impl-trait-for-tuples v0.2.2 (proc-macro) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 (*) +│ ├── parity-scale-codec-derive v3.6.5 (proc-macro) +│ │ ├── proc-macro-crate v1.1.3 +│ │ │ ├── thiserror v1.0.50 +│ │ │ │ └── thiserror-impl v1.0.50 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ └── toml v0.5.11 +│ │ │ └── serde v1.0.190 (*) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 (*) +│ └── serde v1.0.190 (*) +├── percent-encoding v2.3.0 +├── scale-info v2.10.0 +│ ├── cfg-if v1.0.0 +│ ├── derive_more v0.99.17 (proc-macro) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 (*) +│ ├── parity-scale-codec v3.6.5 (*) +│ └── scale-info-derive v2.10.0 (proc-macro) +│ ├── proc-macro-crate v1.1.3 (*) +│ ├── proc-macro2 v1.0.69 (*) +│ ├── quote v1.0.33 (*) +│ └── syn v1.0.109 (*) +├── serde v1.0.190 (*) +├── serde_derive v1.0.190 (proc-macro) (*) +├── serde_json v1.0.107 +│ ├── itoa v1.0.9 +│ ├── ryu v1.0.15 +│ └── serde v1.0.190 (*) +├── static-iref v2.0.0 (proc-macro) +│ └── iref v2.2.3 (*) +├── thiserror v1.0.50 (*) +├── thiserror-no-std v2.0.2 +│ └── thiserror-impl-no-std v2.0.2 (proc-macro) +│ ├── proc-macro2 v1.0.69 (*) +│ ├── quote v1.0.33 (*) +│ └── syn v1.0.109 (*) +├── tracing v0.1.40 +│ ├── pin-project-lite v0.2.13 +│ ├── tracing-attributes v0.1.27 (proc-macro) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v2.0.38 (*) +│ └── tracing-core v0.1.32 +│ └── once_cell v1.18.0 +├── url v2.4.1 +│ ├── form_urlencoded v1.2.0 +│ │ └── percent-encoding v2.3.0 +│ ├── idna v0.4.0 +│ │ ├── unicode-bidi v0.3.13 +│ │ └── unicode-normalization v0.1.22 +│ │ └── tinyvec v1.6.0 +│ │ └── tinyvec_macros v0.1.1 +│ └── percent-encoding v2.3.0 +└── uuid v1.5.0 + └── serde v1.0.190 (*) +[build-dependencies] +├── glob v0.3.1 +├── lazy_static v1.4.0 +└── serde_json v1.0.107 (*) +[dev-dependencies] +├── criterion v0.5.1 +│ ├── anes v0.1.6 +│ ├── cast v0.3.0 +│ ├── ciborium v0.2.1 +│ │ ├── ciborium-io v0.2.1 +│ │ ├── ciborium-ll v0.2.1 +│ │ │ ├── ciborium-io v0.2.1 +│ │ │ └── half v1.8.2 +│ │ └── serde v1.0.190 (*) +│ ├── clap v4.4.7 +│ │ └── clap_builder v4.4.7 +│ │ ├── anstyle v1.0.4 +│ │ └── clap_lex v0.6.0 +│ ├── criterion-plot v0.5.0 +│ │ ├── cast v0.3.0 +│ │ └── itertools v0.10.5 +│ │ └── either v1.9.0 +│ ├── futures v0.3.29 (*) +│ ├── is-terminal v0.4.9 +│ │ └── rustix v0.38.21 +│ │ ├── bitflags v2.4.1 +│ │ ├── errno v0.3.5 +│ │ │ └── libc v0.2.149 +│ │ └── libc v0.2.149 +│ ├── itertools v0.10.5 (*) +│ ├── num-traits v0.2.17 (*) +│ ├── once_cell v1.18.0 +│ ├── oorandom v11.1.3 +│ ├── plotters v0.3.5 +│ │ ├── num-traits v0.2.17 (*) +│ │ ├── plotters-backend v0.3.5 +│ │ └── plotters-svg v0.3.5 +│ │ └── plotters-backend v0.3.5 +│ ├── rayon v1.8.0 +│ │ ├── either v1.9.0 +│ │ └── rayon-core v1.12.0 +│ │ ├── crossbeam-deque v0.8.3 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── crossbeam-epoch v0.9.15 +│ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ ├── crossbeam-utils v0.8.16 +│ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ ├── memoffset v0.9.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── autocfg v1.1.0 +│ │ │ │ └── scopeguard v1.2.0 +│ │ │ │ [build-dependencies] +│ │ │ │ └── autocfg v1.1.0 +│ │ │ └── crossbeam-utils v0.8.16 (*) +│ │ └── crossbeam-utils v0.8.16 (*) +│ ├── regex v1.10.2 +│ │ ├── aho-corasick v1.1.2 +│ │ │ └── memchr v2.6.4 +│ │ ├── memchr v2.6.4 +│ │ ├── regex-automata v0.4.3 +│ │ │ ├── aho-corasick v1.1.2 (*) +│ │ │ ├── memchr v2.6.4 +│ │ │ └── regex-syntax v0.8.2 +│ │ └── regex-syntax v0.8.2 +│ ├── serde v1.0.190 (*) +│ ├── serde_derive v1.0.190 (proc-macro) (*) +│ ├── serde_json v1.0.107 (*) +│ ├── tinytemplate v1.2.1 +│ │ ├── serde v1.0.190 (*) +│ │ └── serde_json v1.0.107 (*) +│ ├── tokio v1.33.0 +│ │ ├── bytes v1.5.0 +│ │ ├── libc v0.2.149 +│ │ ├── mio v0.8.9 +│ │ │ └── libc v0.2.149 +│ │ ├── num_cpus v1.16.0 +│ │ │ └── libc v0.2.149 +│ │ ├── parking_lot v0.12.1 +│ │ │ ├── lock_api v0.4.11 +│ │ │ │ └── scopeguard v1.2.0 +│ │ │ │ [build-dependencies] +│ │ │ │ └── autocfg v1.1.0 +│ │ │ └── parking_lot_core v0.9.9 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── libc v0.2.149 +│ │ │ └── smallvec v1.11.1 +│ │ ├── pin-project-lite v0.2.13 +│ │ ├── signal-hook-registry v1.4.1 +│ │ │ └── libc v0.2.149 +│ │ ├── socket2 v0.5.5 +│ │ │ └── libc v0.2.149 +│ │ └── tokio-macros v2.1.0 (proc-macro) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v2.0.38 (*) +│ └── walkdir v2.4.0 +│ └── same-file v1.0.6 +├── insta v1.34.0 +│ ├── console v0.15.7 +│ │ ├── lazy_static v1.4.0 +│ │ └── libc v0.2.149 +│ ├── lazy_static v1.4.0 +│ ├── linked-hash-map v0.5.6 +│ ├── pest v2.7.5 +│ │ ├── memchr v2.6.4 +│ │ ├── thiserror v1.0.50 (*) +│ │ └── ucd-trie v0.1.6 +│ ├── pest_derive v2.7.5 (proc-macro) +│ │ ├── pest v2.7.5 (*) +│ │ └── pest_generator v2.7.5 +│ │ ├── pest v2.7.5 (*) +│ │ ├── pest_meta v2.7.5 +│ │ │ ├── once_cell v1.18.0 +│ │ │ └── pest v2.7.5 (*) +│ │ │ [build-dependencies] +│ │ │ └── sha2 v0.10.8 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── cpufeatures v0.2.11 (*) +│ │ │ └── digest v0.10.7 +│ │ │ ├── block-buffer v0.10.4 (*) +│ │ │ └── crypto-common v0.1.6 +│ │ │ ├── generic-array v0.14.7 (*) +│ │ │ └── typenum v1.17.0 +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v2.0.38 (*) +│ ├── serde v1.0.190 (*) +│ ├── similar v2.3.0 +│ ├── toml v0.5.11 (*) +│ └── yaml-rust v0.4.5 +│ └── linked-hash-map v0.5.6 +├── mockito v1.2.0 +│ ├── assert-json-diff v2.0.2 +│ │ ├── serde v1.0.190 (*) +│ │ └── serde_json v1.0.107 (*) +│ ├── colored v2.0.4 +│ │ ├── is-terminal v0.4.9 (*) +│ │ └── lazy_static v1.4.0 +│ ├── futures v0.3.29 (*) +│ ├── hyper v0.14.27 +│ │ ├── bytes v1.5.0 +│ │ ├── futures-channel v0.3.29 (*) +│ │ ├── futures-core v0.3.29 +│ │ ├── futures-util v0.3.29 (*) +│ │ ├── h2 v0.3.21 +│ │ │ ├── bytes v1.5.0 +│ │ │ ├── fnv v1.0.7 +│ │ │ ├── futures-core v0.3.29 +│ │ │ ├── futures-sink v0.3.29 +│ │ │ ├── futures-util v0.3.29 (*) +│ │ │ ├── http v0.2.9 +│ │ │ │ ├── bytes v1.5.0 +│ │ │ │ ├── fnv v1.0.7 +│ │ │ │ └── itoa v1.0.9 +│ │ │ ├── indexmap v1.9.3 +│ │ │ │ └── hashbrown v0.12.3 +│ │ │ │ [build-dependencies] +│ │ │ │ └── autocfg v1.1.0 +│ │ │ ├── slab v0.4.9 (*) +│ │ │ ├── tokio v1.33.0 (*) +│ │ │ ├── tokio-util v0.7.10 +│ │ │ │ ├── bytes v1.5.0 +│ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ ├── futures-sink v0.3.29 +│ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ ├── tokio v1.33.0 (*) +│ │ │ │ └── tracing v0.1.40 (*) +│ │ │ └── tracing v0.1.40 (*) +│ │ ├── http v0.2.9 (*) +│ │ ├── http-body v0.4.5 +│ │ │ ├── bytes v1.5.0 +│ │ │ ├── http v0.2.9 (*) +│ │ │ └── pin-project-lite v0.2.13 +│ │ ├── httparse v1.8.0 +│ │ ├── httpdate v1.0.3 +│ │ ├── itoa v1.0.9 +│ │ ├── pin-project-lite v0.2.13 +│ │ ├── socket2 v0.4.10 +│ │ │ └── libc v0.2.149 +│ │ ├── tokio v1.33.0 (*) +│ │ ├── tower-service v0.3.2 +│ │ ├── tracing v0.1.40 (*) +│ │ └── want v0.3.1 +│ │ └── try-lock v0.2.4 +│ ├── log v0.4.20 +│ ├── rand v0.8.5 +│ │ ├── libc v0.2.149 +│ │ ├── rand_chacha v0.3.1 +│ │ │ ├── ppv-lite86 v0.2.17 +│ │ │ └── rand_core v0.6.4 (*) +│ │ └── rand_core v0.6.4 (*) +│ ├── regex v1.10.2 (*) +│ ├── serde_json v1.0.107 (*) +│ ├── serde_urlencoded v0.7.1 +│ │ ├── form_urlencoded v1.2.0 (*) +│ │ ├── itoa v1.0.9 +│ │ ├── ryu v1.0.15 +│ │ └── serde v1.0.190 (*) +│ ├── similar v2.3.0 +│ └── tokio v1.33.0 (*) +├── proptest v1.3.1 +│ ├── bit-set v0.5.3 +│ │ └── bit-vec v0.6.3 +│ ├── bit-vec v0.6.3 +│ ├── bitflags v2.4.1 +│ ├── lazy_static v1.4.0 +│ ├── num-traits v0.2.17 (*) +│ ├── rand v0.8.5 (*) +│ ├── rand_chacha v0.3.1 (*) +│ ├── rand_xorshift v0.3.0 +│ │ └── rand_core v0.6.4 (*) +│ ├── regex-syntax v0.7.5 +│ ├── rusty-fork v0.3.0 +│ │ ├── fnv v1.0.7 +│ │ ├── quick-error v1.2.3 +│ │ ├── tempfile v3.8.1 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── fastrand v2.0.1 +│ │ │ └── rustix v0.38.21 (*) +│ │ └── wait-timeout v0.2.0 +│ │ └── libc v0.2.149 +│ ├── tempfile v3.8.1 (*) +│ └── unarray v0.1.4 +├── tempfile v3.8.1 (*) +├── testcontainers v0.14.0 +│ ├── bollard-stubs v1.41.0 +│ │ ├── chrono v0.4.31 (*) +│ │ ├── serde v1.0.190 (*) +│ │ └── serde_with v1.14.0 +│ │ ├── serde v1.0.190 (*) +│ │ └── serde_with_macros v1.5.2 (proc-macro) +│ │ ├── darling v0.13.4 +│ │ │ ├── darling_core v0.13.4 +│ │ │ │ ├── fnv v1.0.7 +│ │ │ │ ├── ident_case v1.0.1 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ ├── strsim v0.10.0 +│ │ │ │ └── syn v1.0.109 (*) +│ │ │ └── darling_macro v0.13.4 (proc-macro) +│ │ │ ├── darling_core v0.13.4 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 (*) +│ ├── futures v0.3.29 (*) +│ ├── hex v0.4.3 +│ ├── hmac v0.12.1 (*) +│ ├── log v0.4.20 +│ ├── rand v0.8.5 (*) +│ ├── serde v1.0.190 (*) +│ ├── serde_json v1.0.107 (*) +│ └── sha2 v0.10.8 (*) +└── tokio v1.33.0 (*) diff --git a/crates/embedded-substrate/Cargo.toml b/crates/embedded-substrate/Cargo.toml new file mode 100644 index 000000000..ea9362a8e --- /dev/null +++ b/crates/embedded-substrate/Cargo.toml @@ -0,0 +1,23 @@ +[package] +edition = "2021" +name = "embedded-substrate" +version = "0.1.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +lazy_static = { workspace = true } +node-chronicle = { path = "../../node/node-chronicle" } +portpicker = { workspace = true } +protocol-abstract = { path = "../protocol-abstract" } +protocol-substrate = { path = "../protocol-substrate" } +protocol-substrate-chronicle = { path = "../protocol-substrate-chronicle" } +sc-cli = { version = "0.33.0" } +sp-io = { version = "27.0.0" } +sp-runtime = { version = "28.0.0" } +subxt = { version = "0.32", features = ["substrate-compat"] } +tempfile = { version = "3" } +thiserror = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } diff --git a/crates/embedded-substrate/src/lib.rs b/crates/embedded-substrate/src/lib.rs new file mode 100644 index 000000000..39ec267d5 --- /dev/null +++ b/crates/embedded-substrate/src/lib.rs @@ -0,0 +1,221 @@ +use node_chronicle::{cli::Cli, service}; +use protocol_substrate::SubxtClientError; +use protocol_substrate_chronicle::ChronicleSubstrateClient; +use sc_cli::{print_node_infos, CliConfiguration, Signals, SubstrateCli}; +use subxt::{ + config::ExtrinsicParams, + ext::futures::{pin_mut, FutureExt}, + utils::{AccountId32, MultiAddress, MultiSignature}, +}; +use tempfile::TempDir; +use thiserror::Error; +use tokio::{ + select, + sync::oneshot::{channel, Sender}, +}; + +use lazy_static::lazy_static; +use std::{ + collections::BTreeMap, + sync::{Arc, Mutex}, + time::Duration, +}; +use tracing::info; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Substrate invocation error: {source}")] + Cli { source: anyhow::Error }, + #[error("No free ports")] + NoFreePorts, +} + +// Substrate initialization is costly and includes log configuration, so we need to keep and reuse +// instances in most circumnstances +lazy_static! { + static ref SUBSTRATE_INSTANCES: Mutex>> = + Mutex::new(BTreeMap::new()); +} + +pub struct EmbeddedSubstrate { + shutdown: Option>, + _state: TempDir, + rpc_port: u16, +} + +impl EmbeddedSubstrate { + pub async fn connect_chronicle( + &self, + ) -> Result, SubxtClientError> + where + C: subxt::Config< + Hash = subxt::utils::H256, + Address = MultiAddress, + AccountId = AccountId32, + Signature = MultiSignature, + >, + >::OtherParams: Default, + { + ChronicleSubstrateClient::::connect(format!("ws://127.0.0.1:{}", self.rpc_port)).await + } + + pub fn port(&self) -> u16 { + self.rpc_port + } +} + +impl Drop for EmbeddedSubstrate { + fn drop(&mut self) { + if let Some(shutdown) = self.shutdown.take() { + if let Err(e) = shutdown.send(()) { + tracing::error!("Failed to send shutdown signal: {:?}", e); + } + } else { + tracing::warn!("Shutdown signal was already taken"); + } + } +} + +pub async fn shared_dev_node_rpc_on_arbitrary_port() -> Result, Error> { + shared_dev_node_rpc_on_port( + portpicker::pick_unused_port().ok_or_else(|| Error::NoFreePorts)?, + false, + ) + .await +} +// Utilize the CLI run command to bring up a substrate-chronicle dev mode node with a new runtime +// Utilize the CLI run command to bring up a substrate-chronicle dev mode node with a new runtime +// thread. Execute node until receipt of a drop channel message or signal +pub async fn shared_dev_node_rpc_on_port( + port: u16, + configure_logging: bool, +) -> Result, Error> { + let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap(); + let handle = rt.handle().clone(); + + if let Some(substrate_instance) = SUBSTRATE_INSTANCES.lock().unwrap().get(&port) { + return Ok(substrate_instance.clone()); + } + + let (live_tx, live_rx) = channel::<()>(); + let (tx, rx) = channel(); + let tmp_dir = tempfile::tempdir().unwrap(); + let tmp_path = format!("{}", tmp_dir.path().to_string_lossy()); + + std::thread::spawn(move || { + let cli = Cli::from_iter([ + "--chain dev", + "--force-authoring", + "--alice", + &*format!("--rpc-port={}", port), + "--rpc-cors=all", + &*format!("-d{}", tmp_path), + ]); + + let signals = handle + .block_on(async { Signals::capture() }) + .map_err(|e| tracing::error!("{}", e)) + .unwrap(); + + let config = cli + .create_configuration(&cli.run, handle.clone()) + .map_err(|e| tracing::error!("{}", e)) + .unwrap(); + + print_node_infos::(&config); + + if configure_logging { + cli.run + .init( + &"https://chronicle.works".to_owned(), + &"2.0.dev".to_owned(), + |_, _| {}, + &config, + ) + .unwrap(); + } + + let mut task_manager = handle + .block_on(async move { service::new_full(config).map_err(sc_cli::Error::Service) }) + .map_err(|e| tracing::error!("{}", e)) + .unwrap(); + + live_tx.send(()).unwrap(); + + let task_manager = handle.block_on(async move { + let signal_exit = signals.future().fuse(); + let task_exit = task_manager.future().fuse(); + let drop_exit = async move { + let _ = rx.await; + tracing::info!("Shutdown message"); + }; + + pin_mut!(signal_exit, drop_exit); + + select! { + _ = signal_exit => {}, + _ = drop_exit => {}, + _ = task_exit => {}, + } + + task_manager + }); + + let task_registry = task_manager.into_task_registry(); + let shutdown_timeout = Duration::from_secs(60); + rt.shutdown_timeout(shutdown_timeout); + + let running_tasks = task_registry.running_tasks(); + + if !running_tasks.is_empty() { + tracing::error!("Detected running(potentially stalled) tasks on shutdown:"); + running_tasks.iter().for_each(|(task, count)| { + let instances_desc = + if *count > 1 { format!("with {} instances ", count) } else { "".to_string() }; + + if task.is_default_group() { + tracing::error!( + "Task \"{}\" was still running {}after waiting {} seconds to finish.", + task.name, + instances_desc, + 60 + ); + } else { + tracing::error!( + "Task \"{}\" (Group: {}) was still running {}after waiting {} seconds to finish.", + task.name, + task.group, + instances_desc, + 60 + ); + } + }); + } + + info!("Shut down embedded substrate instance on port {}", port); + }); + + tracing::info!("Await substrate boot"); + let _ = live_rx.await; + tracing::info!("Substrate booted"); + + let instance = + Arc::new(EmbeddedSubstrate { shutdown: tx.into(), rpc_port: port, _state: tmp_dir }); + + SUBSTRATE_INSTANCES.lock().unwrap().insert(port, instance.clone()); + + Ok(instance) +} + +pub fn remove_shared_substrate_by_port(port: u16) { + let mut instances = SUBSTRATE_INSTANCES.lock().unwrap(); + if let Some(_instance) = instances.get(&port) { + instances.remove(&port); + } else { + tracing::warn!("No running substrate instance found on port {}", port); + } +} + +pub fn remove_shared_substrate(substrate: &EmbeddedSubstrate) { + remove_shared_substrate_by_port(substrate.port()) +} diff --git a/crates/opa-tp-protocol/build.rs b/crates/opa-tp-protocol/build.rs deleted file mode 100644 index 1a99e734b..000000000 --- a/crates/opa-tp-protocol/build.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::{env, fs, io::Result, path::PathBuf}; - -fn main() -> Result<()> { - let protos = glob::glob("./src/protos/*.proto") - .unwrap() - .map(|x| x.unwrap()) - .collect::>(); - prost_build::compile_protos(&protos, &["./src/protos"])?; - - let out_str = env::var("OUT_DIR").unwrap(); - let out_path = PathBuf::from(&out_str); - let mut out_path = out_path.ancestors().nth(3).unwrap().to_owned(); - out_path.push("assets"); - - if !out_path.exists() { - fs::create_dir(&out_path).expect("Could not create assets dir"); - } - - Ok(()) -} diff --git a/crates/opa-tp-protocol/src/address.rs b/crates/opa-tp-protocol/src/address.rs deleted file mode 100644 index 0cd9134b3..000000000 --- a/crates/opa-tp-protocol/src/address.rs +++ /dev/null @@ -1,24 +0,0 @@ -use hex; -use lazy_static::lazy_static; -use openssl::sha::Sha256; - -lazy_static! { - pub static ref PREFIX: String = { - let mut sha = Sha256::new(); - sha.update("opa-tp".as_bytes()); - hex::encode(sha.finish())[..6].to_string() - }; -} - -pub static VERSION: &str = "1.0"; -pub static FAMILY: &str = "opa-tp"; - -pub fn hash_and_append(addr: impl AsRef) -> String { - let mut sha = Sha256::new(); - sha.update(addr.as_ref().as_bytes()); - format!("{}{}", &*PREFIX, hex::encode(sha.finish())) -} - -pub trait HasSawtoothAddress { - fn get_address(&self) -> String; -} diff --git a/crates/opa-tp-protocol/src/events.rs b/crates/opa-tp-protocol/src/events.rs deleted file mode 100644 index ec7787772..000000000 --- a/crates/opa-tp-protocol/src/events.rs +++ /dev/null @@ -1,50 +0,0 @@ -use async_stl_client::{ - error::SawtoothCommunicationError, - ledger::{LedgerEvent, Span}, -}; -use prost::Message; -use serde_json::json; - -use crate::{ - messages::{self, OpaEvent}, - state::OpaOperationEvent, -}; - -#[async_trait::async_trait] -impl LedgerEvent for OpaOperationEvent { - async fn deserialize(buf: &[u8]) -> Result<(Self, Span), SawtoothCommunicationError> - where - Self: Sized, - { - let ev = OpaEvent::decode(buf)?; - if let Some(payload) = ev.payload { - match payload { - messages::opa_event::Payload::Operation(value) => { - let value = serde_json::from_str(&value)?; - Ok((value, Span::Span(ev.span_id))) - }, - messages::opa_event::Payload::Error(value) => - Ok((OpaOperationEvent::Error(value), Span::Span(ev.span_id))), - } - } else { - Err(SawtoothCommunicationError::MalformedMessage) - } - } -} - -pub fn opa_event(span_id: u64, value: OpaOperationEvent) -> Result, serde_json::Error> { - Ok(OpaEvent { - version: crate::PROTOCOL_VERSION.to_string(), - span_id, - payload: { - match value { - OpaOperationEvent::Error(e) => Some(messages::opa_event::Payload::Error( - serde_json::to_string(&json!({ "error": e }))?, - )), - value => - Some(messages::opa_event::Payload::Operation(serde_json::to_string(&value)?)), - } - }, - } - .encode_to_vec()) -} diff --git a/crates/opa-tp-protocol/src/lib.rs b/crates/opa-tp-protocol/src/lib.rs deleted file mode 100644 index c695ee43a..000000000 --- a/crates/opa-tp-protocol/src/lib.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![cfg_attr(feature = "strict", deny(warnings))] - -use async_stl_client::{ - ledger::SawtoothLedger, - zmq_client::{RetryingRequestResponseChannel, ZmqRequestResponseSawtoothChannel}, -}; -use state::OpaOperationEvent; -use transaction::OpaSubmitTransaction; -pub mod address; -pub mod events; -pub mod state; -pub mod submission; -pub mod transaction; - -pub use async_stl_client; - -static PROTOCOL_VERSION: &str = "1"; - -pub type OpaLedger = SawtoothLedger< - RetryingRequestResponseChannel, - OpaOperationEvent, - OpaSubmitTransaction, ->; - -// generated from ./protos/ -pub mod messages { - #![allow(clippy::derive_partial_eq_without_eq)] - - include!(concat!(env!("OUT_DIR"), "/_.rs")); -} diff --git a/crates/opa-tp-protocol/src/protos/event.proto b/crates/opa-tp-protocol/src/protos/event.proto deleted file mode 100644 index 8d576db59..000000000 --- a/crates/opa-tp-protocol/src/protos/event.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto3"; - -message OPAEvent { - string version = 1; - uint64 span_id = 2; - oneof payload { - string operation = 3; - string error = 4; - } -} diff --git a/crates/opa-tp-protocol/src/protos/submission.proto b/crates/opa-tp-protocol/src/protos/submission.proto deleted file mode 100644 index 9f3e1e9bb..000000000 --- a/crates/opa-tp-protocol/src/protos/submission.proto +++ /dev/null @@ -1,57 +0,0 @@ -syntax = "proto3"; - -// This message is used to bootstrap the root key for a newly created authz tp, -// it can only be executed once -message BootstrapRoot { string public_key = 1; } - -message RegisterKey { - string public_key = 1; - string id = 2; - bool overwrite_existing = 3; -} - -// Rotate the key with name to the new public key, the SignedOperation for this -// message must be signed by the old key. The signature must be valid for -// the new one, to demonstrate ownership of both keys -message RotateKey { - message NewPublicKey { - bytes public_key = 1; - string id = 2; - } - NewPublicKey payload = 1; - string previous_signing_key = 4; - bytes previous_signature = 5; - string new_signing_key = 6; - bytes new_signature = 7; -} - -// Set the policy with name to the new policy, the SignedOperation for this must -// be signed by the root key -message SetPolicy { - string id = 1; - bytes policy = 2; -} - -// An OPA TP operation and its signature -message SignedOperation { - message Payload { - oneof operation { - RegisterKey register_key = 1; - RotateKey rotate_key = 2; - SetPolicy set_policy = 3; - } - } - - Payload payload = 1; - string verifying_key = 4; - bytes signature = 5; -} - -message Submission { - string version = 1; - uint64 span_id = 2; - oneof payload { - BootstrapRoot bootstrap_root = 3; - SignedOperation signed_operation = 4; - } -} diff --git a/crates/opa-tp-protocol/src/state.rs b/crates/opa-tp-protocol/src/state.rs deleted file mode 100644 index c1edb4bc7..000000000 --- a/crates/opa-tp-protocol/src/state.rs +++ /dev/null @@ -1,74 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::address::{hash_and_append, HasSawtoothAddress}; - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct KeyRegistration { - // Der encoded public key - pub key: String, - pub version: u64, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Keys { - pub id: String, - pub current: KeyRegistration, - pub expired: Option, -} - -impl HasSawtoothAddress for Keys { - fn get_address(&self) -> String { - key_address(&self.id) - } -} - -pub fn policy_address(id: impl AsRef) -> String { - hash_and_append(format!("opa:policy:binary:{}", id.as_ref())) -} - -pub fn policy_meta_address(id: impl AsRef) -> String { - hash_and_append(format!("opa:policy:meta:{}", id.as_ref())) -} - -pub fn key_address(id: impl AsRef) -> String { - hash_and_append(format!("opa:keys:{}", id.as_ref())) -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct PolicyMeta { - pub id: String, - pub hash: String, - pub policy_address: String, -} - -impl HasSawtoothAddress for PolicyMeta { - fn get_address(&self) -> String { - policy_address(&self.id) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum OpaOperationEvent { - PolicyUpdate(PolicyMeta), - KeyUpdate(Keys), - - Error(String), -} - -impl From for OpaOperationEvent { - fn from(v: String) -> Self { - Self::Error(v) - } -} - -impl From for OpaOperationEvent { - fn from(v: Keys) -> Self { - Self::KeyUpdate(v) - } -} - -impl From for OpaOperationEvent { - fn from(v: PolicyMeta) -> Self { - Self::PolicyUpdate(v) - } -} diff --git a/crates/opa-tp-protocol/src/transaction.rs b/crates/opa-tp-protocol/src/transaction.rs deleted file mode 100644 index 19ffb6ce7..000000000 --- a/crates/opa-tp-protocol/src/transaction.rs +++ /dev/null @@ -1,163 +0,0 @@ -use std::{convert::Infallible, sync::Arc}; - -use async_stl_client::{ - ledger::{LedgerTransaction, TransactionId}, - sawtooth::MessageBuilder, -}; -use chronicle_signing::{BatcherKnownKeyNamesSigner, ChronicleSigning, SecretError}; -use k256::ecdsa::VerifyingKey; -use prost::Message; - -use crate::{ - async_stl_client::sawtooth::TransactionPayload, - messages::Submission, - state::{key_address, policy_address, policy_meta_address}, -}; - -#[derive(Debug, Clone)] -pub enum OpaSubmitTransaction { - BootstrapRoot(Submission, ChronicleSigning), - RotateRoot(Submission, ChronicleSigning), - RegisterKey(Submission, ChronicleSigning, String, bool), - RotateKey(Submission, ChronicleSigning, String), - SetPolicy(Submission, ChronicleSigning, String), -} - -impl OpaSubmitTransaction { - pub fn bootstrap_root(submission: Submission, sawtooth_signer: &ChronicleSigning) -> Self { - Self::BootstrapRoot(submission, sawtooth_signer.to_owned()) - } - - pub fn rotate_root(submission: Submission, sawtooth_signer: &ChronicleSigning) -> Self { - Self::RotateRoot(submission, sawtooth_signer.to_owned()) - } - - pub fn register_key( - name: impl AsRef, - submission: Submission, - sawtooth_signer: &ChronicleSigning, - overwrite_existing: bool, - ) -> Self { - Self::RegisterKey( - submission, - sawtooth_signer.to_owned(), - name.as_ref().to_owned(), - overwrite_existing, - ) - } - - pub fn rotate_key( - name: impl AsRef, - submission: Submission, - sawtooth_signer: &ChronicleSigning, - ) -> Self { - Self::RegisterKey(submission, sawtooth_signer.to_owned(), name.as_ref().to_owned(), false) - } - - pub fn set_policy( - name: impl AsRef, - submission: Submission, - sawtooth_signer: &ChronicleSigning, - ) -> Self { - Self::SetPolicy(submission, sawtooth_signer.to_owned(), name.as_ref().to_owned()) - } -} - -#[async_trait::async_trait] -impl TransactionPayload for OpaSubmitTransaction { - type Error = Infallible; - - /// Envelope a payload of `ChronicleOperations` and `SignedIdentity` in a `Submission` protocol - /// buffer, along with placeholders for protocol version info and a tracing span id. - async fn to_bytes(&self) -> Result, Infallible> { - Ok(match self { - Self::BootstrapRoot(submission, _) => submission, - Self::RotateRoot(submission, _) => submission, - Self::RegisterKey(submission, _, _, _) => submission, - Self::RotateKey(submission, _, _) => submission, - Self::SetPolicy(submission, _, _) => submission, - } - .encode_to_vec()) - } -} - -#[async_trait::async_trait] -impl LedgerTransaction for OpaSubmitTransaction { - type Error = SecretError; - - async fn sign(&self, bytes: Arc>) -> Result, Self::Error> { - let signer = match self { - Self::BootstrapRoot(_, signer) => signer, - Self::RotateRoot(_, signer) => signer, - Self::RegisterKey(_, signer, _, _) => signer, - Self::RotateKey(_, signer, _) => signer, - Self::SetPolicy(_, signer, _) => signer, - }; - signer.batcher_sign(&bytes).await - } - - async fn verifying_key(&self) -> Result { - let signer = match self { - Self::BootstrapRoot(_, signer) => signer, - Self::RotateRoot(_, signer) => signer, - Self::RegisterKey(_, signer, _, _) => signer, - Self::RotateKey(_, signer, _) => signer, - Self::SetPolicy(_, signer, _) => signer, - }; - - signer.batcher_verifying().await - } - - fn addresses(&self) -> Vec { - match self { - Self::BootstrapRoot(_, _) => { - vec![key_address("root")] - }, - Self::RotateRoot(_, _) => { - vec![key_address("root")] - }, - Self::RegisterKey(_, _, name, _) => { - vec![key_address("root"), key_address(name.clone())] - }, - Self::RotateKey(_, _, name) => { - vec![key_address("root"), key_address(name.clone())] - }, - Self::SetPolicy(_, _, name) => { - vec![ - key_address("root"), - policy_meta_address(name.clone()), - policy_address(name.clone()), - ] - }, - } - } - - async fn as_sawtooth_tx( - &self, - message_builder: &MessageBuilder, - ) -> Result<(async_stl_client::messages::Transaction, TransactionId), Self::Error> { - let signer = match self { - Self::BootstrapRoot(_, signer) => signer, - Self::RotateRoot(_, signer) => signer, - Self::RegisterKey(_, signer, _, _) => signer, - Self::RotateKey(_, signer, _) => signer, - Self::SetPolicy(_, signer, _) => signer, - } - .clone(); - - message_builder - .make_sawtooth_transaction( - self.addresses(), - self.addresses(), - vec![], - self, - signer.batcher_verifying().await?, - |bytes| { - let signer = signer.clone(); - let bytes = bytes.to_vec(); - async move { signer.batcher_sign(&bytes).await } - }, - ) - .await - } -} diff --git a/crates/opa-tp/Cargo.toml b/crates/opa-tp/Cargo.toml index cb53d3a7a..59f21016d 100644 --- a/crates/opa-tp/Cargo.toml +++ b/crates/opa-tp/Cargo.toml @@ -18,7 +18,6 @@ doc = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -async-stl-client = { workspace = true } async-trait = { workspace = true } bytes = { workspace = true } chronicle-signing = { workspace = true } @@ -35,7 +34,9 @@ k256 = { workspace = true, features = [ "std", "pem", ] } -opa-tp-protocol = { path = "../opa-tp-protocol" } +parity-scale-codec = { version = "3.6.5", default-features = false, features = [ + "derive", +] } prost = { workspace = true } sawtooth-sdk = { workspace = true } serde_json = { workspace = true } diff --git a/crates/opa-tp/src/lib.rs b/crates/opa-tp/src/lib.rs index dd3ac41c7..77e714f0e 100644 --- a/crates/opa-tp/src/lib.rs +++ b/crates/opa-tp/src/lib.rs @@ -1,3 +1,4 @@ //! Library exports for use in test and embedding contexts. pub mod abstract_tp; +pub mod messages; pub mod tp; diff --git a/crates/pallet-chronicle/Cargo.toml b/crates/pallet-chronicle/Cargo.toml index 6b28e7212..2920d5b2b 100644 --- a/crates/pallet-chronicle/Cargo.toml +++ b/crates/pallet-chronicle/Cargo.toml @@ -1,42 +1,54 @@ [package] -name = "pallet-chronicle" edition = "2021" +name = "pallet-chronicle" version = "0.7.5" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -common = {path = "../common", default-features=false, features=["parity"]} -parity-scale-codec = { version="3.6.5", default-features = false, features = ["derive"] } -uuid = {version="1.5.0", default-features=false} -sp-std = { version="11.0.0", default-features = false} -scale-info = { version="2.10.0", default-features = false, features = ["derive"] } -frame-support = { version="24.0.0", default-features=false } -frame-system = { version= "24.0.0",default-features=false } -frame-benchmarking = { version = "24.0.0", default-features = false, optional=true} -tracing = {version="0.1.40", default-features=false, features=["attributes"]} -newtype-derive-2018 = {workspace=true} -macro-attr-2018 = {workspace=true} +common = { path = "../common", default-features = false, features = [ + "parity-encoding", +] } +frame-benchmarking = { version = "25.0.0", default-features = false, optional = true } +frame-support = { version = "25.0.0", default-features = false } +frame-system = { version = "25.0.0", default-features = false } +macro-attr-2018 = { workspace = true } +newtype-derive-2018 = { workspace = true } +parity-scale-codec = { version = "3.6.5", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } +serde = { version = "1.0", default-features = false } +sp-core = { version = "25.0.0", default-features = false } +sp-core-hashing = { version = "14", default-features = false } +sp-std = { version = "12.0.0", default-features = false } +tracing = { version = "0.1", default-features = false, features = [ + "attributes", +] } +uuid = { version = "1.5.0", default-features = false } [dev-dependencies] -sp-runtime = { version="27.0.0"} -sp-io = {version="26.0.0" } -sp-core = {version="24.0.0"} -chronicle-telemetry = {path="../chronicle-telemetry"} +chronicle-telemetry = { path = "../chronicle-telemetry" } +sp-core = { version = "25.0.0" } +sp-io = { version = "27.0.0" } +sp-runtime = { version = "28.0.0" } +uuid = { version = "1.5.0", default-features = true } [features] default = ["std"] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] std = [ - "common/std", - "parity-scale-codec/std", - "uuid/std", - "sp-std/std", - "scale-info/std", - "frame-support/std", - "frame-system/std", - "frame-benchmarking/std", - "tracing/std", + "common/std", + "parity-scale-codec/std", + "uuid/std", + "sp-std/std", + "scale-info/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", + "tracing/std", ] -runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime"] diff --git a/crates/pallet-chronicle/src/lib.rs b/crates/pallet-chronicle/src/lib.rs index ff00c99ca..0f40a0fb1 100644 --- a/crates/pallet-chronicle/src/lib.rs +++ b/crates/pallet-chronicle/src/lib.rs @@ -3,7 +3,7 @@ /// Re-export types required for runtime pub use common::prov::*; -use common::ledger::LedgerAddress; +use common::ledger::ChronicleAddress; /// Edit this file to define custom logic or remove it if it is not needed. /// Learn more about FRAME and the core library of Substrate FRAME pallets: /// @@ -15,19 +15,29 @@ mod mock; #[cfg(test)] mod tests; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +//#[cfg(feature = "runtime-benchmarks")] +//mod benchmarking; pub mod weights; -pub use common::prov::*; + +pub mod chronicle_core { + pub use common::{ledger::*, prov::*}; +} pub use weights::*; +// A configuration type for opa settings, serializable to JSON etc +#[derive(frame_support::Serialize, frame_support::Deserialize)] +pub struct OpaConfiguration { + pub policy_name: scale_info::prelude::string::String, + pub entrypoint: scale_info::prelude::string::String, +} + #[frame_support::pallet] pub mod pallet { use super::*; - use frame_support::pallet_prelude::*; + use common::ledger::OperationSubmission; + use frame_support::{pallet_prelude::*, traits::BuildGenesisConfig}; use frame_system::pallet_prelude::*; - use sp_std::collections::btree_set::BTreeSet; - use sp_std::vec::Vec; + use sp_std::{collections::btree_set::BTreeSet, vec::Vec}; #[pallet::pallet] pub struct Pallet(_); @@ -40,26 +50,56 @@ pub mod pallet { /// Type representing the weight of this pallet type WeightInfo: WeightInfo; - type OperationList: Parameter - + Into> - + From> - + parity_scale_codec::Codec; + type OperationSubmission: Parameter + Into + parity_scale_codec::Codec; + } + + /// Genesis configuration, whether or not we need to enforce OPA policies + #[pallet::genesis_config] + pub struct GenesisConfig { + pub opa_settings: Option, + pub _phantom: PhantomData, + } + + impl Default for GenesisConfig { + fn default() -> Self { + Self { opa_settings: None, _phantom: PhantomData } + } } - // The pallet's runtime storage items. - // https://docs.substrate.io/main-docs/build/runtime-storage/ + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + tracing::info!("Chronicle: Building genesis configuration."); + if let Some(ref settings) = self.opa_settings { + OpaSettings::::put(Some(common::opa::OpaSettings { + policy_address: common::opa::PolicyAddress::from(sp_core_hashing::blake2_128( + settings.policy_name.as_bytes(), + )), + policy_name: settings.policy_name.clone(), + entrypoint: settings.entrypoint.clone(), + })); + tracing::debug!("Chronicle: OPA settings are set."); + } else { + OpaSettings::::put(None::); + } + } + } + #[pallet::storage] #[pallet::getter(fn prov)] - // Learn more about declaring storage items: - // https://docs.substrate.io/main-docs/build/runtime-storage/#declaring-storage-items - pub type Provenance = StorageMap<_, Twox128, LedgerAddress, common::prov::ProvModel>; + pub type Provenance = StorageMap<_, Twox128, ChronicleAddress, common::prov::ProvModel>; + + #[pallet::storage] + #[pallet::getter(fn get_opa_settings)] + pub type OpaSettings = StorageValue<_, Option>; // Pallets use events to inform users when important changes are made. // https://docs.substrate.io/main-docs/build/events-errors/ #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - Applied(common::prov::ProvModel), - Contradiction(common::prov::Contradiction), + Applied(common::prov::ProvModel, common::identity::SignedIdentity, [u8; 16]), + Contradiction(common::prov::Contradiction, common::identity::SignedIdentity, [u8; 16]), } // Errors inform users that something went wrong. @@ -89,7 +129,6 @@ pub mod pallet { match error { common::prov::ProcessorError::Address => Error::Address, common::prov::ProcessorError::Contradiction { .. } => Error::Contradiction, - common::prov::ProcessorError::Expansion { .. } => Error::Expansion, common::prov::ProcessorError::Identity(_) => Error::Identity, common::prov::ProcessorError::NotAChronicleIri { .. } => Error::NotAChronicleIri, common::prov::ProcessorError::MissingId { .. } => Error::MissingId, @@ -102,7 +141,7 @@ pub mod pallet { common::prov::ProcessorError::Time(_) => Error::Time, common::prov::ProcessorError::Tokio => Error::Tokio, common::prov::ProcessorError::Utf8(_) => Error::Utf8, - _ => unreachable!(), //TODO: NOT THIS + _ => unreachable!(), } } } @@ -112,20 +151,26 @@ pub mod pallet { // Dispatchable functions must be annotated with a weight and must return a DispatchResult. #[pallet::call] impl Pallet { - /// An example dispatchable that takes a singles value as a parameter, writes the value to - /// storage and emits an event. This function must be dispatched by a signed extrinsic. + // Apply a vector of chronicle operations, yielding an event that indicates state change or + // contradiction #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::apply())] - pub fn apply(origin: OriginFor, operations: T::OperationList) -> DispatchResult { + #[pallet::weight({ + let weight = T::WeightInfo::apply(); + let dispatch_class = DispatchClass::Normal; + let pays_fee = Pays::No; + (weight, dispatch_class, pays_fee) + })] + pub fn apply(origin: OriginFor, operations: T::OperationSubmission) -> DispatchResult { // Check that the extrinsic was signed and get the signer. // This function will return an error if the extrinsic is not signed. // https://docs.substrate.io/main-docs/build/origins/ - let who = ensure_signed(origin)?; + let _who = ensure_signed(origin)?; - // Get operations and load their dependencies - let ops: Vec = operations.into(); + let sub = operations.into(); - let deps = ops.iter().flat_map(|tx| tx.dependencies()).collect::>(); + // Get operations and load their dependencies + let deps = + sub.operations.iter().flat_map(|tx| tx.dependencies()).collect::>(); let initial_input_models: Vec<_> = deps .into_iter() @@ -138,15 +183,20 @@ pub mod pallet { let mut model = common::prov::ProvModel::default(); - for op in ops { + for op in sub.operations.iter() { let res = op.process(model, state.input()); match res { - // A contradiction raises an event, not an error and shortcuts processing - contradiction attempts are useful provenance - // and should not be a purely operational concern + // A contradiction raises an event, not an error and shortcuts processing - + // contradiction attempts are useful provenance and should not be a purely + // operational concern Err(common::prov::ProcessorError::Contradiction(source)) => { tracing::info!(contradiction = %source); - Self::deposit_event(Event::::Contradiction(source)); + Self::deposit_event(Event::::Contradiction( + source, + (*sub.identity).clone(), + sub.correlation_id, + )); return Ok(()); }, @@ -177,7 +227,7 @@ pub mod pallet { } // Emit an event. - Self::deposit_event(Event::Applied(delta)); + Self::deposit_event(Event::Applied(delta, (*sub.identity).clone(), sub.correlation_id)); // Return a successful DispatchResultWithPostInfo Ok(()) } diff --git a/crates/pallet-chronicle/src/mock.rs b/crates/pallet-chronicle/src/mock.rs index 4d9424fdc..63487f504 100644 --- a/crates/pallet-chronicle/src/mock.rs +++ b/crates/pallet-chronicle/src/mock.rs @@ -1,58 +1,56 @@ use crate as pallet_template; +use common::ledger::OperationSubmission; use frame_support::traits::{ConstU16, ConstU64}; use sp_core::H256; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, - BuildStorage, + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, }; type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( - pub enum Test - { - System: frame_system, - ChronicleModule: pallet_template, - } + pub enum Test + { + System: frame_system, + ChronicleModule: pallet_template, + } ); impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Nonce = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Block = Block; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<250>; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; + type AccountData = (); + type AccountId = u64; + type BaseCallFilter = frame_support::traits::Everything; + type Block = Block; + type BlockHashCount = ConstU64<250>; + type BlockLength = (); + type BlockWeights = (); + type DbWeight = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type Lookup = IdentityLookup; + type MaxConsumers = frame_support::traits::ConstU32<16>; + type Nonce = u64; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type PalletInfo = PalletInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SS58Prefix = ConstU16<42>; + type SystemWeightInfo = (); + type Version = (); } impl pallet_template::Config for Test { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); - type OperationList = Vec; + type OperationSubmission = OperationSubmission; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); } // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::::default() - .build_storage() - .unwrap() - .into() + frame_system::GenesisConfig::::default().build_storage().unwrap().into() } diff --git a/crates/pallet-chronicle/src/tests.rs b/crates/pallet-chronicle/src/tests.rs index 3d9b18b95..301c5587e 100644 --- a/crates/pallet-chronicle/src/tests.rs +++ b/crates/pallet-chronicle/src/tests.rs @@ -1,7 +1,10 @@ use crate::{mock::*, Event}; -use common::prov::{ - operations::{ChronicleOperation, CreateNamespace}, - ExternalId, NamespaceId, +use common::{ + ledger::OperationSubmission, + prov::{ + operations::{ChronicleOperation, CreateNamespace}, + NamespaceId, + }, }; use frame_support::assert_ok; use uuid::Uuid; @@ -11,10 +14,18 @@ fn it_works_for_default_value() { new_test_ext().execute_with(|| { // Go past genesis block so events get deposited System::set_block_number(1); + let op = OperationSubmission::new_anonymous(Uuid::from_bytes([0u8; 16]), vec![]); // Dispatch a signed extrinsic. - assert_ok!(ChronicleModule::apply(RuntimeOrigin::signed(1), vec![])); + assert_ok!(ChronicleModule::apply(RuntimeOrigin::signed(1), op.clone())); // Assert that the correct event was deposited - System::assert_last_event(Event::Applied(common::prov::ProvModel::default()).into()); + System::assert_last_event( + Event::Applied( + common::prov::ProvModel::default(), + common::identity::SignedIdentity::new_no_identity(), + op.correlation_id, + ) + .into(), + ); }); } @@ -24,20 +35,27 @@ fn single_operation() { new_test_ext().execute_with(|| { // Go past genesis block so events get deposited System::set_block_number(1); - let uuid = Uuid::new_v4(); + let uuid = Uuid::from_u128(0u128); let op = ChronicleOperation::CreateNamespace(CreateNamespace { id: NamespaceId::from_external_id("test", uuid), - external_id: ExternalId::from("test"), - uuid: uuid.into(), }); + + let sub = OperationSubmission::new_anonymous(Uuid::from_bytes([0u8; 16]), vec![op.clone()]); // Dispatch our operation - assert_ok!(ChronicleModule::apply(RuntimeOrigin::signed(1), vec![op.clone()])); + assert_ok!(ChronicleModule::apply(RuntimeOrigin::signed(1), sub.clone(),)); // Apply that operation to a new prov model for assertion - // the pallet execution should produce an identical delta let mut delta_model = common::prov::ProvModel::default(); delta_model.apply(&op).unwrap(); // Assert that the delta is correct - System::assert_last_event(Event::Applied(delta_model).into()); + System::assert_last_event( + Event::Applied( + delta_model, + common::identity::SignedIdentity::new_no_identity(), + sub.correlation_id, + ) + .into(), + ); }); } diff --git a/crates/pallet-opa/Cargo.toml b/crates/pallet-opa/Cargo.toml new file mode 100644 index 000000000..628804f49 --- /dev/null +++ b/crates/pallet-opa/Cargo.toml @@ -0,0 +1,62 @@ +[package] +edition = "2021" +name = "pallet-opa" +version = "0.7.5" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +common = { path = "../common", default-features = false, features = [ + "parity-encoding", +] } +frame-benchmarking = { version = "25.0.0", default-features = false, optional = true } +frame-support = { version = "25.0.0", default-features = false } +frame-system = { version = "25.0.0", default-features = false } +k256 = { version = "0.11", default-features = false, features = [ + "arithmetic", + "ecdsa", + "pkcs8", + "pem", +] } +macro-attr-2018 = { workspace = true } +newtype-derive-2018 = { workspace = true } +parity-scale-codec = { version = "3.6.5", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } +serde = { version = "1", default-features = false } +serde_json = { version = "1", default-features = false, features = ["alloc"] } +sp-core = { version = "25", default-features = false } +sp-core-hashing = { version = "14", default-features = false } +sp-std = { version = "12.0.0", default-features = false } +tracing = { version = "0.1", default-features = false, features = [ + "attributes", +] } +uuid = { version = "1.5", default-features = false } + +[dev-dependencies] +chronicle-telemetry = { path = "../chronicle-telemetry" } +sp-core = { version = "25.0.0" } +sp-io = { version = "27.0.0" } +sp-runtime = { version = "28.0.0" } +uuid = { version = "1.5.0", default-features = true } + +[features] +default = ["std"] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +std = [ + "common/std", + "k256/std", + "parity-scale-codec/std", + "uuid/std", + "sp-std/std", + "scale-info/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", + "tracing/std", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/crates/pallet-opa/src/lib.rs b/crates/pallet-opa/src/lib.rs new file mode 100644 index 000000000..cf3893cae --- /dev/null +++ b/crates/pallet-opa/src/lib.rs @@ -0,0 +1,397 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +use core::convert::Infallible; + +/// Re-export types required for runtime +pub use common::prov::*; +use common::{ + k256::ecdsa::{Signature, VerifyingKey}, + opa::{ + codec::{NewPublicKeyV1, OpaSubmissionV1, PayloadV1, SignedOperationV1}, + BootstrapRoot, KeyAddress, KeyRegistration, Keys, OpaSubmission, Operation, Payload, + PolicyAddress, PolicyMeta, PolicyMetaAddress, RegisterKey, RotateKey, SetPolicy, + SignedOperation, SignedOperationPayload, + }, +}; + +use scale_info::prelude::format; + +pub fn policy_address(id: impl AsRef) -> PolicyAddress { + blake2_128(format!("opa:policy:binary:{}", id.as_ref()).as_bytes()).into() +} + +pub fn policy_meta_address(id: impl AsRef) -> PolicyMetaAddress { + blake2_128(format!("opa:policy:meta:{}", id.as_ref()).as_bytes()).into() +} + +pub fn key_address(id: impl AsRef) -> KeyAddress { + blake2_128(format!("opa:keys:{}", id.as_ref()).as_bytes()).into() +} +/// Edit this file to define custom logic or remove it if it is not needed. +/// Learn more about FRAME and the core library of Substrate FRAME pallets: +/// +pub use pallet::*; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +//#[cfg(feature = "runtime-benchmarks")] +//mod benchmarking; +pub mod weights; + +pub mod opa_core { + pub use common::{ledger::*, opa::*}; +} +use parity_scale_codec::Encode; +use sp_core_hashing::blake2_128; +use tracing::{error, instrument}; +pub use weights::*; + +#[derive(Debug)] +enum OpaError { + OperationSignatureVerification, + InvalidSigningKey, + InvalidOperation, +} + +impl From for OpaError { + fn from(_: Infallible) -> Self { + unreachable!() + } +} + +// Verifies the submission. +// Keys == None indicates that the opa tp is not bootstrapped, so the bootstrap +// operation can be performed, otherwise this will be an error +// If the system has been bootstrapped, then the current key must match the signing +// key of the operation +#[instrument(skip(submission, root_keys), ret(Debug))] +fn verify_signed_operation( + submission: &OpaSubmissionV1, + root_keys: &Option, +) -> Result<(), OpaError> { + use k256::ecdsa::signature::Verifier; + match &submission.payload { + PayloadV1::BootstrapRoot(_) => Ok(()), + PayloadV1::SignedOperation(SignedOperationV1 { payload, verifying_key, signature }) => { + if root_keys.is_none() { + error!("No registered root keys for signature verification"); + return Err(OpaError::OperationSignatureVerification); + } + let payload_bytes = payload.encode(); + let signature: Signature = k256::ecdsa::signature::Signature::from_bytes(signature) + .map_err(|e| { + error!(signature = ?signature, signature_load_error = ?e); + OpaError::OperationSignatureVerification + })?; + let signing_key = ::from_public_key_pem( + verifying_key.as_str(), + ) + .map_err(|e| { + error!(verifying_key = ?verifying_key, key_load_error = ?e); + OpaError::OperationSignatureVerification + })?; + if let Err(e) = signing_key.verify(&payload_bytes, &signature) { + error!(signature = ?signature, verify_error = ?e); + return Err(OpaError::OperationSignatureVerification); + } + + if *verifying_key == root_keys.as_ref().unwrap().current.key { + Ok(()) + } else { + error!(verifying_key = ?verifying_key, current_key = ?root_keys.as_ref().unwrap().current.key, "Invalid signing key"); + Err(OpaError::InvalidSigningKey) + } + }, + } +} + +// Either apply our bootstrap operation or our signed operation +#[instrument(skip(payload), ret(Debug))] +fn apply_signed_operation( + correlation_id: ChronicleTransactionId, + payload: Payload, +) -> Result<(), OpaError> { + use scale_info::prelude::string::ToString; + match payload { + Payload::BootstrapRoot(BootstrapRoot { public_key }) => { + let existing_key = pallet::KeyStore::::try_get(key_address("root")); + + if existing_key.is_ok() { + error!("OPA TP has already been bootstrapped"); + return Err(OpaError::InvalidOperation); + } + + let keys = Keys { + id: "root".to_string(), + current: KeyRegistration { key: public_key, version: 0 }, + expired: None, + }; + + pallet::KeyStore::::set(key_address("root"), Some(keys.clone().into())); + + pallet::Pallet::::deposit_event(pallet::Event::::KeyUpdate( + keys.into(), + correlation_id, + )); + + Ok(()) + }, + Payload::SignedOperation(SignedOperation { + payload: SignedOperationPayload { operation }, + verifying_key: _, + signature: _, + }) => apply_signed_operation_payload::(correlation_id, operation), + } +} + +#[instrument(skip(payload), ret(Debug))] +fn apply_signed_operation_payload( + correlation_id: ChronicleTransactionId, + payload: Operation, +) -> Result<(), OpaError> { + match payload { + Operation::RegisterKey(RegisterKey { public_key, id, overwrite_existing }) => { + if id == "root" { + error!("Cannot register a key with the id 'root'"); + return Err(OpaError::InvalidOperation); + } + + let existing_key = pallet::KeyStore::::try_get(key_address(&id)); + + if existing_key.is_ok() { + if overwrite_existing { + tracing::debug!("Registration replaces existing key"); + } else { + error!("Key already registered"); + return Err(OpaError::InvalidOperation); + } + } + + let keys = Keys { + id, + current: KeyRegistration { key: public_key, version: 0 }, + expired: None, + }; + + pallet::KeyStore::::set(key_address(&keys.id), Some(keys.clone().into())); + + pallet::Pallet::::deposit_event(pallet::Event::::KeyUpdate( + keys.try_into()?, + correlation_id, + )); + + Ok(()) + }, + Operation::RotateKey(RotateKey { + payload, + previous_signing_key, + previous_signature, + new_signing_key, + new_signature, + }) => { + // Get current key registration from state + let existing_key = pallet::KeyStore::::try_get(key_address(&payload.id)); + + if existing_key.is_err() { + error!("No key to rotate"); + return Err(OpaError::InvalidOperation); + } + + let existing_key = existing_key.unwrap(); + + if previous_signing_key != existing_key.current.key { + error!("Key does not match current key"); + return Err(OpaError::InvalidOperation); + } + + let payload_id = payload.id.clone(); + let payload_bytes: NewPublicKeyV1 = payload.into(); + // Verify the previous key and signature + let payload_bytes = payload_bytes.encode(); + let previous_signature = Signature::try_from(&*previous_signature) + .map_err(|_| OpaError::OperationSignatureVerification)?; + let previous_key = ::from_public_key_pem( + previous_signing_key.as_str(), + ) + .map_err(|_| OpaError::OperationSignatureVerification)?; + + k256::ecdsa::signature::Verifier::verify( + &previous_key, + &payload_bytes, + &previous_signature, + ) + .map_err(|_| OpaError::OperationSignatureVerification)?; + + //Verify the new key and signature + let new_signature = Signature::try_from(&*new_signature) + .map_err(|_| OpaError::OperationSignatureVerification)?; + let new_key = ::from_public_key_pem( + new_signing_key.as_str(), + ) + .map_err(|_| OpaError::OperationSignatureVerification)?; + + k256::ecdsa::signature::Verifier::verify(&new_key, &payload_bytes, &new_signature) + .map_err(|_| OpaError::OperationSignatureVerification)?; + + //Store new keys + let keys = Keys { + id: payload_id, + current: KeyRegistration { + key: new_signing_key, + version: existing_key.current.version + 1, + }, + expired: Some(KeyRegistration { + key: previous_signing_key, + version: existing_key.current.version, + }), + }; + + pallet::KeyStore::::set(key_address(&keys.id), Some(keys.clone().into())); + + pallet::Pallet::::deposit_event(pallet::Event::::KeyUpdate( + keys.into(), + correlation_id, + )); + + Ok(()) + }, + Operation::SetPolicy(SetPolicy { policy, id }) => { + let hash = sp_core_hashing::blake2_128(policy.as_bytes()); + + let meta = PolicyMeta { + id: id.clone(), + hash: hash.into(), + policy_address: policy_address(&*id), + }; + + pallet::PolicyMetaStore::::set(policy_meta_address(&*id), Some(meta.clone().into())); + + pallet::PolicyStore::::set(policy_address(&*id), Some(policy.into())); + + pallet::Pallet::::deposit_event(pallet::Event::::PolicyUpdate( + meta.into(), + correlation_id, + )); + + Ok(()) + }, + } +} + +fn root_keys_from_state() -> Result, OpaError> { + let existing_key = pallet::KeyStore::::try_get(key_address("root")); + + if let Ok(existing_key) = existing_key { + Ok(Some(existing_key.try_into()?)) + } else { + Ok(None) + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Type representing the weight of this pallet + type WeightInfo: WeightInfo; + + type OpaSubmission: Parameter + + Into + + parity_scale_codec::Codec; + } + // The pallet's runtime storage items. + // https://docs.substrate.io/main-docs/build/runtime-storage/ + #[pallet::storage] + #[pallet::getter(fn get_policy)] + // Learn more about declaring storage items: + // https://docs.substrate.io/main-docs/build/runtime-storage/#declaring-storage-items + pub type PolicyStore = + StorageMap<_, Twox128, common::opa::PolicyAddress, common::opa::codec::PolicyV1>; + #[pallet::storage] + #[pallet::getter(fn get_policy_meta)] + pub type PolicyMetaStore = + StorageMap<_, Twox128, common::opa::PolicyMetaAddress, common::opa::codec::PolicyMetaV1>; + #[pallet::storage] + #[pallet::getter(fn get_key)] + pub type KeyStore = + StorageMap<_, Twox128, common::opa::KeyAddress, common::opa::codec::KeysV1>; + + // Pallets use events to inform users when important changes are made. + // https://docs.substrate.io/main-docs/build/events-errors/ + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + PolicyUpdate(common::opa::codec::PolicyMetaV1, ChronicleTransactionId), + KeyUpdate(common::opa::codec::KeysV1, ChronicleTransactionId), + } + + // Errors inform users that something went wrong. + #[pallet::error] + pub enum Error { + OperationSignatureVerification, + InvalidSigningKey, + JsonSerialize, + InvalidOperation, + } + + impl From for Error { + fn from(error: OpaError) -> Self { + match error { + OpaError::OperationSignatureVerification => Error::OperationSignatureVerification, + OpaError::InvalidSigningKey => Error::InvalidSigningKey, + OpaError::InvalidOperation => Error::InvalidOperation, + } + } + } + + // Dispatchable functions allows users to interact with the pallet and invoke state changes. + // These functions materialize as "extrinsics", which are often compared to transactions. + // Dispatchable functions must be annotated with a weight and must return a DispatchResult. + #[pallet::call] + impl Pallet { + // Apply a vector of chronicle operations, yielding an event that indicates state change or + // contradiction + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::apply())] + pub fn apply(origin: OriginFor, submission: T::OpaSubmission) -> DispatchResult { + // Check that the extrinsic was signed and get the signer. + // This function will return an error if the extrinsic is not signed. + // https://docs.substrate.io/main-docs/build/origins/ + let _who = ensure_signed(origin)?; + + // We need to validate the submission's own internal signatures at the codec level + let submission: OpaSubmissionV1 = submission.into(); + + super::verify_signed_operation::( + &submission, + &super::root_keys_from_state::().map_err(Error::::from)?, + ) + .map_err(Error::::from)?; + + let submission: OpaSubmission = submission.into(); + + super::apply_signed_operation::( + submission.correlation_id.into(), + submission.payload, + ) + .map_err(Error::::from)?; + + // Return a successful DispatchResultWithPostInfo + Ok(()) + } + } +} diff --git a/crates/pallet-opa/src/mock.rs b/crates/pallet-opa/src/mock.rs new file mode 100644 index 000000000..2707ed494 --- /dev/null +++ b/crates/pallet-opa/src/mock.rs @@ -0,0 +1,48 @@ +use crate as pallet_template; +use common::opa::codec::OpaSubmissionV1; +use frame_support::traits::{ConstU16, ConstU64}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; + +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + ChronicleModule: pallet_template, + } +); + +impl frame_system::Config for Test { + type AccountData = (); + type AccountId = u64; + type BaseCallFilter = frame_support::traits::Everything; + type Block = Block; + type BlockHashCount = ConstU64<250>; + type BlockLength = (); + type BlockWeights = (); + type DbWeight = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type Lookup = IdentityLookup; + type MaxConsumers = frame_support::traits::ConstU32<16>; + type Nonce = u64; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type PalletInfo = PalletInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SS58Prefix = ConstU16<42>; + type SystemWeightInfo = (); + type Version = (); +} + +impl pallet_template::Config for Test { + type OpaSubmission = OpaSubmissionV1; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); +} diff --git a/crates/pallet-opa/src/tests.rs b/crates/pallet-opa/src/tests.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/crates/pallet-opa/src/tests.rs @@ -0,0 +1 @@ + diff --git a/crates/pallet-opa/src/weights.rs b/crates/pallet-opa/src/weights.rs new file mode 100644 index 000000000..c2b102ef7 --- /dev/null +++ b/crates/pallet-opa/src/weights.rs @@ -0,0 +1,66 @@ +//! Autogenerated weights for pallet_template +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-04-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Alexs-MacBook-Pro-2.local`, CPU: `` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ../../target/release/node-template +// benchmark +// pallet +// --chain +// dev +// --pallet +// pallet_template +// --extrinsic +// * +// --steps=50 +// --repeat=20 +// --wasm-execution=compiled +// --output +// pallets/template/src/weights.rs +// --template +// ../../.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for pallet_template. +pub trait WeightInfo { + fn apply() -> Weight; +} + +/// Weights for pallet_template using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: TemplateModule Something (r:0 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn apply() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: TemplateModule Something (r:0 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn apply() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/crates/pallet-opa/tree.txt b/crates/pallet-opa/tree.txt new file mode 100644 index 000000000..c4b35efba --- /dev/null +++ b/crates/pallet-opa/tree.txt @@ -0,0 +1,1257 @@ +pallet-chronicle v0.7.5 (/Users/ryan/code/chronicle/crates/pallet-chronicle) +├── common v0.7.5 (/Users/ryan/code/chronicle/crates/common) +│ ├── anyhow v1.0.75 +│ ├── async-trait v0.1.74 (proc-macro) +│ │ ├── proc-macro2 v1.0.69 +│ │ │ └── unicode-ident v1.0.12 +│ │ ├── quote v1.0.33 +│ │ │ └── proc-macro2 v1.0.69 (*) +│ │ └── syn v2.0.38 +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── unicode-ident v1.0.12 +│ ├── chrono v0.4.31 +│ │ ├── js-sys v0.3.64 +│ │ │ └── wasm-bindgen v0.2.87 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ └── wasm-bindgen-macro v0.2.87 (proc-macro) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── wasm-bindgen-macro-support v0.2.87 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ ├── syn v2.0.38 (*) +│ │ │ ├── wasm-bindgen-backend v0.2.87 +│ │ │ │ ├── bumpalo v3.14.0 +│ │ │ │ ├── log v0.4.20 +│ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ ├── syn v2.0.38 (*) +│ │ │ │ └── wasm-bindgen-shared v0.2.87 +│ │ │ └── wasm-bindgen-shared v0.2.87 +│ │ ├── num-traits v0.2.17 +│ │ │ [build-dependencies] +│ │ │ └── autocfg v1.1.0 +│ │ ├── serde v1.0.190 +│ │ │ └── serde_derive v1.0.190 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ └── wasm-bindgen v0.2.87 (*) +│ ├── futures v0.3.29 +│ │ ├── futures-channel v0.3.29 +│ │ │ ├── futures-core v0.3.29 +│ │ │ └── futures-sink v0.3.29 +│ │ ├── futures-core v0.3.29 +│ │ ├── futures-executor v0.3.29 +│ │ │ ├── futures-core v0.3.29 +│ │ │ ├── futures-task v0.3.29 +│ │ │ ├── futures-util v0.3.29 +│ │ │ │ ├── futures-channel v0.3.29 (*) +│ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ ├── futures-io v0.3.29 +│ │ │ │ ├── futures-macro v0.3.29 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── futures-sink v0.3.29 +│ │ │ │ ├── futures-task v0.3.29 +│ │ │ │ ├── memchr v2.6.4 +│ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ ├── pin-utils v0.1.0 +│ │ │ │ └── slab v0.4.9 +│ │ │ │ [build-dependencies] +│ │ │ │ └── autocfg v1.1.0 +│ │ │ └── num_cpus v1.16.0 +│ │ │ └── libc v0.2.149 +│ │ ├── futures-io v0.3.29 +│ │ ├── futures-sink v0.3.29 +│ │ ├── futures-task v0.3.29 +│ │ └── futures-util v0.3.29 (*) +│ ├── glob v0.3.1 +│ ├── hex v0.4.3 +│ ├── iref v2.2.3 +│ │ ├── pct-str v1.2.0 +│ │ │ └── utf8-decode v1.0.1 +│ │ └── smallvec v1.11.1 +│ ├── iref-enum v2.1.0 (proc-macro) +│ │ ├── iref v2.2.3 +│ │ │ ├── pct-str v1.2.0 +│ │ │ │ └── utf8-decode v1.0.1 +│ │ │ └── smallvec v1.11.1 +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── unicode-ident v1.0.12 +│ ├── k256 v0.11.6 +│ │ ├── cfg-if v1.0.0 +│ │ ├── ecdsa v0.14.8 +│ │ │ ├── der v0.6.1 +│ │ │ │ └── const-oid v0.9.5 +│ │ │ ├── elliptic-curve v0.12.3 +│ │ │ │ ├── base16ct v0.1.1 +│ │ │ │ ├── crypto-bigint v0.4.9 +│ │ │ │ │ ├── generic-array v0.14.7 +│ │ │ │ │ │ ├── typenum v1.17.0 +│ │ │ │ │ │ └── zeroize v1.6.0 +│ │ │ │ │ │ └── zeroize_derive v1.4.2 (proc-macro) +│ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ └── getrandom v0.2.10 +│ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ ├── digest v0.10.7 +│ │ │ │ │ ├── block-buffer v0.10.4 +│ │ │ │ │ │ └── generic-array v0.14.7 (*) +│ │ │ │ │ ├── const-oid v0.9.5 +│ │ │ │ │ ├── crypto-common v0.1.6 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── ff v0.12.1 +│ │ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ ├── group v0.12.1 +│ │ │ │ │ ├── ff v0.12.1 (*) +│ │ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── pkcs8 v0.9.0 +│ │ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ │ └── spki v0.6.0 +│ │ │ │ │ └── der v0.6.1 (*) +│ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ ├── sec1 v0.3.0 +│ │ │ │ │ ├── base16ct v0.1.1 +│ │ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── subtle v2.4.1 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── rfc6979 v0.3.1 +│ │ │ │ ├── crypto-bigint v0.4.9 (*) +│ │ │ │ ├── hmac v0.12.1 +│ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ └── signature v1.6.4 +│ │ │ ├── digest v0.10.7 (*) +│ │ │ └── rand_core v0.6.4 (*) +│ │ ├── elliptic-curve v0.12.3 (*) +│ │ └── sha2 v0.10.8 +│ │ ├── cfg-if v1.0.0 +│ │ └── digest v0.10.7 (*) +│ ├── lazy_static v1.4.0 +│ ├── locspan v0.7.16 +│ ├── macro-attr-2018 v3.0.0 +│ ├── mime v0.3.17 +│ ├── newtype-derive-2018 v0.2.1 +│ │ └── generics v0.5.1 +│ ├── parity-scale-codec v3.6.5 +│ │ ├── arrayvec v0.7.4 +│ │ ├── byte-slice-cast v1.2.2 +│ │ ├── bytes v1.5.0 +│ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── parity-scale-codec-derive v3.6.5 (proc-macro) +│ │ │ ├── proc-macro-crate v1.1.3 +│ │ │ │ ├── thiserror v1.0.50 +│ │ │ │ │ └── thiserror-impl v1.0.50 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ └── toml v0.5.11 +│ │ │ │ └── serde v1.0.190 +│ │ │ │ └── serde_derive v1.0.190 (proc-macro) (*) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ └── serde v1.0.190 (*) +│ ├── percent-encoding v2.3.0 +│ ├── scale-info v2.10.0 +│ │ ├── cfg-if v1.0.0 +│ │ ├── derive_more v0.99.17 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info-derive v2.10.0 (proc-macro) +│ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ └── serde v1.0.190 (*) +│ ├── serde v1.0.190 (*) +│ ├── serde_derive v1.0.190 (proc-macro) (*) +│ ├── serde_json v1.0.108 +│ │ ├── itoa v1.0.9 +│ │ ├── ryu v1.0.15 +│ │ └── serde v1.0.190 (*) +│ ├── static-iref v2.0.0 (proc-macro) +│ │ └── iref v2.2.3 (*) +│ ├── thiserror v1.0.50 +│ │ └── thiserror-impl v1.0.50 (proc-macro) (*) +│ ├── thiserror-no-std v2.0.2 +│ │ └── thiserror-impl-no-std v2.0.2 (proc-macro) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 (*) +│ ├── tracing v0.1.40 +│ │ ├── pin-project-lite v0.2.13 +│ │ ├── tracing-attributes v0.1.27 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ └── tracing-core v0.1.32 +│ │ └── once_cell v1.18.0 +│ ├── url v2.4.1 +│ │ ├── form_urlencoded v1.2.0 +│ │ │ └── percent-encoding v2.3.0 +│ │ ├── idna v0.4.0 +│ │ │ ├── unicode-bidi v0.3.13 +│ │ │ └── unicode-normalization v0.1.22 +│ │ │ └── tinyvec v1.6.0 +│ │ │ └── tinyvec_macros v0.1.1 +│ │ ├── percent-encoding v2.3.0 +│ │ └── serde v1.0.190 (*) +│ └── uuid v1.5.0 +│ └── serde v1.0.190 (*) +│ [build-dependencies] +│ ├── glob v0.3.1 +│ ├── lazy_static v1.4.0 +│ └── serde_json v1.0.108 +│ ├── itoa v1.0.9 +│ ├── ryu v1.0.15 +│ └── serde v1.0.190 (*) +├── frame-support v24.0.0 +│ ├── aquamarine v0.3.2 (proc-macro) +│ │ ├── include_dir v0.7.3 +│ │ │ └── include_dir_macros v0.7.3 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ └── quote v1.0.33 (*) +│ │ ├── itertools v0.10.5 +│ │ │ └── either v1.9.0 +│ │ ├── proc-macro-error v1.0.4 +│ │ │ ├── proc-macro-error-attr v1.0.4 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ └── quote v1.0.33 (*) +│ │ │ │ [build-dependencies] +│ │ │ │ └── version_check v0.9.4 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ │ [build-dependencies] +│ │ │ └── version_check v0.9.4 +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v1.0.109 (*) +│ ├── bitflags v1.3.2 +│ ├── docify v0.2.6 +│ │ └── docify_macros v0.2.6 (proc-macro) +│ │ ├── common-path v1.0.0 +│ │ ├── derive-syn-parse v0.1.5 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── once_cell v1.18.0 +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ ├── regex v1.10.2 +│ │ │ ├── aho-corasick v1.1.2 +│ │ │ │ └── memchr v2.6.4 +│ │ │ ├── memchr v2.6.4 +│ │ │ ├── regex-automata v0.4.3 +│ │ │ │ ├── aho-corasick v1.1.2 (*) +│ │ │ │ ├── memchr v2.6.4 +│ │ │ │ └── regex-syntax v0.8.2 +│ │ │ └── regex-syntax v0.8.2 +│ │ ├── syn v2.0.38 (*) +│ │ ├── termcolor v1.3.0 +│ │ ├── toml v0.7.8 +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── serde_spanned v0.6.4 +│ │ │ │ └── serde v1.0.190 (*) +│ │ │ ├── toml_datetime v0.6.5 +│ │ │ │ └── serde v1.0.190 (*) +│ │ │ └── toml_edit v0.19.15 +│ │ │ ├── indexmap v2.0.2 +│ │ │ │ ├── equivalent v1.0.1 +│ │ │ │ └── hashbrown v0.14.2 +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── serde_spanned v0.6.4 (*) +│ │ │ ├── toml_datetime v0.6.5 (*) +│ │ │ └── winnow v0.5.17 +│ │ └── walkdir v2.4.0 +│ │ └── same-file v1.0.6 +│ ├── environmental v1.1.4 +│ ├── frame-metadata v16.0.0 +│ │ ├── cfg-if v1.0.0 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ └── scale-info v2.10.0 (*) +│ ├── frame-support-procedural v19.0.0 (proc-macro) +│ │ ├── Inflector v0.11.4 +│ │ │ ├── lazy_static v1.4.0 +│ │ │ └── regex v1.10.2 (*) +│ │ ├── cfg-expr v0.15.5 +│ │ │ └── smallvec v1.11.1 +│ │ ├── derive-syn-parse v0.1.5 (proc-macro) (*) +│ │ ├── expander v2.0.0 +│ │ │ ├── blake2 v0.10.6 +│ │ │ │ └── digest v0.10.7 +│ │ │ │ ├── block-buffer v0.10.4 +│ │ │ │ │ └── generic-array v0.14.7 +│ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ ├── crypto-common v0.1.6 +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ └── subtle v2.4.1 +│ │ │ ├── fs-err v2.9.0 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── frame-support-procedural-tools v8.0.0 +│ │ │ ├── frame-support-procedural-tools-derive v9.0.0 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── itertools v0.10.5 (*) +│ │ ├── macro_magic v0.4.2 +│ │ │ ├── macro_magic_core v0.4.2 +│ │ │ │ ├── const-random v0.1.16 +│ │ │ │ │ └── const-random-macro v0.1.16 (proc-macro) +│ │ │ │ │ ├── getrandom v0.2.10 +│ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ └── libc v0.2.149 +│ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ └── tiny-keccak v2.0.2 +│ │ │ │ │ └── crunchy v0.2.2 +│ │ │ │ ├── derive-syn-parse v0.1.5 (proc-macro) (*) +│ │ │ │ ├── macro_magic_core_macros v0.4.3 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── macro_magic_macros v0.4.2 (proc-macro) +│ │ │ │ ├── macro_magic_core v0.4.2 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── proc-macro-warning v0.4.2 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v2.0.38 (*) +│ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ ├── k256 v0.13.1 +│ │ ├── cfg-if v1.0.0 +│ │ ├── ecdsa v0.16.8 +│ │ │ ├── der v0.7.8 +│ │ │ │ ├── const-oid v0.9.5 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── digest v0.10.7 (*) +│ │ │ ├── elliptic-curve v0.13.6 +│ │ │ │ ├── base16ct v0.2.0 +│ │ │ │ ├── crypto-bigint v0.5.3 +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ ├── ff v0.13.0 +│ │ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ ├── group v0.13.0 +│ │ │ │ │ ├── ff v0.13.0 (*) +│ │ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ ├── sec1 v0.7.3 +│ │ │ │ │ ├── base16ct v0.2.0 +│ │ │ │ │ ├── der v0.7.8 (*) +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── subtle v2.4.1 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── rfc6979 v0.4.0 +│ │ │ │ ├── hmac v0.12.1 (*) +│ │ │ │ └── subtle v2.4.1 +│ │ │ └── signature v2.1.0 +│ │ │ ├── digest v0.10.7 (*) +│ │ │ └── rand_core v0.6.4 (*) +│ │ ├── elliptic-curve v0.13.6 (*) +│ │ └── sha2 v0.10.8 (*) +│ ├── log v0.4.20 +│ ├── macro_magic v0.4.2 +│ │ └── macro_magic_macros v0.4.2 (proc-macro) (*) +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── paste v1.0.14 (proc-macro) +│ ├── scale-info v2.10.0 (*) +│ ├── serde v1.0.190 (*) +│ ├── serde_json v1.0.108 (*) +│ ├── smallvec v1.11.1 +│ ├── sp-api v22.0.0 +│ │ ├── log v0.4.20 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── sp-api-proc-macro v11.0.0 (proc-macro) +│ │ │ ├── Inflector v0.11.4 (*) +│ │ │ ├── blake2 v0.10.6 (*) +│ │ │ ├── expander v2.0.0 (*) +│ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── sp-core v24.0.0 +│ │ │ ├── array-bytes v6.1.0 +│ │ │ ├── bitflags v1.3.2 +│ │ │ ├── blake2 v0.10.6 +│ │ │ │ └── digest v0.10.7 (*) +│ │ │ ├── bounded-collections v0.1.9 +│ │ │ │ ├── log v0.4.20 +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ └── serde v1.0.190 (*) +│ │ │ ├── bs58 v0.5.0 +│ │ │ ├── dyn-clonable v0.9.0 +│ │ │ │ ├── dyn-clonable-impl v0.9.0 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ └── dyn-clone v1.0.14 +│ │ │ ├── ed25519-zebra v3.1.0 +│ │ │ │ ├── curve25519-dalek v3.2.0 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── digest v0.9.0 +│ │ │ │ │ │ └── generic-array v0.14.7 (*) +│ │ │ │ │ ├── rand_core v0.5.1 +│ │ │ │ │ │ └── getrandom v0.1.16 +│ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── hashbrown v0.12.3 +│ │ │ │ │ └── ahash v0.7.7 +│ │ │ │ │ └── once_cell v1.18.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ ├── hex v0.4.3 +│ │ │ │ ├── rand_core v0.6.4 (*) +│ │ │ │ ├── sha2 v0.9.9 +│ │ │ │ │ ├── block-buffer v0.9.0 +│ │ │ │ │ │ └── generic-array v0.14.7 (*) +│ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ ├── digest v0.9.0 (*) +│ │ │ │ │ └── opaque-debug v0.3.0 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── futures v0.3.29 (*) +│ │ │ ├── hash-db v0.16.0 +│ │ │ ├── hash256-std-hasher v0.15.2 +│ │ │ │ └── crunchy v0.2.2 +│ │ │ ├── impl-serde v0.4.0 +│ │ │ │ └── serde v1.0.190 (*) +│ │ │ ├── lazy_static v1.4.0 +│ │ │ ├── libsecp256k1 v0.7.1 +│ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ ├── base64 v0.13.1 +│ │ │ │ ├── digest v0.9.0 (*) +│ │ │ │ ├── hmac-drbg v0.3.0 +│ │ │ │ │ ├── digest v0.9.0 (*) +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ └── hmac v0.8.1 +│ │ │ │ │ ├── crypto-mac v0.8.0 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ └── digest v0.9.0 (*) +│ │ │ │ ├── libsecp256k1-core v0.3.0 +│ │ │ │ │ ├── crunchy v0.2.2 +│ │ │ │ │ ├── digest v0.9.0 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── rand v0.8.5 +│ │ │ │ │ ├── rand_chacha v0.3.1 +│ │ │ │ │ │ ├── ppv-lite86 v0.2.17 +│ │ │ │ │ │ └── rand_core v0.6.4 (*) +│ │ │ │ │ └── rand_core v0.6.4 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── sha2 v0.9.9 (*) +│ │ │ │ └── typenum v1.17.0 +│ │ │ │ [build-dependencies] +│ │ │ │ ├── libsecp256k1-gen-ecmult v0.3.0 +│ │ │ │ │ └── libsecp256k1-core v0.3.0 +│ │ │ │ │ ├── crunchy v0.2.2 +│ │ │ │ │ ├── digest v0.9.0 +│ │ │ │ │ │ └── generic-array v0.14.7 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ └── libsecp256k1-gen-genmult v0.3.0 +│ │ │ │ └── libsecp256k1-core v0.3.0 (*) +│ │ │ ├── log v0.4.20 +│ │ │ ├── merlin v2.0.1 +│ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ ├── keccak v0.1.4 +│ │ │ │ ├── rand_core v0.5.1 (*) +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── parking_lot v0.12.1 +│ │ │ │ ├── lock_api v0.4.11 +│ │ │ │ │ └── scopeguard v1.2.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── autocfg v1.1.0 +│ │ │ │ └── parking_lot_core v0.9.9 +│ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ └── smallvec v1.11.1 +│ │ │ ├── paste v1.0.14 (proc-macro) +│ │ │ ├── primitive-types v0.12.2 +│ │ │ │ ├── fixed-hash v0.8.0 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ ├── rustc-hex v2.1.0 +│ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ ├── impl-codec v0.6.0 +│ │ │ │ │ └── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── impl-serde v0.4.0 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ └── uint v0.9.5 +│ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ ├── crunchy v0.2.2 +│ │ │ │ ├── hex v0.4.3 +│ │ │ │ └── static_assertions v1.1.0 +│ │ │ ├── rand v0.8.5 (*) +│ │ │ ├── regex v1.10.2 +│ │ │ │ ├── aho-corasick v1.1.2 +│ │ │ │ │ └── memchr v2.6.4 +│ │ │ │ ├── memchr v2.6.4 +│ │ │ │ ├── regex-automata v0.4.3 +│ │ │ │ │ ├── aho-corasick v1.1.2 (*) +│ │ │ │ │ ├── memchr v2.6.4 +│ │ │ │ │ └── regex-syntax v0.8.2 +│ │ │ │ └── regex-syntax v0.8.2 +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── schnorrkel v0.9.1 +│ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ ├── arrayvec v0.5.2 +│ │ │ │ ├── curve25519-dalek v2.1.3 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── digest v0.8.1 +│ │ │ │ │ │ └── generic-array v0.12.4 +│ │ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ ├── rand_core v0.5.1 (*) +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── getrandom v0.1.16 (*) +│ │ │ │ ├── merlin v2.0.1 (*) +│ │ │ │ ├── rand v0.7.3 +│ │ │ │ │ ├── getrandom v0.1.16 (*) +│ │ │ │ │ ├── rand_chacha v0.2.2 +│ │ │ │ │ │ ├── ppv-lite86 v0.2.17 +│ │ │ │ │ │ └── rand_core v0.5.1 (*) +│ │ │ │ │ └── rand_core v0.5.1 (*) +│ │ │ │ ├── rand_core v0.5.1 (*) +│ │ │ │ ├── sha2 v0.8.2 +│ │ │ │ │ ├── block-buffer v0.7.3 +│ │ │ │ │ │ ├── block-padding v0.1.5 +│ │ │ │ │ │ │ └── byte-tools v0.3.1 +│ │ │ │ │ │ ├── byte-tools v0.3.1 +│ │ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ │ └── generic-array v0.12.4 (*) +│ │ │ │ │ ├── digest v0.8.1 (*) +│ │ │ │ │ ├── fake-simd v0.1.2 +│ │ │ │ │ └── opaque-debug v0.2.3 +│ │ │ │ ├── subtle v2.4.1 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── secp256k1 v0.24.3 +│ │ │ │ └── secp256k1-sys v0.6.1 +│ │ │ │ [build-dependencies] +│ │ │ │ └── cc v1.0.83 +│ │ │ │ └── libc v0.2.149 +│ │ │ ├── secrecy v0.8.0 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── sp-core-hashing v12.0.0 +│ │ │ │ ├── blake2b_simd v1.0.2 +│ │ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ │ └── constant_time_eq v0.3.0 +│ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ ├── sha2 v0.10.8 (*) +│ │ │ │ ├── sha3 v0.10.8 +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ └── keccak v0.1.4 +│ │ │ │ └── twox-hash v1.6.3 +│ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ └── static_assertions v1.1.0 +│ │ │ ├── sp-debug-derive v11.0.0 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── sp-externalities v0.22.0 +│ │ │ │ ├── environmental v1.1.4 +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ └── sp-storage v16.0.0 +│ │ │ │ ├── impl-serde v0.4.0 (*) +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── ref-cast v1.0.20 +│ │ │ │ │ └── ref-cast-impl v1.0.20 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── sp-debug-derive v11.0.0 (proc-macro) (*) +│ │ │ │ └── sp-std v11.0.0 +│ │ │ ├── sp-runtime-interface v20.0.0 +│ │ │ │ ├── bytes v1.5.0 +│ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── primitive-types v0.12.2 (*) +│ │ │ │ ├── sp-externalities v0.22.0 (*) +│ │ │ │ ├── sp-runtime-interface-proc-macro v14.0.0 (proc-macro) +│ │ │ │ │ ├── Inflector v0.11.4 (*) +│ │ │ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ ├── sp-storage v16.0.0 (*) +│ │ │ │ ├── sp-tracing v13.0.0 +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ ├── tracing-core v0.1.32 (*) +│ │ │ │ │ └── tracing-subscriber v0.2.25 +│ │ │ │ │ ├── ansi_term v0.12.1 +│ │ │ │ │ ├── chrono v0.4.31 (*) +│ │ │ │ │ ├── lazy_static v1.4.0 +│ │ │ │ │ ├── matchers v0.0.1 +│ │ │ │ │ │ └── regex-automata v0.1.10 +│ │ │ │ │ │ └── regex-syntax v0.6.29 +│ │ │ │ │ ├── regex v1.10.2 (*) +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ ├── serde_json v1.0.108 (*) +│ │ │ │ │ ├── sharded-slab v0.1.7 +│ │ │ │ │ │ └── lazy_static v1.4.0 +│ │ │ │ │ ├── smallvec v1.11.1 +│ │ │ │ │ ├── thread_local v1.1.7 +│ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ └── once_cell v1.18.0 +│ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ ├── tracing-core v0.1.32 (*) +│ │ │ │ │ ├── tracing-log v0.1.4 +│ │ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ │ └── tracing-core v0.1.32 (*) +│ │ │ │ │ └── tracing-serde v0.1.3 +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ └── tracing-core v0.1.32 (*) +│ │ │ │ ├── sp-wasm-interface v17.0.0 +│ │ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ └── wasmtime v8.0.1 +│ │ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ │ ├── bincode v1.3.3 +│ │ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ ├── indexmap v1.9.3 +│ │ │ │ │ │ ├── hashbrown v0.12.3 (*) +│ │ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── autocfg v1.1.0 +│ │ │ │ │ ├── libc v0.2.149 +│ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ ├── object v0.30.4 +│ │ │ │ │ │ ├── crc32fast v1.3.2 +│ │ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ │ ├── hashbrown v0.13.2 +│ │ │ │ │ │ │ └── ahash v0.8.6 +│ │ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ │ ├── getrandom v0.2.10 (*) +│ │ │ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ │ │ └── zerocopy v0.7.20 +│ │ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ └── memchr v2.6.4 +│ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ ├── paste v1.0.14 (proc-macro) +│ │ │ │ │ ├── psm v0.1.21 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── cc v1.0.83 (*) +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ ├── target-lexicon v0.12.12 +│ │ │ │ │ ├── wasmparser v0.102.0 +│ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ └── url v2.4.1 (*) +│ │ │ │ │ ├── wasmtime-environ v8.0.1 +│ │ │ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ │ │ ├── cranelift-entity v0.95.1 +│ │ │ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ │ │ ├── gimli v0.27.3 +│ │ │ │ │ │ │ ├── fallible-iterator v0.2.0 +│ │ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ │ └── stable_deref_trait v1.2.0 +│ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ │ ├── object v0.30.4 (*) +│ │ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ │ ├── target-lexicon v0.12.12 +│ │ │ │ │ │ ├── thiserror v1.0.50 (*) +│ │ │ │ │ │ ├── wasmparser v0.102.0 (*) +│ │ │ │ │ │ └── wasmtime-types v8.0.1 +│ │ │ │ │ │ ├── cranelift-entity v0.95.1 (*) +│ │ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ │ ├── thiserror v1.0.50 (*) +│ │ │ │ │ │ └── wasmparser v0.102.0 (*) +│ │ │ │ │ ├── wasmtime-jit v8.0.1 +│ │ │ │ │ │ ├── addr2line v0.19.0 +│ │ │ │ │ │ │ └── gimli v0.27.3 (*) +│ │ │ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ │ │ ├── bincode v1.3.3 (*) +│ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ ├── cpp_demangle v0.3.5 +│ │ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ │ ├── gimli v0.27.3 (*) +│ │ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ │ ├── object v0.30.4 (*) +│ │ │ │ │ │ ├── rustc-demangle v0.1.23 +│ │ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ │ ├── target-lexicon v0.12.12 +│ │ │ │ │ │ ├── wasmtime-environ v8.0.1 (*) +│ │ │ │ │ │ ├── wasmtime-jit-icache-coherence v8.0.1 +│ │ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ │ └── wasmtime-runtime v8.0.1 +│ │ │ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ ├── libc v0.2.149 +│ │ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ │ ├── memfd v0.6.4 +│ │ │ │ │ │ │ └── rustix v0.38.21 +│ │ │ │ │ │ │ ├── bitflags v2.4.1 +│ │ │ │ │ │ │ ├── errno v0.3.5 +│ │ │ │ │ │ │ └── libc v0.2.149 +│ │ │ │ │ │ ├── memoffset v0.8.0 +│ │ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ │ └── autocfg v1.1.0 +│ │ │ │ │ │ ├── paste v1.0.14 (proc-macro) +│ │ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ │ ├── wasmtime-asm-macros v8.0.1 +│ │ │ │ │ │ │ └── cfg-if v1.0.0 +│ │ │ │ │ │ ├── wasmtime-environ v8.0.1 (*) +│ │ │ │ │ │ └── wasmtime-jit-debug v8.0.1 +│ │ │ │ │ │ └── once_cell v1.18.0 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── cc v1.0.83 (*) +│ │ │ │ │ └── wasmtime-runtime v8.0.1 (*) +│ │ │ │ └── static_assertions v1.1.0 +│ │ │ ├── sp-std v11.0.0 +│ │ │ ├── sp-storage v16.0.0 (*) +│ │ │ ├── ss58-registry v1.43.0 +│ │ │ │ └── num-format v0.4.4 +│ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ └── itoa v1.0.9 +│ │ │ │ [build-dependencies] +│ │ │ │ ├── Inflector v0.11.4 (*) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── serde_json v1.0.108 (*) +│ │ │ │ └── unicode-xid v0.2.4 +│ │ │ ├── substrate-bip39 v0.4.5 +│ │ │ │ ├── hmac v0.11.0 +│ │ │ │ │ ├── crypto-mac v0.11.1 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ └── digest v0.9.0 (*) +│ │ │ │ ├── pbkdf2 v0.8.0 +│ │ │ │ │ └── crypto-mac v0.11.1 (*) +│ │ │ │ ├── schnorrkel v0.9.1 (*) +│ │ │ │ ├── sha2 v0.9.9 (*) +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── thiserror v1.0.50 (*) +│ │ │ ├── tiny-bip39 v1.0.0 +│ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ ├── hmac v0.12.1 (*) +│ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ ├── pbkdf2 v0.11.0 +│ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ ├── rustc-hash v1.1.0 +│ │ │ │ ├── sha2 v0.10.8 (*) +│ │ │ │ ├── thiserror v1.0.50 (*) +│ │ │ │ ├── unicode-normalization v0.1.22 (*) +│ │ │ │ ├── wasm-bindgen v0.2.87 (*) +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── tracing v0.1.40 (*) +│ │ │ └── zeroize v1.6.0 (*) +│ │ ├── sp-metadata-ir v0.3.0 +│ │ │ ├── frame-metadata v16.0.0 (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ └── sp-std v11.0.0 +│ │ ├── sp-runtime v27.0.0 +│ │ │ ├── either v1.9.0 +│ │ │ ├── hash256-std-hasher v0.15.2 (*) +│ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ ├── log v0.4.20 +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── paste v1.0.14 (proc-macro) +│ │ │ ├── rand v0.8.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── sp-application-crypto v26.0.0 +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ ├── sp-io v26.0.0 +│ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ ├── ed25519-dalek v2.0.0 +│ │ │ │ │ │ ├── curve25519-dalek v4.1.1 +│ │ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ │ ├── platforms v3.1.2 +│ │ │ │ │ │ │ └── rustc_version v0.4.0 +│ │ │ │ │ │ │ └── semver v1.0.20 +│ │ │ │ │ │ ├── ed25519 v2.2.3 +│ │ │ │ │ │ │ └── signature v2.1.0 (*) +│ │ │ │ │ │ └── sha2 v0.10.8 (*) +│ │ │ │ │ ├── libsecp256k1 v0.7.1 (*) +│ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── secp256k1 v0.24.3 (*) +│ │ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ │ ├── sp-externalities v0.22.0 (*) +│ │ │ │ │ ├── sp-keystore v0.30.0 +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ ├── parking_lot v0.12.1 (*) +│ │ │ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ │ │ ├── sp-externalities v0.22.0 (*) +│ │ │ │ │ │ └── thiserror v1.0.50 (*) +│ │ │ │ │ ├── sp-runtime-interface v20.0.0 (*) +│ │ │ │ │ ├── sp-state-machine v0.31.0 +│ │ │ │ │ │ ├── hash-db v0.16.0 +│ │ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ ├── parking_lot v0.12.1 (*) +│ │ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ │ ├── smallvec v1.11.1 +│ │ │ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ │ │ ├── sp-externalities v0.22.0 (*) +│ │ │ │ │ │ ├── sp-panic-handler v11.0.0 +│ │ │ │ │ │ │ ├── backtrace v0.3.69 +│ │ │ │ │ │ │ │ ├── addr2line v0.21.0 +│ │ │ │ │ │ │ │ │ └── gimli v0.28.0 +│ │ │ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ │ │ ├── libc v0.2.149 +│ │ │ │ │ │ │ │ ├── miniz_oxide v0.7.1 +│ │ │ │ │ │ │ │ │ └── adler v1.0.2 +│ │ │ │ │ │ │ │ ├── object v0.32.1 +│ │ │ │ │ │ │ │ │ └── memchr v2.6.4 +│ │ │ │ │ │ │ │ └── rustc-demangle v0.1.23 +│ │ │ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ │ │ └── cc v1.0.83 (*) +│ │ │ │ │ │ │ ├── lazy_static v1.4.0 +│ │ │ │ │ │ │ └── regex v1.10.2 (*) +│ │ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ │ ├── sp-trie v25.0.0 +│ │ │ │ │ │ │ ├── ahash v0.8.6 (*) +│ │ │ │ │ │ │ ├── hash-db v0.16.0 +│ │ │ │ │ │ │ ├── hashbrown v0.13.2 (*) +│ │ │ │ │ │ │ ├── lazy_static v1.4.0 +│ │ │ │ │ │ │ ├── memory-db v0.32.0 +│ │ │ │ │ │ │ │ └── hash-db v0.16.0 +│ │ │ │ │ │ │ ├── nohash-hasher v0.2.0 +│ │ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ │ ├── parking_lot v0.12.1 (*) +│ │ │ │ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ │ │ │ ├── schnellru v0.2.1 +│ │ │ │ │ │ │ │ ├── ahash v0.8.6 (*) +│ │ │ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ │ │ └── hashbrown v0.13.2 (*) +│ │ │ │ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ │ │ ├── thiserror v1.0.50 (*) +│ │ │ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ │ │ ├── trie-db v0.28.0 +│ │ │ │ │ │ │ │ ├── hash-db v0.16.0 +│ │ │ │ │ │ │ │ ├── hashbrown v0.13.2 (*) +│ │ │ │ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ │ │ │ ├── rustc-hex v2.1.0 +│ │ │ │ │ │ │ │ └── smallvec v1.11.1 +│ │ │ │ │ │ │ └── trie-root v0.18.0 +│ │ │ │ │ │ │ └── hash-db v0.16.0 +│ │ │ │ │ │ ├── thiserror v1.0.50 (*) +│ │ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ │ └── trie-db v0.28.0 (*) +│ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ ├── sp-tracing v13.0.0 (*) +│ │ │ │ │ ├── sp-trie v25.0.0 (*) +│ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ └── tracing-core v0.1.32 (*) +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── rustversion v1.0.14 (proc-macro) +│ │ │ │ └── sp-std v11.0.0 +│ │ │ ├── sp-arithmetic v19.0.0 +│ │ │ │ ├── integer-sqrt v0.1.5 +│ │ │ │ │ └── num-traits v0.2.17 (*) +│ │ │ │ ├── num-traits v0.2.17 (*) +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ └── static_assertions v1.1.0 +│ │ │ ├── sp-core v24.0.0 (*) +│ │ │ ├── sp-io v26.0.0 (*) +│ │ │ ├── sp-std v11.0.0 +│ │ │ └── sp-weights v23.0.0 +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── smallvec v1.11.1 +│ │ │ ├── sp-arithmetic v19.0.0 (*) +│ │ │ ├── sp-core v24.0.0 (*) +│ │ │ ├── sp-debug-derive v11.0.0 (proc-macro) (*) +│ │ │ └── sp-std v11.0.0 +│ │ ├── sp-std v11.0.0 +│ │ └── sp-version v25.0.0 +│ │ ├── impl-serde v0.4.0 (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── sp-core-hashing-proc-macro v12.0.0 (proc-macro) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ ├── sp-core-hashing v12.0.0 +│ │ │ │ ├── blake2b_simd v1.0.2 +│ │ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ │ └── constant_time_eq v0.3.0 +│ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ ├── sha2 v0.10.8 +│ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ ├── cpufeatures v0.2.11 +│ │ │ │ │ │ └── libc v0.2.149 +│ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ ├── sha3 v0.10.8 +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ └── keccak v0.1.4 +│ │ │ │ │ └── cpufeatures v0.2.11 (*) +│ │ │ │ └── twox-hash v1.6.3 +│ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ └── static_assertions v1.1.0 +│ │ │ └── syn v2.0.38 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ ├── sp-std v11.0.0 +│ │ └── sp-version-proc-macro v11.0.0 (proc-macro) +│ │ ├── parity-scale-codec v3.6.5 +│ │ │ ├── arrayvec v0.7.4 +│ │ │ ├── byte-slice-cast v1.2.2 +│ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ ├── parity-scale-codec-derive v3.6.5 (proc-macro) (*) +│ │ │ └── serde v1.0.190 (*) +│ │ ├── proc-macro2 v1.0.69 (*) +│ │ ├── quote v1.0.33 (*) +│ │ └── syn v2.0.38 (*) +│ ├── sp-arithmetic v19.0.0 (*) +│ ├── sp-core v24.0.0 (*) +│ ├── sp-core-hashing-proc-macro v12.0.0 (proc-macro) (*) +│ ├── sp-debug-derive v11.0.0 (proc-macro) (*) +│ ├── sp-genesis-builder v0.3.0 +│ │ ├── serde_json v1.0.108 (*) +│ │ ├── sp-api v22.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── sp-inherents v22.0.0 +│ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── sp-io v26.0.0 (*) +│ ├── sp-metadata-ir v0.3.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ ├── sp-staking v22.0.0 +│ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── sp-core v24.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── sp-std v11.0.0 +│ ├── sp-tracing v13.0.0 (*) +│ ├── sp-weights v23.0.0 (*) +│ ├── static_assertions v1.1.0 +│ └── tt-call v1.0.9 +├── frame-system v24.0.0 +│ ├── cfg-if v1.0.0 +│ ├── frame-support v24.0.0 (*) +│ ├── log v0.4.20 +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── serde v1.0.190 (*) +│ ├── sp-core v24.0.0 (*) +│ ├── sp-io v26.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ ├── sp-std v11.0.0 +│ ├── sp-version v25.0.0 (*) +│ └── sp-weights v23.0.0 (*) +├── macro-attr-2018 v3.0.0 +├── newtype-derive-2018 v0.2.1 (*) +├── parity-scale-codec v3.6.5 (*) +├── scale-info v2.10.0 (*) +├── sp-std v11.0.0 +├── tracing v0.1.40 (*) +└── uuid v1.5.0 (*) +[dev-dependencies] +├── chronicle-telemetry v0.7.5 (/Users/ryan/code/chronicle/crates/chronicle-telemetry) +│ ├── cfg-if v1.0.0 +│ ├── console-subscriber v0.1.10 +│ │ ├── console-api v0.5.0 +│ │ │ ├── prost v0.11.9 +│ │ │ │ ├── bytes v1.5.0 +│ │ │ │ └── prost-derive v0.11.9 (proc-macro) +│ │ │ │ ├── anyhow v1.0.75 +│ │ │ │ ├── itertools v0.10.5 (*) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v1.0.109 (*) +│ │ │ ├── prost-types v0.11.9 +│ │ │ │ └── prost v0.11.9 (*) +│ │ │ ├── tonic v0.9.2 +│ │ │ │ ├── async-trait v0.1.74 (proc-macro) (*) +│ │ │ │ ├── axum v0.6.20 +│ │ │ │ │ ├── async-trait v0.1.74 (proc-macro) (*) +│ │ │ │ │ ├── axum-core v0.3.4 +│ │ │ │ │ │ ├── async-trait v0.1.74 (proc-macro) (*) +│ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ ├── futures-util v0.3.29 (*) +│ │ │ │ │ │ ├── http v0.2.9 +│ │ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ │ ├── fnv v1.0.7 +│ │ │ │ │ │ │ └── itoa v1.0.9 +│ │ │ │ │ │ ├── http-body v0.4.5 +│ │ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ │ ├── http v0.2.9 (*) +│ │ │ │ │ │ │ └── pin-project-lite v0.2.13 +│ │ │ │ │ │ ├── mime v0.3.17 +│ │ │ │ │ │ ├── tower-layer v0.3.2 +│ │ │ │ │ │ └── tower-service v0.3.2 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── rustversion v1.0.14 (proc-macro) +│ │ │ │ │ ├── bitflags v1.3.2 +│ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ ├── futures-util v0.3.29 (*) +│ │ │ │ │ ├── http v0.2.9 (*) +│ │ │ │ │ ├── http-body v0.4.5 (*) +│ │ │ │ │ ├── hyper v0.14.27 +│ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ ├── futures-channel v0.3.29 (*) +│ │ │ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ │ │ ├── futures-util v0.3.29 (*) +│ │ │ │ │ │ ├── h2 v0.3.21 +│ │ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ │ ├── fnv v1.0.7 +│ │ │ │ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ │ │ │ ├── futures-sink v0.3.29 +│ │ │ │ │ │ │ ├── futures-util v0.3.29 (*) +│ │ │ │ │ │ │ ├── http v0.2.9 (*) +│ │ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ │ ├── slab v0.4.9 (*) +│ │ │ │ │ │ │ ├── tokio v1.33.0 +│ │ │ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ │ │ ├── mio v0.8.9 +│ │ │ │ │ │ │ │ ├── num_cpus v1.16.0 (*) +│ │ │ │ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ │ │ │ └── tokio-macros v2.1.0 (proc-macro) +│ │ │ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ │ │ ├── tokio-util v0.7.10 +│ │ │ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ │ │ │ │ ├── futures-sink v0.3.29 +│ │ │ │ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ │ │ │ ├── tokio v1.33.0 (*) +│ │ │ │ │ │ │ │ └── tracing v0.1.40 (*) +│ │ │ │ │ │ │ └── tracing v0.1.40 (*) +│ │ │ │ │ │ ├── http v0.2.9 (*) +│ │ │ │ │ │ ├── http-body v0.4.5 (*) +│ │ │ │ │ │ ├── httparse v1.8.0 +│ │ │ │ │ │ ├── httpdate v1.0.3 +│ │ │ │ │ │ ├── itoa v1.0.9 +│ │ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ │ ├── socket2 v0.4.10 +│ │ │ │ │ │ ├── tokio v1.33.0 (*) +│ │ │ │ │ │ ├── tower-service v0.3.2 +│ │ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ │ └── want v0.3.1 +│ │ │ │ │ │ └── try-lock v0.2.4 +│ │ │ │ │ ├── itoa v1.0.9 +│ │ │ │ │ ├── matchit v0.7.3 +│ │ │ │ │ ├── memchr v2.6.4 +│ │ │ │ │ ├── mime v0.3.17 +│ │ │ │ │ ├── percent-encoding v2.3.0 +│ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ ├── sync_wrapper v0.1.2 +│ │ │ │ │ ├── tower v0.4.13 +│ │ │ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ │ │ ├── futures-util v0.3.29 (*) +│ │ │ │ │ │ ├── indexmap v1.9.3 (*) +│ │ │ │ │ │ ├── pin-project v1.1.3 +│ │ │ │ │ │ │ └── pin-project-internal v1.1.3 (proc-macro) +│ │ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ │ ├── rand v0.8.5 (*) +│ │ │ │ │ │ ├── slab v0.4.9 (*) +│ │ │ │ │ │ ├── tokio v1.33.0 (*) +│ │ │ │ │ │ ├── tokio-util v0.7.10 (*) +│ │ │ │ │ │ ├── tower-layer v0.3.2 +│ │ │ │ │ │ ├── tower-service v0.3.2 +│ │ │ │ │ │ └── tracing v0.1.40 (*) +│ │ │ │ │ ├── tower-layer v0.3.2 +│ │ │ │ │ └── tower-service v0.3.2 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── rustversion v1.0.14 (proc-macro) +│ │ │ │ ├── base64 v0.21.5 +│ │ │ │ ├── bytes v1.5.0 +│ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ ├── futures-util v0.3.29 (*) +│ │ │ │ ├── h2 v0.3.21 (*) +│ │ │ │ ├── http v0.2.9 (*) +│ │ │ │ ├── http-body v0.4.5 (*) +│ │ │ │ ├── hyper v0.14.27 (*) +│ │ │ │ ├── hyper-timeout v0.4.1 +│ │ │ │ │ ├── hyper v0.14.27 (*) +│ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ ├── tokio v1.33.0 (*) +│ │ │ │ │ └── tokio-io-timeout v1.2.0 +│ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ └── tokio v1.33.0 (*) +│ │ │ │ ├── percent-encoding v2.3.0 +│ │ │ │ ├── pin-project v1.1.3 (*) +│ │ │ │ ├── prost v0.11.9 (*) +│ │ │ │ ├── tokio v1.33.0 (*) +│ │ │ │ ├── tokio-stream v0.1.14 +│ │ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ └── tokio v1.33.0 (*) +│ │ │ │ ├── tower v0.4.13 (*) +│ │ │ │ ├── tower-layer v0.3.2 +│ │ │ │ ├── tower-service v0.3.2 +│ │ │ │ └── tracing v0.1.40 (*) +│ │ │ └── tracing-core v0.1.32 (*) +│ │ ├── crossbeam-channel v0.5.8 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ └── crossbeam-utils v0.8.16 +│ │ │ └── cfg-if v1.0.0 +│ │ ├── crossbeam-utils v0.8.16 (*) +│ │ ├── futures v0.3.29 (*) +│ │ ├── hdrhistogram v7.5.2 +│ │ │ ├── base64 v0.13.1 +│ │ │ ├── byteorder v1.5.0 +│ │ │ ├── flate2 v1.0.28 +│ │ │ │ ├── crc32fast v1.3.2 (*) +│ │ │ │ └── miniz_oxide v0.7.1 (*) +│ │ │ ├── nom v7.1.3 +│ │ │ │ ├── memchr v2.6.4 +│ │ │ │ └── minimal-lexical v0.2.1 +│ │ │ └── num-traits v0.2.17 (*) +│ │ ├── humantime v2.1.0 +│ │ ├── prost-types v0.11.9 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── serde_json v1.0.108 (*) +│ │ ├── thread_local v1.1.7 (*) +│ │ ├── tokio v1.33.0 (*) +│ │ ├── tokio-stream v0.1.14 (*) +│ │ ├── tonic v0.9.2 (*) +│ │ ├── tracing v0.1.40 (*) +│ │ ├── tracing-core v0.1.32 (*) +│ │ └── tracing-subscriber v0.3.17 +│ │ ├── matchers v0.1.0 +│ │ │ └── regex-automata v0.1.10 (*) +│ │ ├── nu-ansi-term v0.46.0 +│ │ │ └── overload v0.1.1 +│ │ ├── once_cell v1.18.0 +│ │ ├── regex v1.10.2 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── serde_json v1.0.108 (*) +│ │ ├── sharded-slab v0.1.7 (*) +│ │ ├── smallvec v1.11.1 +│ │ ├── thread_local v1.1.7 (*) +│ │ ├── tracing v0.1.40 (*) +│ │ ├── tracing-core v0.1.32 (*) +│ │ ├── tracing-log v0.1.4 (*) +│ │ └── tracing-serde v0.1.3 (*) +│ ├── tracing v0.1.40 (*) +│ ├── tracing-elastic-apm v3.2.3 +│ │ ├── anyhow v1.0.75 +│ │ ├── base64 v0.13.1 +│ │ ├── fxhash v0.2.1 +│ │ │ └── byteorder v1.5.0 +│ │ ├── rand v0.8.5 (*) +│ │ ├── reqwest v0.11.22 +│ │ │ ├── base64 v0.21.5 +│ │ │ ├── bytes v1.5.0 +│ │ │ ├── futures-core v0.3.29 +│ │ │ ├── futures-util v0.3.29 (*) +│ │ │ ├── http v0.2.9 (*) +│ │ │ ├── js-sys v0.3.64 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── serde_json v1.0.108 (*) +│ │ │ ├── serde_urlencoded v0.7.1 +│ │ │ │ ├── form_urlencoded v1.2.0 (*) +│ │ │ │ ├── itoa v1.0.9 +│ │ │ │ ├── ryu v1.0.15 +│ │ │ │ └── serde v1.0.190 (*) +│ │ │ ├── tower-service v0.3.2 +│ │ │ ├── url v2.4.1 (*) +│ │ │ ├── wasm-bindgen v0.2.87 (*) +│ │ │ ├── wasm-bindgen-futures v0.4.37 +│ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ ├── js-sys v0.3.64 (*) +│ │ │ │ └── wasm-bindgen v0.2.87 (*) +│ │ │ └── web-sys v0.3.64 +│ │ │ ├── js-sys v0.3.64 (*) +│ │ │ └── wasm-bindgen v0.2.87 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── serde_json v1.0.108 (*) +│ │ ├── tokio v1.33.0 (*) +│ │ ├── tracing v0.1.40 (*) +│ │ ├── tracing-subscriber v0.3.17 (*) +│ │ └── version v3.0.0 +│ ├── tracing-log v0.1.4 (*) +│ ├── tracing-subscriber v0.3.17 (*) +│ └── url v2.4.1 (*) +├── sp-core v24.0.0 (*) +└── sp-runtime v27.0.0 (*) diff --git a/crates/protocol-abstract/Cargo.toml b/crates/protocol-abstract/Cargo.toml new file mode 100644 index 000000000..d6daaa784 --- /dev/null +++ b/crates/protocol-abstract/Cargo.toml @@ -0,0 +1,18 @@ +[package] +edition = "2021" +name = "protocol-abstract" +version = "0.1.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +async-trait = { workspace = true } +futures = { workspace = true } +k256 = { workspace = true } +pallet-chronicle = { path = "../pallet-chronicle", features = ["std"] } +serde = { workspace = true } +subxt = { version = "0.32", features = ["substrate-compat"] } +thiserror = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } diff --git a/crates/protocol-abstract/src/abstract_ledger.rs b/crates/protocol-abstract/src/abstract_ledger.rs new file mode 100644 index 000000000..121ffaf12 --- /dev/null +++ b/crates/protocol-abstract/src/abstract_ledger.rs @@ -0,0 +1,282 @@ +use std::str::FromStr; + +use async_trait::async_trait; +use futures::stream::BoxStream; +use pallet_chronicle::ChronicleTransactionId; +use std::time::Duration; +use subxt::ext::sp_core::H256; +use thiserror::Error; +use tokio::time::sleep; +use tracing::{instrument, warn}; + +#[derive(Debug, Error)] +pub enum BlockIdError { + #[error("Parse {0}")] + Parse(#[from] anyhow::Error), +} +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum BlockId { + Unknown, //Block ids can be null, empty string etc + Block(H256), //ToDo - trait +} + +impl From for BlockId { + fn from(hash: H256) -> Self { + BlockId::Block(hash) + } +} + +impl TryFrom<&str> for BlockId { + type Error = BlockIdError; + + #[instrument(level = "trace", skip(s), err)] + fn try_from(s: &str) -> Result { + let hash = H256::from_str(s).map_err(|e| BlockIdError::Parse(anyhow::Error::new(e)))?; + Ok(BlockId::Block(hash)) + } +} + +impl std::fmt::Display for BlockId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BlockId::Unknown => f.write_str("Unknown"), + BlockId::Block(hash) => f.write_str(&format!("{:?}", hash)), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Position(u32); + +impl From for Position { + fn from(height: u32) -> Self { + Position(height) + } +} + +impl PartialOrd for Position { + fn partial_cmp(&self, other: &Self) -> Option { + let (Position(x), Position(y)) = (self, other); + x.partial_cmp(y) + } +} + +impl Position { + pub fn new(height: u32) -> Self { + Position(height) + } + + pub fn map(&self, f: F) -> T + where + F: FnOnce(&u32) -> T, + { + f(&self.0) + } + + pub fn distance(&self, other: &Self) -> u32 { + let (Position(x), Position(y)) = (self, other); + x.saturating_sub(*y) + } +} + +impl std::fmt::Display for Position { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Position(x) => f.write_str(&format!("{}", x)), + } + } +} + +// Type that can contain a distributed tracing span for transaction processors +// that support it +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Span { + Span(u64), + NotTraced, +} + +// An application specific ledger event with its corresponding transaction id, +// block height and trace span +pub type LedgerEventContext = (Event, ChronicleTransactionId, BlockId, Position, Span); + +#[async_trait::async_trait] +pub trait LedgerEvent { + fn correlation_id(&self) -> [u8; 16]; +} + +#[async_trait::async_trait] +pub trait LedgerEventCodec { + type Source; + type Sink: LedgerEvent + Send + Sync; + type Error: std::error::Error; + // Attempt to deserialize an event, where there may be none present in the source + async fn maybe_deserialize( + source: Self::Source, + ) -> Result, Self::Error> + where + Self: Sized; +} + +pub trait MessageBuilder {} + +#[async_trait::async_trait] +pub trait LedgerTransaction { + type Error: std::error::Error + Send + Sync + 'static; + type Payload: Sized + Send + Sync; + async fn as_payload(&self) -> Result; + fn correlation_id(&self) -> [u8; 16]; +} + +#[async_trait::async_trait] +pub trait LedgerWriter { + type Error: std::error::Error; + type Transaction: LedgerTransaction; + type Submittable: Sized; + + // Minimally process the transaction offline to get a transaction id and submittable type + async fn pre_submit( + &self, + tx: Self::Transaction, + ) -> Result<(Self::Submittable, ChronicleTransactionId), Self::Error>; + + // Submit is used to submit a transaction to the ledger + async fn do_submit( + &self, + submittable: Self::Submittable, + ) -> Result; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FromBlock { + // Do not attempt to catch up, start from the current head + Head, + // Discover the first useful block and start from there + First, + // Start from the given block + BlockId(BlockId), +} + +#[async_trait::async_trait] +pub trait LedgerReader { + type Event: LedgerEvent; + type EventCodec: LedgerEventCodec; + type Error: std::error::Error; + // Get the block height of the ledger, and the id of the highest block + async fn block_height(&self) -> Result<(Position, BlockId), Self::Error>; + /// Subscribe to state updates from this ledger, starting at `offset`, and + /// ending the stream after `number_of_blocks` blocks have been processed. + async fn state_updates( + &self, + // The block to start from + from_block: FromBlock, + // The number of blocks to process before ending the stream + number_of_blocks: Option, + ) -> Result>, Self::Error>; +} + +pub fn retryable_ledger(ledger: L, retry_delay: Duration) -> RetryLedger { + RetryLedger::new(ledger, retry_delay) +} + +#[derive(Clone)] +pub struct RetryLedger { + inner: L, + retry_delay: Duration, +} + +impl RetryLedger { + pub fn new(inner: L, retry_delay: Duration) -> Self { + Self { inner, retry_delay } + } +} + +#[async_trait::async_trait] +impl LedgerWriter for RetryLedger +where + L: LedgerReader + LedgerWriter + Send + Sync, + ::Error: Send + Sync + 'static, + ::Transaction: Send + Sync + 'static, + L::Submittable: Send + Sync + 'static + Clone, +{ + type Error = ::Error; + type Submittable = L::Submittable; + type Transaction = L::Transaction; + + async fn pre_submit( + &self, + tx: Self::Transaction, + ) -> Result<(Self::Submittable, ChronicleTransactionId), Self::Error> { + tracing::debug!(target: "ledger_writer", "Pre-submitting transaction"); + let pre_submit_result = self.inner.pre_submit(tx).await; + match pre_submit_result { + Ok(result) => Ok(result), + Err(e) => { + tracing::error!(error = %e, "Failed to pre-submit transaction"); + Err(e) + }, + } + } + + async fn do_submit( + &self, + submittable: Self::Submittable, + ) -> Result { + let mut attempts = 0; + loop { + match self.inner.do_submit(submittable.clone()).await { + Ok(result) => { + tracing::info!(target: "ledger_writer", "Successfully submitted transaction"); + return Ok(result); + }, + Err(e) => { + attempts += 1; + tracing::warn!(error = %e.0, attempts, "Failed to submit transaction, retrying after delay"); + tokio::time::sleep(self.retry_delay).await; + }, + } + } + } +} + +#[async_trait] +impl LedgerReader for RetryLedger +where + ::Error: Send + Sync, +{ + type Error = L::Error; + type Event = L::Event; + type EventCodec = L::EventCodec; + + async fn block_height(&self) -> Result<(Position, BlockId), Self::Error> { + let mut attempts = 0; + loop { + match self.inner.block_height().await { + Ok(result) => { + tracing::info!(target: "ledger_reader", "Successfully retrieved block height"); + return Ok(result); + }, + Err(e) => { + attempts += 1; + tracing::warn!(error = %e, attempts, "Failed to get block height, retrying after delay"); + tokio::time::sleep(self.retry_delay).await; + }, + } + } + } + + async fn state_updates( + &self, + from_block: FromBlock, + number_of_blocks: Option, + ) -> Result>, Self::Error> { + loop { + match self.inner.state_updates(from_block, number_of_blocks).await { + Ok(stream) => return Ok(stream), + Err(e) => { + warn!(error = %e, "Failed to subscribe to state updates, retrying after delay"); + sleep(self.retry_delay).await; + }, + } + } + } +} diff --git a/crates/protocol-abstract/src/lib.rs b/crates/protocol-abstract/src/lib.rs new file mode 100644 index 000000000..634907139 --- /dev/null +++ b/crates/protocol-abstract/src/lib.rs @@ -0,0 +1,3 @@ +mod abstract_ledger; + +pub use abstract_ledger::*; diff --git a/crates/protocol-substrate-chronicle/Cargo.toml b/crates/protocol-substrate-chronicle/Cargo.toml new file mode 100644 index 000000000..718149040 --- /dev/null +++ b/crates/protocol-substrate-chronicle/Cargo.toml @@ -0,0 +1,45 @@ +[package] +edition = "2021" +name = "protocol-substrate-chronicle" +version = "0.1.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait = { workspace = true } +clap_builder = { version = "*" } +futures = { workspace = true } +k256 = { workspace = true } +serde = { workspace = true } +subxt = { version = "0.32", features = ["substrate-compat"] } +thiserror = { workspace = true } +tracing = { workspace = true } +uuid = { workspace = true, features = ["std", "v4"] } +#local dependencies +chronicle-signing = { path = "../chronicle-signing" } +common = { path = "../common", features = ["parity-encoding", "std"] } +hex = { workspace = true } +opa = { git = "https://github.com/chronicleworks/opa-rs", rev = "9fa2fbce" } +pallet-chronicle = { path = "../pallet-chronicle", features = ["std"] } +parity-scale-codec = { version = "3.6.5", default-features = false, features = [ + "derive", + "max-encoded-len", + "std", +] } +protocol-abstract = { path = "../protocol-abstract" } +protocol-substrate = { path = "../protocol-substrate" } +scale-encode = { version = "0.5", features = [ + "derive", + "primitive-types", + "bits", +] } +scale-info = { version = "2.10.0", features = ["derive", "std"] } +tokio = { workspace = true } + +[dev-dependencies] +chronicle-telemetry = { path = "../chronicle-telemetry" } +embedded-substrate = { path = "../embedded-substrate" } + + +[features] +default = [] diff --git a/crates/protocol-substrate-chronicle/src/lib.rs b/crates/protocol-substrate-chronicle/src/lib.rs new file mode 100644 index 000000000..f88ebbb38 --- /dev/null +++ b/crates/protocol-substrate-chronicle/src/lib.rs @@ -0,0 +1,7 @@ +mod subxt_client; + +pub mod protocol { + pub use protocol_abstract::*; +} + +pub use subxt_client::*; diff --git a/crates/protocol-substrate-chronicle/src/subxt_client.rs b/crates/protocol-substrate-chronicle/src/subxt_client.rs new file mode 100644 index 000000000..e075d233e --- /dev/null +++ b/crates/protocol-substrate-chronicle/src/subxt_client.rs @@ -0,0 +1,336 @@ +use std::{convert::Infallible, marker::PhantomData, sync::Arc}; + +use chronicle_signing::{ + ChronicleSigning, OwnedSecret, SecretError, BATCHER_NAMESPACE, BATCHER_PK, +}; +use common::{identity::SignedIdentity, ledger::OperationSubmission, opa::OpaSettings}; + +use pallet_chronicle::operations::ChronicleOperation; +use protocol_substrate::{SubstrateClient, SubxtClientError}; +use subxt::ext::{ + codec::Decode, + scale_value::Composite, + sp_core::{blake2_256, Pair}, +}; + +use subxt::{ + tx::Signer, + utils::{AccountId32, MultiAddress, MultiSignature}, +}; + +use protocol_abstract::{LedgerEvent, LedgerEventCodec, LedgerTransaction, Span}; + +//This type must match pallet::Event but we cannot reference it directly +pub enum ChronicleEvent { + Committed { + diff: common::prov::ProvModel, + identity: SignedIdentity, + correlation_id: [u8; 16], + }, + Contradicted { + contradiction: common::prov::Contradiction, + identity: SignedIdentity, + correlation_id: [u8; 16], + }, +} + +//This type must match pallet::Event but we cannot reference it directly +pub struct ChronicleEventCodec +where + C: subxt::Config, +{ + _p: PhantomData, +} + +impl ChronicleEvent { + #[tracing::instrument(level = "trace", skip(diff, identity), fields(diff = tracing::field::debug(&diff), identity = tracing::field::debug(&identity), correlation_id = tracing::field::debug(&correlation_id)))] + pub fn new_committed( + diff: common::prov::ProvModel, + identity: SignedIdentity, + correlation_id: [u8; 16], + ) -> Self { + ChronicleEvent::Committed { diff, identity, correlation_id } + } + + pub fn new_contradicted( + contradiction: common::prov::Contradiction, + identity: SignedIdentity, + correlation_id: [u8; 16], + ) -> Self { + ChronicleEvent::Contradicted { contradiction, identity, correlation_id } + } +} + +fn extract_event( + event: subxt::events::EventDetails, +) -> Result, SubxtClientError> +where + C: subxt::Config, +{ + type Applied = (common::prov::ProvModel, common::identity::SignedIdentity, [u8; 16]); + type Contradicted = (common::prov::Contradiction, common::identity::SignedIdentity, [u8; 16]); + match (event.pallet_name(), event.variant_name(), event.field_bytes()) { + ("Chronicle", "Applied", mut event_bytes) => match Applied::decode(&mut event_bytes) { + Ok((prov_model, identity, correlation_id)) => { + Ok(Some(ChronicleEvent::new_committed(prov_model, identity, correlation_id))) + }, + Err(e) => { + tracing::error!("Failed to decode ProvModel: {}", e); + Err(e.into()) + }, + }, + ("Chronicle", "Contradicted", mut event_bytes) => { + match Contradicted::decode(&mut event_bytes) { + Ok((contradiction, identity, correlation_id)) => { + Ok(ChronicleEvent::new_contradicted(contradiction, identity, correlation_id) + .into()) + }, + Err(e) => { + tracing::error!("Failed to decode Contradiction: {}", e); + Err(e.into()) + }, + } + }, + (_pallet, _event, _) => Ok(None), + } +} + +impl LedgerEvent for ChronicleEvent { + fn correlation_id(&self) -> [u8; 16] { + match self { + Self::Committed { correlation_id, .. } => *correlation_id, + Self::Contradicted { correlation_id, .. } => *correlation_id, + } + } +} + +#[async_trait::async_trait] +impl LedgerEventCodec for ChronicleEventCodec +where + C: subxt::Config, +{ + type Error = SubxtClientError; + type Sink = ChronicleEvent; + type Source = subxt::events::EventDetails; + + async fn maybe_deserialize( + source: Self::Source, + ) -> Result, Self::Error> + where + Self: Sized, + { + match extract_event(source) { + Ok(Some(ev)) => Ok(Some((ev, Span::NotTraced))), + Ok(None) => Ok(None), + Err(e) => Err(e), + } + } +} + +pub struct ChronicleTransaction { + correlation_id: uuid::Uuid, + key: subxt::ext::sp_core::ecdsa::Pair, //We need the batcher key to sign transactions + identity: Arc, + operations: Arc>, +} + +impl ChronicleTransaction { + pub async fn new( + signer: &ChronicleSigning, + identity: SignedIdentity, + operations: impl IntoIterator, + ) -> Result { + Ok(Self { + correlation_id: uuid::Uuid::new_v4(), + key: subxt::ext::sp_core::ecdsa::Pair::from_seed_slice( + &signer.copy_signing_key(BATCHER_NAMESPACE, BATCHER_PK).await?.to_bytes(), + ) + .unwrap(), + identity: identity.into(), + operations: Arc::new(operations.into_iter().collect::>()), + }) + } +} + +// This type must match the signature of the extrinsic call +#[derive( + scale_info::TypeInfo, + scale_encode::EncodeAsType, + parity_scale_codec::Encode, + parity_scale_codec::Decode, +)] +pub struct ApplyArgs { + pub operations: OperationSubmission, +} + +#[async_trait::async_trait] +impl LedgerTransaction for ChronicleTransaction { + type Error = Infallible; + type Payload = ApplyArgs; + + async fn as_payload(&self) -> Result { + Ok(ApplyArgs { + operations: OperationSubmission { + correlation_id: self.correlation_id.into_bytes(), + identity: self.identity.clone(), + operations: self.operations.clone(), + }, + }) + } + + fn correlation_id(&self) -> [u8; 16] { + self.correlation_id.into_bytes() + } +} + +///Subxt signer needs to be infallible, so we need to keep a copy of key material here +impl Signer for ChronicleTransaction +where + C: subxt::Config< + AccountId = AccountId32, + Address = MultiAddress, + Signature = MultiSignature, + >, +{ + // The account id for an ecdsa key is the blake2_256 hash of the compressed public key + fn account_id(&self) -> AccountId32 { + AccountId32::from(blake2_256(&self.key.public().0)) + } + + fn address(&self) -> MultiAddress<::AccountId, ()> { + MultiAddress::Id(>::account_id(self)) + } + + fn sign(&self, signer_payload: &[u8]) -> MultiSignature { + self.key.sign(signer_payload).into() + } +} + +#[async_trait::async_trait] +pub trait SettingsLoader { + async fn load_settings_from_storage(&self) -> Result, SubxtClientError>; +} + +pub type ChronicleSubstrateClient = + SubstrateClient, ChronicleTransaction>; + +#[async_trait::async_trait] +impl SettingsLoader for ChronicleSubstrateClient +where + C: subxt::Config, +{ + async fn load_settings_from_storage(&self) -> Result, SubxtClientError> { + tracing::debug!("Loading OPA settings from storage."); + let call = subxt::dynamic::runtime_api_call( + "Chronicle", + "get_opa_settings", + Composite::unnamed(vec![]), + ); + let settings: Option = self + .client + .runtime_api() + .at_latest() + .await? + .call(call) + .await + .map_err(SubxtClientError::from) + .and_then(|r| r.as_type::>().map_err(SubxtClientError::from))?; + + Ok(settings) + } +} + +#[cfg(test)] +pub mod test_runtime { + use chronicle_signing::{ + chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, + CHRONICLE_NAMESPACE, + }; + use common::identity::SignedIdentity; + use pallet_chronicle::{ + operations::{ChronicleOperation, CreateNamespace}, + ExternalId, NamespaceId, + }; + use subxt::{ + ext::sp_core::{Pair, Public}, + PolkadotConfig, + }; + use uuid::Uuid; + + fn get_from_seed(seed: &str) -> [u8; 32] { + let k = TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed"); + let mut buf = [0; 32]; + buf.copy_from_slice(&k.to_raw_vec()); + + buf + } + + #[tokio::test] + pub async fn connect() { + use protocol_abstract::{LedgerReader, LedgerWriter}; + //chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); + let handle = embedded_substrate::shared_dev_node_rpc_on_port(2003, true).await.unwrap(); + + let client = handle.connect_chronicle::().await.unwrap(); + + let mut events = + client.state_updates(protocol_abstract::FromBlock::Head, None).await.unwrap(); + + let signing = ChronicleSigning::new( + chronicle_secret_names(), + vec![ + ( + CHRONICLE_NAMESPACE.to_string(), + ChronicleSecretsOptions::seeded( + vec![( + "chronicle-pk".to_string(), + get_from_seed::("Chronicle"), + )] + .into_iter() + .collect(), + ), + ), + ( + BATCHER_NAMESPACE.to_string(), + ChronicleSecretsOptions::seeded( + vec![( + "batcher-pk".to_string(), + get_from_seed::("Chronicle"), + )] + .into_iter() + .collect(), + ), + ), + ], + ) + .await + .unwrap(); + + let (submit, id) = client + .pre_submit( + super::ChronicleTransaction::new( + &signing, + SignedIdentity::new_no_identity(), + vec![ChronicleOperation::CreateNamespace(CreateNamespace::new( + NamespaceId::from_external_id(&ExternalId::from("test"), Uuid::default()), + ))], + ) + .await + .unwrap(), + ) + .await + .unwrap(); + + let res = client.do_submit(submit).await.unwrap(); + + let (ev, id, block, pos, _) = events.next().await.unwrap(); + + match ev { + crate::subxt_client::ChronicleEvent::Committed { diff, .. } => { + tracing::info!("{:?}", diff) + }, + crate::subxt_client::ChronicleEvent::Contradicted { .. } => panic!("Contradicted"), + } + } +} diff --git a/crates/opa-tp-protocol/Cargo.toml b/crates/protocol-substrate-opa/Cargo.toml similarity index 60% rename from crates/opa-tp-protocol/Cargo.toml rename to crates/protocol-substrate-opa/Cargo.toml index b43e68b2e..c520cbe6b 100644 --- a/crates/opa-tp-protocol/Cargo.toml +++ b/crates/protocol-substrate-opa/Cargo.toml @@ -1,33 +1,33 @@ [package] -build = "build.rs" edition = "2021" -name = "opa-tp-protocol" +name = "protocol-substrate-opa" version = "0.7.5" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -async-stl-client = { workspace = true } async-trait = { workspace = true } chronicle-signing = { workspace = true } derivative = { workspace = true } futures = { workspace = true } hex = { workspace = true } -k256 = { workspace = true } lazy_static = { workspace = true } -openssl = { workspace = true } -prost = { workspace = true } -prost-types = { workspace = true } +opa = { git = "https://github.com/chronicleworks/opa-rs", rev = "9fa2fbce" } rand = { workspace = true } rand_core = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } +subxt = { version = "0.32", features = ["substrate-compat"] } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } uuid = { workspace = true } -zmq = { workspace = true } + +#Local dependencies +common = { path = "../common", features = ["parity-encoding", "std"] } +pallet-opa = { path = "../pallet-opa", default-features = false } +protocol-abstract = { path = "../protocol-abstract" } +protocol-substrate = { path = "../protocol-substrate" } [build-dependencies] -glob = { workspace = true } -prost-build = { workspace = true } +glob = { workspace = true } diff --git a/crates/protocol-substrate-opa/src/lib.rs b/crates/protocol-substrate-opa/src/lib.rs new file mode 100644 index 000000000..08b49296c --- /dev/null +++ b/crates/protocol-substrate-opa/src/lib.rs @@ -0,0 +1,103 @@ +#![cfg_attr(feature = "strict", deny(warnings))] + +use std::marker::PhantomData; + +use pallet_opa::ChronicleTransactionId; +use protocol_abstract::{LedgerEvent, LedgerEventCodec, Span}; +use protocol_substrate::{SubstrateClient, SubxtClientError}; +use subxt::ext::codec::Decode; +use transaction::OpaTransaction; +//pub mod submission; +pub mod loader; +pub mod transaction; + +pub use subxt::ext::sp_core::blake2_128 as policy_hash; + +pub struct OpaEventCodec +where + C: subxt::Config, +{ + _p: PhantomData, +} + +//This type must match pallet::Event but we cannot reference it directly +pub enum OpaEvent { + PolicyUpdate(common::opa::PolicyMeta, ChronicleTransactionId), + KeyUpdate(common::opa::Keys, ChronicleTransactionId), +} + +impl OpaEvent { + fn new_policy_update( + policy_meta: common::opa::PolicyMeta, + transaction_id: ChronicleTransactionId, + ) -> Self { + OpaEvent::PolicyUpdate(policy_meta, transaction_id) + } + + fn new_key_update(keys: common::opa::Keys, transaction_id: ChronicleTransactionId) -> Self { + OpaEvent::KeyUpdate(keys, transaction_id) + } +} + +fn extract_event( + event: subxt::events::EventDetails, +) -> Result, SubxtClientError> +where + C: subxt::Config, +{ + type PolicyUpdate = (common::opa::codec::PolicyMetaV1, ChronicleTransactionId); + type KeyUpdate = (common::opa::codec::KeysV1, ChronicleTransactionId); + match (event.pallet_name(), event.variant_name(), event.field_bytes()) { + ("Opa", "PolicyUpdate", mut event_bytes) => match PolicyUpdate::decode(&mut event_bytes) { + Ok((meta, correlation_id)) => + Ok(Some(OpaEvent::new_policy_update(meta.try_into()?, correlation_id))), + Err(e) => { + tracing::error!("Failed to decode ProvModel: {}", e); + Err(e.into()) + }, + }, + ("Chronicle", "KeyUpdate", mut event_bytes) => match KeyUpdate::decode(&mut event_bytes) { + Ok((keys, correlation_id)) => + Ok(OpaEvent::new_key_update(keys.try_into()?, correlation_id).into()), + Err(e) => { + tracing::error!("Failed to decode Contradiction: {}", e); + Err(e.into()) + }, + }, + (_pallet, _event, _) => Ok(None), + } +} + +#[async_trait::async_trait] +impl LedgerEventCodec for OpaEventCodec +where + C: subxt::Config, +{ + type Error = SubxtClientError; + type Sink = OpaEvent; + type Source = subxt::events::EventDetails; + + async fn maybe_deserialize( + source: Self::Source, + ) -> Result, Self::Error> + where + Self: Sized, + { + match extract_event(source) { + Ok(Some(ev)) => Ok(Some((ev, Span::NotTraced))), + Ok(None) => Ok(None), + Err(e) => Err(e), + } + } +} + +impl LedgerEvent for OpaEvent { + fn correlation_id(&self) -> [u8; 16] { + match self { + Self::PolicyUpdate(_, correlation_id, ..) => **correlation_id, + Self::KeyUpdate(_, correlation_id, ..) => **correlation_id, + } + } +} + +pub type OpaSubstrateClient = SubstrateClient, OpaTransaction>; diff --git a/crates/protocol-substrate-opa/src/loader.rs b/crates/protocol-substrate-opa/src/loader.rs new file mode 100644 index 000000000..4ef820f38 --- /dev/null +++ b/crates/protocol-substrate-opa/src/loader.rs @@ -0,0 +1,124 @@ +use common::opa::{ + codec::PolicyV1, + std::{PolicyLoader, PolicyLoaderError}, + OpaSettings, +}; +use opa::bundle::Bundle; +use protocol_substrate::{SubstrateClient, SubxtClientError}; +use subxt::{ + ext::{scale_value::Composite, sp_core::blake2_128}, + PolkadotConfig, +}; +use tracing::{debug, error, info, instrument, warn}; + +use crate::{transaction::OpaTransaction, OpaEventCodec, OpaSubstrateClient}; + +pub struct SubstratePolicyLoader { + settings: OpaSettings, + policy: Option>, + client: OpaSubstrateClient, + addr_string: String, +} + +impl SubstratePolicyLoader { + pub fn new( + settings: OpaSettings, + client: &SubstrateClient, OpaTransaction>, + ) -> Self { + Self { + addr_string: settings.policy_address.to_string(), + settings, + policy: None, + client: client.clone(), + } + } + + #[instrument(level = "debug", skip(self), fields(policy_address = %self.settings.policy_address, entrypoint = %self.settings.entrypoint))] + async fn load_bundle_from_chain(&mut self) -> Result, SubxtClientError> { + if let Some(policy) = self.policy.as_ref() { + return Ok(policy.clone()); + } + let load_policy_from = self.settings.policy_address; + debug!(policy_address=?load_policy_from, "Loading policy from address"); + let load_policy_from = subxt::ext::scale_value::serde::to_value(load_policy_from)?; + loop { + tracing::debug!(target: "protocol_substrate_opa::loader", "Loading policy from storage."); + let call = subxt::dynamic::runtime_api_call( + "Opa", + "get_policy", + Composite::unnamed(vec![load_policy_from.clone()]), + ); + + let policy: PolicyV1 = self + .client + .client + .runtime_api() + .at_latest() + .await? + .call(call) + .await + .map_err(SubxtClientError::from) + .and_then(|r| r.as_type::().map_err(SubxtClientError::from))?; + + if let Some(policy) = Some(policy) { + return Ok(policy.into_vec()); + } else { + warn!("Policy not found, retrying in 2 seconds"); + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + continue; + } + } + } +} + +#[async_trait::async_trait] +impl PolicyLoader for SubstratePolicyLoader { + fn set_address(&mut self, _address: &str) { + unimplemented!() + } + + fn set_rule_name(&mut self, _name: &str) { + unimplemented!() + } + + fn set_entrypoint(&mut self, _entrypoint: &str) { + unimplemented!() + } + + fn get_address(&self) -> &str { + &self.addr_string + } + + fn get_rule_name(&self) -> &str { + &self.settings.policy_name + } + + fn get_entrypoint(&self) -> &str { + &self.settings.entrypoint + } + + fn get_policy(&self) -> &[u8] { + self.policy.as_ref().unwrap() + } + + async fn load_policy(&mut self) -> Result<(), PolicyLoaderError> { + let bundle = self + .load_bundle_from_chain() + .await + .map_err(|e| PolicyLoaderError::Substrate(e.into()))?; + info!(fetched_policy_bytes=?bundle.len(), "Fetched policy"); + if bundle.is_empty() { + error!("Policy not found: {}", self.get_rule_name()); + return Err(PolicyLoaderError::MissingPolicy(self.get_rule_name().to_string())); + } + self.load_policy_from_bundle(&Bundle::from_bytes(&*bundle)?) + } + + fn load_policy_from_bytes(&mut self, policy: &[u8]) { + self.policy = Some(policy.to_vec()) + } + + fn hash(&self) -> String { + hex::encode(blake2_128(self.policy.as_ref().unwrap())) + } +} diff --git a/crates/opa-tp-protocol/src/submission.rs b/crates/protocol-substrate-opa/src/submission_builder.rs similarity index 68% rename from crates/opa-tp-protocol/src/submission.rs rename to crates/protocol-substrate-opa/src/submission_builder.rs index 6724eaa6d..a5acd0f0d 100644 --- a/crates/opa-tp-protocol/src/submission.rs +++ b/crates/protocol-substrate-opa/src/submission_builder.rs @@ -3,7 +3,6 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::{messages, PROTOCOL_VERSION}; use chronicle_signing::{ ChronicleSigning, OpaKnownKeyNamesSigner, SecretError, WithSecret, OPA_NAMESPACE, }; @@ -13,20 +12,21 @@ use k256::{ schnorr::signature::Signer, PublicKey, }; -use prost::Message; -fn bootstrap_root(public_key: VerifyingKey) -> messages::BootstrapRoot { +fn bootstrap_root(public_key: VerifyingKey) -> pallet_opa::messages::BootstrapRoot { let public_key: PublicKey = public_key.into(); - messages::BootstrapRoot { public_key: public_key.to_public_key_pem(LineEnding::CRLF).unwrap() } + pallet_opa::messages::BootstrapRoot { + public_key: public_key.to_public_key_pem(LineEnding::CRLF).unwrap(), + } } fn register_key( id: impl AsRef, public_key: &VerifyingKey, overwrite_existing: bool, -) -> messages::RegisterKey { +) -> pallet_opa::messages::RegisterKey { let public_key: PublicKey = public_key.into(); - messages::RegisterKey { + pallet_opa::messages::RegisterKey { id: id.as_ref().to_string(), public_key: public_key.to_public_key_pem(LineEnding::CRLF).unwrap(), overwrite_existing, @@ -37,8 +37,8 @@ fn rotate_key( id: impl AsRef, old_key: &SigningKey, new_key: &SigningKey, -) -> messages::RotateKey { - let new_key_message = messages::rotate_key::NewPublicKey { +) -> pallet_opa::messages::RotateKey { + let new_key_message = pallet_opa::messages::NewPublicKey { id: id.as_ref().to_string(), public_key: new_key.to_bytes().to_vec(), }; @@ -53,7 +53,7 @@ fn rotate_key( let new_verifying_key = new_key.verifying_key(); let new_verifying_public_key: PublicKey = new_verifying_key.into(); - messages::RotateKey { + pallet_opa::messages::RotateKey { payload: Some(new_key_message), previous_signature: old_signature.to_vec(), previous_signing_key: old_verifying_public_key.to_public_key_pem(LineEnding::CRLF).unwrap(), @@ -62,15 +62,15 @@ fn rotate_key( } } -fn set_policy(id: impl AsRef, policy: Vec) -> messages::SetPolicy { - messages::SetPolicy { id: id.as_ref().to_owned(), policy } +fn set_policy(id: impl AsRef, policy: Vec) -> pallet_opa::messages::SetPolicy { + pallet_opa::messages::SetPolicy { id: id.as_ref().to_owned(), policy } } enum BuildingMessage { - BootstrapRoot(messages::BootstrapRoot), - RegisterKey(messages::SignedOperation), - RotateKey(messages::SignedOperation), - SetPolicy(messages::SignedOperation), + BootstrapRoot(pallet_opa::messages::BootstrapRoot), + RegisterKey(pallet_opa::messages::SignedOperation), + RotateKey(pallet_opa::messages::SignedOperation), + SetPolicy(pallet_opa::messages::SignedOperation), } pub struct SubmissionBuilder { @@ -88,19 +88,17 @@ impl SubmissionBuilder { signer: &ChronicleSigning, overwrite_existing: bool, ) -> Result { - let operation = messages::signed_operation::Payload { - operation: Some(messages::signed_operation::payload::Operation::RegisterKey( - register_key( - id, - &signer.verifying_key(OPA_NAMESPACE, new_key).await?, - overwrite_existing, - ), - )), + let operation = pallet_opa::messages::SignedOperationPayload { + operation: Some(pallet_opa::messages::Operation::RegisterKey(register_key( + id, + &signer.verifying_key(OPA_NAMESPACE, new_key).await?, + overwrite_existing, + ))), }; let signature = signer.opa_sign(&operation.encode_to_vec()).await?; let key: PublicKey = signer.opa_verifying().await?.into(); - let signed_operation = messages::SignedOperation { + let signed_operation = pallet_opa::messages::SignedOperation { payload: Some(operation), signature: signature.to_vec(), verifying_key: key.to_public_key_pem(LineEnding::CRLF).unwrap(), @@ -133,8 +131,8 @@ impl SubmissionBuilder { let new_key = extract_key.lock().unwrap().borrow().clone().unwrap(); - let operation = messages::signed_operation::Payload { - operation: Some(messages::signed_operation::payload::Operation::RotateKey(rotate_key( + let operation = pallet_opa::messages::SignedOperationPayload { + operation: Some(pallet_opa::messages::Operation::RotateKey(rotate_key( id, &old_key, &new_key, ))), }; @@ -142,7 +140,7 @@ impl SubmissionBuilder { let signature = signer.opa_sign(&operation.encode_to_vec()).await?; let key: PublicKey = signer.opa_verifying().await?.into(); - let signed_operation = messages::SignedOperation { + let signed_operation = pallet_opa::messages::SignedOperation { payload: Some(operation), signature, verifying_key: key.to_public_key_pem(LineEnding::CRLF).unwrap(), @@ -155,15 +153,15 @@ impl SubmissionBuilder { policy: Vec, signer: &ChronicleSigning, ) -> Result { - let operation = messages::signed_operation::Payload { - operation: Some(messages::signed_operation::payload::Operation::SetPolicy(set_policy( + let operation = pallet_opa::messages::SignedOperationPayload { + operation: Some(pallet_opa::messages::SignedOperationPayload::SetPolicy(set_policy( id, policy, ))), }; let signature = signer.opa_sign(&operation.encode_to_vec()).await?; let key: PublicKey = signer.opa_verifying().await?.into(); - let signed_operation = messages::SignedOperation { + let signed_operation = pallet_opa::messages::SignedOperation { payload: Some(operation), signature, verifying_key: key.to_public_key_pem(LineEnding::CRLF).unwrap(), @@ -172,24 +170,24 @@ impl SubmissionBuilder { Ok(Self { message: Some(BuildingMessage::SetPolicy(signed_operation)) }) } - pub fn build(mut self, span_id: u64) -> messages::Submission { - let mut submission = messages::Submission::default(); + pub fn build(mut self, span_id: u64) -> pallet_opa::messages::Submission { + let mut submission = pallet_opa::messages::Submission::default(); match self.message.take().unwrap() { BuildingMessage::BootstrapRoot(message) => { - submission.payload = Some(messages::submission::Payload::BootstrapRoot(message)); + submission.payload = Some(pallet_opa::messages::Payload::BootstrapRoot(message)); }, BuildingMessage::RotateKey(message) => { - submission.payload = Some(messages::submission::Payload::SignedOperation(message)); + submission.payload = Some(pallet_opa::messages::Payload::SignedOperation(message)); }, BuildingMessage::SetPolicy(message) => { - submission.payload = Some(messages::submission::Payload::SignedOperation(message)); + submission.payload = Some(pallet_opa::messages::Payload::SignedOperation(message)); }, BuildingMessage::RegisterKey(message) => { - submission.payload = Some(messages::submission::Payload::SignedOperation(message)); + submission.payload = Some(pallet_opa::messages::Payload::SignedOperation(message)); }, }; submission.span_id = span_id; - submission.version = PROTOCOL_VERSION.to_string(); + submission.version = "1.0"; submission } diff --git a/crates/protocol-substrate-opa/src/transaction.rs b/crates/protocol-substrate-opa/src/transaction.rs new file mode 100644 index 000000000..be7b21e40 --- /dev/null +++ b/crates/protocol-substrate-opa/src/transaction.rs @@ -0,0 +1,87 @@ +use chronicle_signing::{ChronicleSigning, SecretError}; +use common::opa::{codec::OpaSubmissionV1, OpaSubmission}; +use protocol_abstract::LedgerTransaction; + +#[derive(Debug, Clone)] +pub enum OpaTransaction { + BootstrapRoot(OpaSubmission, ChronicleSigning), + RotateRoot(OpaSubmission, ChronicleSigning), + RegisterKey(OpaSubmission, ChronicleSigning, String, bool), + RotateKey(OpaSubmission, ChronicleSigning, String), + SetPolicy(OpaSubmission, ChronicleSigning, String), +} + +impl OpaTransaction { + pub fn bootstrap_root( + opa_submission: OpaSubmission, + sawtooth_signer: &ChronicleSigning, + ) -> Self { + Self::BootstrapRoot(opa_submission, sawtooth_signer.to_owned()) + } + + pub fn rotate_root(opa_submission: OpaSubmission, sawtooth_signer: &ChronicleSigning) -> Self { + Self::RotateRoot(opa_submission, sawtooth_signer.to_owned()) + } + + pub fn register_key( + name: impl AsRef, + opa_submission: OpaSubmission, + sawtooth_signer: &ChronicleSigning, + overwrite_existing: bool, + ) -> Self { + Self::RegisterKey( + opa_submission, + sawtooth_signer.to_owned(), + name.as_ref().to_owned(), + overwrite_existing, + ) + } + + pub fn rotate_key( + name: impl AsRef, + opa_submission: OpaSubmission, + sawtooth_signer: &ChronicleSigning, + ) -> Self { + Self::RegisterKey( + opa_submission, + sawtooth_signer.to_owned(), + name.as_ref().to_owned(), + false, + ) + } + + pub fn set_policy( + name: impl AsRef, + opa_submission: OpaSubmission, + sawtooth_signer: &ChronicleSigning, + ) -> Self { + Self::SetPolicy(opa_submission, sawtooth_signer.to_owned(), name.as_ref().to_owned()) + } +} + +#[async_trait::async_trait] +impl LedgerTransaction for OpaTransaction { + type Error = SecretError; + type Payload = OpaSubmissionV1; + + async fn as_payload(&self) -> Result { + Ok(match self.clone() { + OpaTransaction::BootstrapRoot(o, _) => o, + OpaTransaction::RotateRoot(o, _) => o, + OpaTransaction::RegisterKey(o, _, _, _) => o, + OpaTransaction::RotateKey(o, _, _) => o, + OpaTransaction::SetPolicy(o, _, _) => o, + } + .into()) + } + + fn correlation_id(&self) -> [u8; 16] { + match self { + OpaTransaction::BootstrapRoot(o, _) => o.correlation_id, + OpaTransaction::RotateRoot(o, _) => o.correlation_id, + OpaTransaction::RegisterKey(o, _, _, _) => o.correlation_id, + OpaTransaction::RotateKey(o, _, _) => o.correlation_id, + OpaTransaction::SetPolicy(o, _, _) => o.correlation_id, + } + } +} diff --git a/crates/protocol-substrate/Cargo.toml b/crates/protocol-substrate/Cargo.toml new file mode 100644 index 000000000..ef5e4d346 --- /dev/null +++ b/crates/protocol-substrate/Cargo.toml @@ -0,0 +1,26 @@ +[package] +edition = "2021" +name = "protocol-substrate" +version = "0.1.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +async-trait = { workspace = true } +derivative = { workspace = true } +futures = { workspace = true } +hex = { workspace = true } +k256 = { workspace = true } +serde = { workspace = true } +subxt = { version = "0.32", features = ["substrate-compat"] } +thiserror = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +uuid = { workspace = true } + +# Local dependencies +chronicle-signing = { path = "../chronicle-signing" } +common = { path = "../common", features = ["parity-encoding", "std"] } +pallet-chronicle = { path = "../pallet-chronicle", features = ["std"] } +protocol-abstract = { path = "../protocol-abstract" } diff --git a/crates/protocol-substrate/src/lib.rs b/crates/protocol-substrate/src/lib.rs new file mode 100644 index 000000000..02d2e7d68 --- /dev/null +++ b/crates/protocol-substrate/src/lib.rs @@ -0,0 +1,4 @@ +mod subxt_client; + +pub use subxt::PolkadotConfig; +pub use subxt_client::*; diff --git a/crates/protocol-substrate/src/subxt_client.rs b/crates/protocol-substrate/src/subxt_client.rs new file mode 100644 index 000000000..adf5cef65 --- /dev/null +++ b/crates/protocol-substrate/src/subxt_client.rs @@ -0,0 +1,581 @@ +use std::{convert::Infallible, marker::PhantomData, net::SocketAddr, time::Duration}; + +use derivative::Derivative; +use futures::{ + stream::{self, BoxStream}, + StreamExt, TryFutureExt, TryStreamExt, +}; + +use pallet_chronicle::ChronicleTransactionId; +use subxt::{ + backend::BackendExt, + config::ExtrinsicParams, + error::MetadataError, + ext::{ + codec::{Decode, Encode}, + sp_core::{twox_128, H256}, + }, + metadata::{ + types::{PalletMetadata, StorageEntryMetadata, StorageEntryType}, + DecodeWithMetadata, + }, + storage::{DynamicAddress, StorageAddress}, + tx::{Payload, SubmittableExtrinsic}, + utils::{AccountId32, MultiAddress, MultiSignature}, + Metadata, OnlineClient, +}; + +pub use subxt::Config; + +use protocol_abstract::{ + BlockId, FromBlock, LedgerEvent, LedgerEventCodec, LedgerEventContext, LedgerReader, + LedgerTransaction, LedgerWriter, Position, RetryLedger, +}; + +#[derive(Derivative)] +#[derivative(Clone(bound = ""))] +pub struct SubstrateClient { + pub client: OnlineClient, + _p: PhantomData<(EC, T)>, +} + +impl SubstrateClient +where + // Constraint for the client configuration + C: subxt::Config< + Hash = subxt::utils::H256, /* Specifies the hash type used by the blockchain - polkadot + * default */ + Address = MultiAddress, /* Specifies the address format as polkadot + * defaults */ + Signature = MultiSignature, // Specifies the signature format - polkadot default + >, + // Ensures that the extrinsic parameters can be defaulted + >::OtherParams: Default, + // LedgerTransaction trait bound with Send and Sync for multi-threaded usage + T: LedgerTransaction + Send + Sync, + // Ensures that the payload of the transaction can be encoded as fields + ::Payload: subxt::ext::scale_encode::EncodeAsFields, + // LedgerEventCodec trait bound with Send and Sync for multi-threaded usage + EC: LedgerEventCodec + Send + Sync, +{ + pub async fn connect(url: impl AsRef) -> Result { + Ok(Self { client: OnlineClient::from_url(url).await?, _p: Default::default() }) + } + + pub async fn connect_socket_addr(socket: SocketAddr) -> Result { + tracing::info!("Connecting to Substrate client via SocketAddr: {:?}", socket); + let client_result = OnlineClient::from_url(socket.to_string()).await; + match client_result { + Ok(client) => { + tracing::info!("Successfully connected to Substrate client."); + Ok(Self { client, _p: Default::default() }) + }, + Err(e) => { + tracing::error!("Failed to connect to Substrate client: {:?}", e); + Err(SubxtClientError::from(e)) + }, + } + } + + pub fn retry(&self, duration: Duration) -> RetryLedger + where + Self: LedgerReader + Sized, + { + tracing::debug!(target: "substrate_client", "Creating a retryable ledger reader."); + RetryLedger::new(self.clone(), duration) + } + + // TODO: bring the pallet / call name in from trait + + #[tracing::instrument(level="trace" , skip(self, signer, correlation_id, operations), fields(correlation_id = %hex::encode(correlation_id), ret))] + pub async fn create_extrinsic + Send>( + &self, + signer: &S, + correlation_id: [u8; 16], + operations: &T, + ) -> Result<(SubmittableExtrinsic>, [u8; 16]), subxt::Error> { + let payload = Payload::new("Chronicle", "apply", operations.as_payload().await.unwrap()); + + self.client + .tx() + .create_signed(&payload, signer, Default::default()) + .await + .map(|extrinsic| (extrinsic, correlation_id)) + } + + pub async fn send_extrinsic( + &self, + extrinsic: (SubmittableExtrinsic>, [u8; 16]), + ) -> Result { + extrinsic + .0 + .submit_and_watch() + .and_then(|progress| progress.wait_for_finalized_success()) + .await + .map(|_| extrinsic.1.into()) + .map_err(|e| (e, ChronicleTransactionId::from(extrinsic.1))) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum SubxtClientError { + #[error("Subxt error: {0}")] + SubxtError(#[from] subxt::Error), + + #[error("Invalid block")] + InvalidBlock, + + #[error("Codec: {0}")] + Codec(#[from] subxt::ext::codec::Error), + + #[error("Decode: {0}")] + Decode(#[from] subxt::error::DecodeError), + + #[error("Serde: {0}")] + Serde(#[from] subxt::ext::scale_value::serde::SerializerError), +} + +impl From for SubxtClientError { + fn from(_value: Infallible) -> Self { + unreachable!() + } +} + +impl SubstrateClient +where + C: subxt::Config, + H: subxt::config::Header + Send + Sync + Decode + Encode, + EC: LedgerEventCodec> + + Send + + Sync, + T: LedgerTransaction + Send + Sync, +{ + // Return child blocks of from_block, limiting to num_blocks if not none + async fn block_hashes_from( + &self, + from_block: C::Hash, + num_blocks: Option, + ) -> Result>, SubxtClientError> { + // Get the block at hash + let block = self.client.blocks().at(from_block).await?; + + let from_block_num = block.number(); + + let hashes = stream::unfold( + (self.client.clone(), from_block_num), + move |(client, block_num)| async move { + if let Some(num_blocks) = num_blocks { + if num_blocks == block_num { + return None; + } + } + + let block_hash: Result = client + .backend() + .call_decoding( + "chain_getBlockHash", + Some(&vec![block_num].encode()), + subxt::utils::H256::zero(), + ) + .await + .map_err(SubxtClientError::from); + + Some((block_hash, (client, block_num + 1))) + }, + ); + + Ok(Box::pin(hashes)) + } + + // Return events from `number_of_blocks` blocks from the client, starting at `from_block` + async fn events_for_block( + &self, + from_block: C::Hash, + ) -> Result::Sink>>, SubxtClientError> { + let header = self.client.backend().block_header(from_block).await?; + let block_num = match header { + Some(header) => Ok(header.number()), + None => { + tracing::error!("Block header is None"); + Err(SubxtClientError::InvalidBlock) + }, + }?; + + let events_for_block = match self.client.events().at(from_block).await { + Ok(events) => Ok(events), + Err(e) => { + tracing::error!("Failed to get events for block: {}", e); + Err(SubxtClientError::InvalidBlock) + }, + }?; + + let events_for_block = + stream::unfold(events_for_block.iter(), |mut events_for_block| async move { + match events_for_block.next() { + Some(Ok(event)) => match EC::maybe_deserialize(event).await { + Ok(Some(event)) => Some((event, events_for_block)), + _ => None, + }, + Some(Err(e)) => { + tracing::error!("Cannot fetch event {}", e); + None + }, + _ => None, + } + }); + + let event_stream = events_for_block.map(move |(event, span)| { + let correlation_id = event.correlation_id(); + ( + event, + ChronicleTransactionId::from(correlation_id), + BlockId::Block(from_block), + Position::from(block_num), + span, + ) + }); + + Ok(event_stream.boxed()) + } + + async fn stream_finalized_events( + &self, + ) -> Result::Sink>>, SubxtClientError> { + let blocks = self.client.blocks().subscribe_finalized().await?; + + let parsed_events = blocks + .map_err(SubxtClientError::from) + .and_then(|block| async move { + let block_num = block.number(); + let block_hash = block.hash(); + + let events = block.events().await.map_err(SubxtClientError::from); + + match events { + Err(e) => Err(e), + Ok(events) => { + let events = events + .iter() + .filter_map(|event| { + event + .map_err(SubxtClientError::from) + .and_then(|event| { + futures::executor::block_on(EC::maybe_deserialize(event)) + }) + .transpose() + .map(|event| { + event.map(|(event, span)| { + let correlation_id = event.correlation_id(); + ( + event, + ChronicleTransactionId::from(correlation_id), + BlockId::Block(block_hash), + Position::from(block_num), + span, + ) + }) + }) + }) + .collect::>(); + Ok(stream::iter(events)) + }, + } + }) + .boxed(); + + //Unfold and terminate stream on error + let flattened_stream = stream::unfold(parsed_events, |mut parsed_events| async move { + match parsed_events.next().await { + Some(Ok(events)) => Some((events, parsed_events)), + Some(Err(e)) => { + tracing::error!("Subscription error {}", e); + None + }, + _ => None, + } + }) + .flatten() + .boxed(); + + // Terminate on parse error in flattened stream, + let flattened_stream = + stream::unfold(flattened_stream, |mut flattened_stream| async move { + match flattened_stream.next().await { + Some(Err(e)) => { + tracing::error!("Event parse error {}", e); + None + }, + Some(Ok(event)) => Some((event, flattened_stream)), + None => None, + } + }) + .boxed(); + + Ok(flattened_stream) + } + + async fn historical_events( + &self, + from_block: C::Hash, + num_blocks: Option, + ) -> Result::Sink>>, SubxtClientError> { + let from_block_clone = self; + let block_hashes = from_block_clone.block_hashes_from(from_block, num_blocks).await?; + + let events = stream::unfold( + (block_hashes, self), + move |(mut block_hashes, self_clone)| async move { + let next_block_hash = block_hashes.next().await; + match next_block_hash { + Some(Ok(block_hash)) => { + let events = self_clone.events_for_block(block_hash).await; + match events { + Ok(events) => Some((events, (block_hashes, self_clone))), + Err(e) => { + tracing::error!("Subscription error {}", e); + None + }, + } + }, + Some(Err(e)) => { + tracing::error!("Subscription error {}", e); + None + }, + _ => None, + } + }, + ) + .flatten() + .boxed(); + + Ok(events) + } +} + +#[async_trait::async_trait] +impl LedgerWriter for SubstrateClient +where + C: subxt::Config< + Address = MultiAddress, + AccountId = AccountId32, + Hash = H256, + Signature = MultiSignature, + >, + >::OtherParams: Default + Send, + E: LedgerEventCodec> + Send + Sync, + T: LedgerTransaction + Send + Sync + subxt::tx::Signer, + ::Payload: subxt::ext::scale_encode::EncodeAsFields, +{ + type Error = SubxtClientError; + type Submittable = (SubmittableExtrinsic>, [u8; 16]); + type Transaction = T; + + async fn pre_submit( + &self, + tx: Self::Transaction, + ) -> Result<(Self::Submittable, ChronicleTransactionId), Self::Error> { + let correlation_id = tx.correlation_id(); + let (ext, id) = self.create_extrinsic(&tx, correlation_id, &tx).await?; + + Ok(((ext, id), id.into())) + } + + async fn do_submit( + &self, + submittable: Self::Submittable, + ) -> Result { + tracing::info!( + target: "substrate_client", + correlation_id = ?submittable.1, + "Submitting extrinsic with correlation ID." + ); + + self.send_extrinsic(submittable).await.map_err(|(e, id)| (e.into(), id)) + } +} + +#[async_trait::async_trait] +pub trait SubstrateStateReader { + type Error: std::error::Error; + /// Get the state entry at `address` + + async fn get_state_entry< + K: subxt::ext::scale_encode::EncodeAsType + Send + Sync, + V: DecodeWithMetadata, + >( + &self, + address: DynamicAddress, + ) -> Result, Self::Error>; +} + +pub(crate) fn validate_storage_address( + address: &Address, + pallet: PalletMetadata<'_>, +) -> Result<(), subxt::Error> { + if let Some(hash) = address.validation_hash() { + validate_storage(pallet, address.entry_name(), hash)?; + } + Ok(()) +} + +/// Return details about the given storage entry. +fn lookup_entry_details<'a>( + pallet_name: &str, + entry_name: &str, + metadata: &'a Metadata, +) -> Result<(PalletMetadata<'a>, &'a StorageEntryMetadata), subxt::Error> { + let pallet_metadata = metadata.pallet_by_name_err(pallet_name)?; + let storage_metadata = pallet_metadata + .storage() + .ok_or_else(|| MetadataError::StorageNotFoundInPallet(pallet_name.to_owned()))?; + let storage_entry = storage_metadata + .entry_by_name(entry_name) + .ok_or_else(|| MetadataError::StorageEntryNotFound(entry_name.to_owned()))?; + Ok((pallet_metadata, storage_entry)) +} + +/// Validate a storage entry against the metadata. +fn validate_storage( + pallet: PalletMetadata<'_>, + storage_name: &str, + hash: [u8; 32], +) -> Result<(), subxt::Error> { + let Some(expected_hash) = pallet.storage_hash(storage_name) else { + return Err(MetadataError::IncompatibleCodegen.into()); + }; + if expected_hash != hash { + return Err(MetadataError::IncompatibleCodegen.into()); + } + Ok(()) +} + +/// Fetch the return type out of a [`StorageEntryType`]. +fn return_type_from_storage_entry_type(entry: &StorageEntryType) -> u32 { + match entry { + StorageEntryType::Plain(ty) => *ty, + StorageEntryType::Map { value_ty, .. } => *value_ty, + } +} + +/// Given some bytes, a pallet and storage name, decode the response. +fn decode_storage_with_metadata( + bytes: &mut &[u8], + metadata: &Metadata, + storage_metadata: &StorageEntryMetadata, +) -> Result { + let ty = storage_metadata.entry_type(); + let return_ty = return_type_from_storage_entry_type(ty); + let val = T::decode_with_metadata(bytes, return_ty, metadata)?; + Ok(val) +} + +pub(crate) fn write_storage_address_root_bytes( + addr: &Address, + out: &mut Vec, +) { + out.extend(twox_128(addr.pallet_name().as_bytes())); + out.extend(twox_128(addr.entry_name().as_bytes())); +} + +pub(crate) fn storage_address_bytes( + addr: &Address, + metadata: &Metadata, +) -> Result, subxt::Error> { + let mut bytes = Vec::new(); + write_storage_address_root_bytes(addr, &mut bytes); + addr.append_entry_bytes(metadata, &mut bytes)?; + Ok(bytes) +} + +#[async_trait::async_trait] +impl SubstrateStateReader for SubstrateClient +where + C: subxt::Config, + EC: LedgerEventCodec + Send + Sync, + T: protocol_abstract::LedgerTransaction + Send + Sync, +{ + type Error = SubxtClientError; + + async fn get_state_entry< + K: subxt::ext::scale_encode::EncodeAsType + Send + Sync, + V: DecodeWithMetadata, + >( + &self, + address: DynamicAddress, + ) -> Result, Self::Error> { + let metadata = self.client.metadata(); + let (pallet, entry) = + lookup_entry_details(address.pallet_name(), address.entry_name(), &metadata)?; + + // Metadata validation checks whether the static address given + // is likely to actually correspond to a real storage entry or not. + // if not, it means static codegen doesn't line up with runtime + // metadata. + validate_storage_address(&address, pallet)?; + + // Look up the return type ID to enable DecodeWithMetadata: + let lookup_bytes = storage_address_bytes(&address, &metadata)?; + if let Some(data) = self.client.storage().at_latest().await?.fetch_raw(lookup_bytes).await? + { + let val = decode_storage_with_metadata::(&mut &*data, &metadata, entry)?; + Ok(Some(val)) + } else { + Ok(None) + } + } +} + +#[async_trait::async_trait] +impl LedgerReader for SubstrateClient +where + C: subxt::Config, + H: subxt::config::Header + Decode + Encode + Send + Sync, + EC: LedgerEventCodec> + + Send + + Sync, + T: LedgerTransaction + Send + Sync, +{ + type Error = SubxtClientError; + type Event = ::Sink; + type EventCodec = EC; + + // Get the block height of the ledger, and the id of the highest block + async fn block_height(&self) -> Result<(Position, BlockId), Self::Error> { + let block = self.client.blocks().at_latest().await?; + + Ok((Position::from(block.number()), BlockId::from(block.hash()))) + } + + /// Subscribe to state updates from this ledger, starting at `offset`, and + /// ending the stream after `number_of_blocks` blocks have been processed. + async fn state_updates( + &self, + // The block to start from + from_block: FromBlock, + // The number of blocks to process before ending the stream + number_of_blocks: Option, + ) -> Result>, Self::Error> { + // If fromblock is not head, then load in historical blocks and yield up to number_of_blocks + // events + let historical = match from_block { + FromBlock::Head => stream::empty().boxed(), + FromBlock::First => self + .historical_events(self.client.backend().genesis_hash().await?, number_of_blocks) + .await? + .boxed(), + FromBlock::BlockId(BlockId::Block(hash)) => { + self.historical_events(hash, number_of_blocks).await?.boxed() + }, + FromBlock::BlockId(BlockId::Unknown) => self + .historical_events(self.client.backend().genesis_hash().await?, number_of_blocks) + .await? + .boxed(), + }; + + let all = historical.chain(self.stream_finalized_events().await?); + + //TODO: only take number_of_blocks worth of events before closing the stream + + Ok(all.boxed()) + } +} diff --git a/crates/runtime-api-chronicle/Cargo.toml b/crates/runtime-api-chronicle/Cargo.toml new file mode 100644 index 000000000..cef0b2de0 --- /dev/null +++ b/crates/runtime-api-chronicle/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "runtime-api-chronicle" +version = "1.0.0" +edition = "2021" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +sp-api = { version = "23.0.0", default-features = false } +sp-core = { version = "25.0.0", default-features = false } + +#Local dependencies +common = {path="../common", default-features=false, features=["parity-encoding"]} + +[features] +default = ["std"] +std = [ + "sp-api/std", + "common/std" +] diff --git a/crates/runtime-api-chronicle/src/lib.rs b/crates/runtime-api-chronicle/src/lib.rs new file mode 100644 index 000000000..cdcb71087 --- /dev/null +++ b/crates/runtime-api-chronicle/src/lib.rs @@ -0,0 +1,14 @@ +#![cfg_attr(not(feature = "std"), no_std)] +pub type Hash = sp_core::H256; + +pub mod chronicle_core { + pub use common::*; +} + +// Here we declare the runtime API. It is implemented it the `impl` block in +// runtime file (the `runtime/src/lib.rs`) +sp_api::decl_runtime_apis! { + pub trait ChronicleApi { + fn placeholder() -> u32; + } +} diff --git a/crates/sawtooth-tp/Cargo.toml b/crates/sawtooth-tp/Cargo.toml deleted file mode 100644 index 4d844c826..000000000 --- a/crates/sawtooth-tp/Cargo.toml +++ /dev/null @@ -1,57 +0,0 @@ -[[bin]] -name = "chronicle_sawtooth_tp" -path = "src/main.rs" - -[lib] -name = "chronicle_sawtooth_tp" -path = "src/lib.rs" - -[package] -build = "build.rs" -edition = "2021" -name = "sawtooth_tp" -version = "0.7.5" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -async-stl-client = { workspace = true } -async-trait = { workspace = true } -bytes = { workspace = true } -chronicle-protocol = { path = "../chronicle-protocol" } -chronicle-signing = { workspace = true } -chronicle-telemetry = { path = "../chronicle-telemetry" } -clap = { workspace = true } -common = { path = "../common" } -const_format = { workspace = true } -custom_error = { workspace = true } -derivative = { workspace = true } -futures = { workspace = true } -glob = { workspace = true } -hex = { workspace = true } -lazy_static = { workspace = true } -opa-tp-protocol = { path = "../opa-tp-protocol" } -openssl = { workspace = true } -opentelemetry = { workspace = true } -prost = { workspace = true } -protobuf = { workspace = true } -rand = { workspace = true } -rand_core = { workspace = true } -sawtooth-sdk = { workspace = true } -serde = { workspace = true } -serde_derive = { workspace = true } -serde_json = { workspace = true } -tokio = { workspace = true } -tracing = { workspace = true } -url = { workspace = true } -uuid = { workspace = true } -zmq = { workspace = true } - -[build-dependencies] -glob = { workspace = true } - -[dev-dependencies] -chrono = { workspace = true } -insta = { workspace = true, features = ["yaml"] } -protobuf = { workspace = true } -tempfile = { workspace = true } diff --git a/crates/sawtooth-tp/build.rs b/crates/sawtooth-tp/build.rs deleted file mode 100644 index afb2c9546..000000000 --- a/crates/sawtooth-tp/build.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - //Create a .VERSION file containing 'local' if it does not exist - - let version_file = std::path::Path::new("../../.VERSION"); - if !version_file.exists() { - std::fs::write(version_file, "local").expect("Unable to write file"); - } -} diff --git a/crates/sawtooth-tp/src/abstract_tp.rs b/crates/sawtooth-tp/src/abstract_tp.rs deleted file mode 100644 index 076921ca7..000000000 --- a/crates/sawtooth-tp/src/abstract_tp.rs +++ /dev/null @@ -1,100 +0,0 @@ -use chronicle_protocol::{address::SawtoothAddress, protocol::messages::Submission}; -use common::{ - identity::SignedIdentity, - ledger::OperationState, - opa::ExecutorContext, - prov::{operations::ChronicleOperation, ChronicleTransaction}, -}; -use sawtooth_sdk::{ - messages::processor::TpProcessRequest, - processor::handler::{ApplyError, ContextError, TransactionContext}, -}; -use tracing::instrument; -// Sawtooth's &mut dyn TransactionContext is highly inconvenient to work with in -// an async environment, so we will use an effects model instead, -// TP inputs can be determined synchronously, so we split processing into a sync -// and async part which returns effects -#[async_trait::async_trait] -pub trait TP { - fn tp_parse(request: &TpProcessRequest) -> Result; - fn tp_state( - context: &mut dyn TransactionContext, - operations: &ChronicleTransaction, - ) -> Result, ApplyError>; - async fn tp_operations(request: Submission) -> Result; - async fn tp( - opa_executor: ExecutorContext, - request: &TpProcessRequest, - submission: Submission, - operations: ChronicleTransaction, - state: OperationState, - ) -> Result; - async fn enforce_opa( - opa_executor: ExecutorContext, - identity: &SignedIdentity, - operation: &ChronicleOperation, - state: &OperationState, - ) -> Result<(), ApplyError>; -} - -#[derive(Debug)] -pub enum TPSideEffect { - SetState { address: String, value: Vec }, - AddEvent { event_type: String, attributes: Vec<(String, String)>, data: Vec }, -} - -pub struct TPSideEffects { - effects: Vec, -} - -impl TPSideEffects { - pub fn new() -> Self { - Self { effects: vec![] } - } - - #[instrument(name = "set_state_entry", level = "trace", skip(self, data))] - pub fn set_state_entry(&mut self, address: String, data: Vec) { - self.effects.push(TPSideEffect::SetState { address, value: data }); - } - - #[instrument(name = "add_event", level = "trace", skip(self, data))] - pub fn add_event( - &mut self, - event_type: String, - attributes: Vec<(String, String)>, - data: Vec, - ) { - self.effects.push(TPSideEffect::AddEvent { event_type, attributes, data }); - } - - #[instrument(name = "apply_effects", level = "trace", skip(self, ctx), fields (effects = ?self.effects))] - pub fn apply(self, ctx: &mut dyn TransactionContext) -> Result<(), ContextError> { - for effect in self.effects.into_iter() { - match effect { - TPSideEffect::SetState { address, value } => { - ctx.set_state_entry(address.clone(), value.clone())?; - }, - TPSideEffect::AddEvent { event_type, attributes, data } => { - ctx.add_event(event_type, attributes, data.as_slice())?; - }, - } - } - - Ok(()) - } -} - -impl Default for TPSideEffects { - fn default() -> Self { - Self::new() - } -} - -impl IntoIterator for TPSideEffects { - type IntoIter = std::vec::IntoIter; - type Item = TPSideEffect; - - fn into_iter(self) -> Self::IntoIter { - self.effects.into_iter() - } -} diff --git a/crates/sawtooth-tp/src/lib.rs b/crates/sawtooth-tp/src/lib.rs deleted file mode 100644 index 4837001c2..000000000 --- a/crates/sawtooth-tp/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Library exports for use in test and embedding contexts. -pub mod abstract_tp; -mod opa; -pub mod tp; diff --git a/crates/sawtooth-tp/src/main.rs b/crates/sawtooth-tp/src/main.rs deleted file mode 100644 index fc9cb13be..000000000 --- a/crates/sawtooth-tp/src/main.rs +++ /dev/null @@ -1,96 +0,0 @@ -mod abstract_tp; -mod tp; -use ::chronicle_telemetry::ConsoleLogging; -use chronicle_telemetry::telemetry; -use clap::{builder::PossibleValuesParser, Arg, Command, ValueHint}; -mod opa; -use sawtooth_sdk::processor::TransactionProcessor; -use tokio::runtime::Handle; -use tp::ChronicleTransactionHandler; -use tracing::info; -use url::Url; - -pub const LONG_VERSION: &str = const_format::formatcp!( - "{}:{}", - env!("CARGO_PKG_VERSION"), - include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../.VERSION")) -); - -#[tokio::main] -async fn main() { - let matches = Command::new("chronicle-sawtooth-tp") - .version(LONG_VERSION) - .author("Blockchain Technology Partners") - .about("Write and query provenance data to distributed ledgers") - .arg( - Arg::new("connect") - .short('C') - .long("connect") - .value_hint(ValueHint::Url) - .help("Sets sawtooth validator address") - .takes_value(true), - ) - .arg( - Arg::new("completions") - .long("completions") - .value_name("completions") - .value_parser(PossibleValuesParser::new(["bash", "zsh", "fish"])) - .help("Generate shell completions and exit"), - ) - .arg( - Arg::new("instrument") - .long("instrument") - .value_name("instrument") - .takes_value(true) - .value_hint(ValueHint::Url) - .help("Instrument using RUST_LOG environment"), - ) - .arg( - Arg::new("console-logging") - .long("console-logging") - .value_name("console-logging") - .takes_value(true) - .default_value("pretty") - .help("Log to console using RUST_LOG environment"), - ) - .get_matches(); - - telemetry( - matches.get_one::("instrument").and_then(|s| Url::parse(s).ok()), - match matches.get_one::("console-logging") { - Some(level) => match level.as_str() { - "pretty" => ConsoleLogging::Pretty, - "json" => ConsoleLogging::Json, - _ => ConsoleLogging::Off, - }, - _ => ConsoleLogging::Off, - }, - ); - - info!(chronicle_tp_version = LONG_VERSION); - - let (bootstrap_policy, bootstrap_entrypoint) = - ("allow_transactions", "allow_transactions.allowed_users"); - - Handle::current().spawn_blocking(move || { - info!( - "Starting Chronicle Transaction Processor on {:?}", - matches.get_one::("connect") - ); - let handler = match ChronicleTransactionHandler::new(bootstrap_policy, bootstrap_entrypoint) - { - Ok(handler) => handler, - Err(e) => panic!("Error initializing TransactionHandler: {e}"), - }; - let mut processor = TransactionProcessor::new({ - if let Some(connect) = matches.get_one::("connect") { - connect - } else { - "tcp://127.0.0.1:4004" - } - }); - - processor.add_handler(&handler); - processor.start(); - }); -} diff --git a/crates/sawtooth-tp/src/opa.rs b/crates/sawtooth-tp/src/opa.rs deleted file mode 100644 index 0063f0807..000000000 --- a/crates/sawtooth-tp/src/opa.rs +++ /dev/null @@ -1,133 +0,0 @@ -use chronicle_protocol::settings::sawtooth_settings_address; -use common::opa::{CliPolicyLoader, ExecutorContext}; -use protobuf::Message; -use sawtooth_sdk::{ - messages::setting::Setting, - processor::handler::{ApplyError, TransactionContext}, -}; -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; -use tracing::{debug, info, warn}; - -#[derive(Debug)] -pub struct TpOpa { - pub embedded: ExecutorContext, - pub on_chain: Arc>>, -} - -impl TpOpa { - pub fn new(policy: &str, entrypoint: &str) -> Result { - Ok(Self { - on_chain: Arc::new(HashMap::new().into()), - embedded: { - ExecutorContext::from_loader( - &CliPolicyLoader::from_embedded_policy(policy, entrypoint) - .map_err(|e| ApplyError::InternalError(e.to_string()))?, - ) - .map_err(|e| ApplyError::InternalError(e.to_string()))? - }, - }) - } - - pub fn executor_context( - &self, - ctx: &dyn TransactionContext, - ) -> Result { - let policy_name_settings_entry = - ctx.get_state_entry(&sawtooth_settings_address("chronicle.opa.policy_name"))?; - - let entrypoint_settings_entry = - ctx.get_state_entry(&sawtooth_settings_address("chronicle.opa.entrypoint"))?; - - match (policy_name_settings_entry, entrypoint_settings_entry) { - (None, None) => { - warn!("Insecure operating mode - no on-chain policy name or entrypoint settings found"); - Ok(self.embedded.clone()) - }, - (Some(policy_name_settings_entry), Some(entrypoint_settings_entry)) => { - info!("Chronicle operating in secure mode - on-chain policy name and entrypoint settings found"); - let policy_name_settings_entry: Setting = - Message::parse_from_bytes(&policy_name_settings_entry).map_err(|_e| { - ApplyError::InternalError("Invalid setting entry".to_string()) - })?; - let entrypoint_settings_entry: Setting = - Message::parse_from_bytes(&entrypoint_settings_entry).map_err(|_e| { - ApplyError::InternalError("Invalid setting entry".to_string()) - })?; - - let policy_name = - policy_name_settings_entry.get_entries().iter().next().ok_or_else(|| { - ApplyError::InternalError("Invalid setting entry".to_string()) - })?; - - let policy_entrypoint = - entrypoint_settings_entry.get_entries().iter().next().ok_or_else(|| { - ApplyError::InternalError("Invalid setting entry".to_string()) - })?; - - let policy_meta_address = - opa_tp_protocol::state::policy_meta_address(&policy_name.value); - - let policy_meta: Vec = - ctx.get_state_entry(&policy_meta_address)?.ok_or_else(|| { - ApplyError::InternalError(format!( - "Failed to load policy metadata for policy '{}' from '{}'", - policy_name.value, policy_meta_address - )) - })?; - - let policy_meta: opa_tp_protocol::state::PolicyMeta = - serde_json::from_slice(&policy_meta).map_err(|_e| { - ApplyError::InternalError(format!( - "Cannot parse policy meta for {}", - policy_name.value - )) - })?; - - debug!(policy_from_submission_meta = ?policy_meta); - - // Check if we have the policy loaded as an executor context and the - // loaded policy version against the current policy - // version. If either the policy is not loaded or the policy version is nor - // current, load the policy from the chain and cache it - if let Some((hash, executor_context)) = - self.on_chain.lock().unwrap().get(&policy_name.value) - { - if *hash == policy_meta.hash { - return Ok(executor_context.clone()) - } - } - - // Load the policy from the chain - let policy_bytes = ctx - .get_state_entry(&opa_tp_protocol::state::policy_address(&policy_name.value))? - .ok_or_else(|| { - ApplyError::InternalError(format!( - "Failed to load policy for policy {}", - policy_name.value - )) - })?; - - let loader = CliPolicyLoader::from_policy_bytes( - &policy_name.value, - &policy_entrypoint.value, - &policy_bytes, - ) - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - - let ctx = ExecutorContext::from_loader(&loader) - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - - self.on_chain - .lock() - .unwrap() - .insert(policy_name.value.clone(), (policy_meta.hash, ctx.clone())); - - Ok(ctx) - }, - _ => Err(ApplyError::InternalError("Opa policy settings are invalid".to_string())), - } - } -} diff --git a/crates/sawtooth-tp/src/tp.rs b/crates/sawtooth-tp/src/tp.rs deleted file mode 100644 index 6795d4816..000000000 --- a/crates/sawtooth-tp/src/tp.rs +++ /dev/null @@ -1,732 +0,0 @@ -use chronicle_protocol::protocol::{ - chronicle_committed, chronicle_contradicted, chronicle_identity_from_submission, - chronicle_operations_from_submission_v1, chronicle_operations_from_submission_v2, - deserialize_submission, messages::Submission, -}; -use common::{ - identity::{AuthId, OpaData, SignedIdentity}, - ledger::{OperationState, StateOutput, SubmissionError}, - opa::ExecutorContext, - prov::{ - operations::ChronicleOperation, to_json_ld::ToJson, ChronicleTransaction, - ChronicleTransactionId, ProcessorError, ProvModel, - }, -}; -use prost::Message; -use std::collections::{BTreeMap, HashSet}; - -use chronicle_protocol::address::{SawtoothAddress, FAMILY, PREFIX, VERSION}; - -use sawtooth_sdk::{ - messages::processor::TpProcessRequest, - processor::handler::{ApplyError, TransactionContext, TransactionHandler}, -}; -use tracing::{error, info, instrument, trace}; - -use crate::{ - abstract_tp::{TPSideEffects, TP}, - opa::TpOpa, -}; - -#[derive(Debug)] -pub struct ChronicleTransactionHandler { - family_name: String, - family_versions: Vec, - namespaces: Vec, - opa_executor: TpOpa, -} - -impl ChronicleTransactionHandler { - pub fn new(policy: &str, entrypoint: &str) -> Result { - Ok(ChronicleTransactionHandler { - family_name: FAMILY.to_owned(), - family_versions: vec![VERSION.to_owned()], - namespaces: vec![PREFIX.to_string()], - opa_executor: TpOpa::new(policy, entrypoint)?, - }) - } -} - -#[async_trait::async_trait] -impl TP for ChronicleTransactionHandler { - fn tp_parse(request: &TpProcessRequest) -> Result { - deserialize_submission(request.get_payload()) - .map_err(|e| ApplyError::InternalError(e.to_string())) - } - - fn tp_state( - context: &mut dyn TransactionContext, - operations: &ChronicleTransaction, - ) -> Result, ApplyError> { - let deps = operations.tx.iter().flat_map(|tx| tx.dependencies()).collect::>(); - - let addresses_to_load = deps.iter().map(SawtoothAddress::from).collect::>(); - - // Entries not present in state must be None - let sawtooth_entries = context - .get_state_entries( - &addresses_to_load.iter().map(|x| x.to_string()).collect::>(), - )? - .into_iter() - .map(|(addr, data)| { - (SawtoothAddress::new(addr), Some(String::from_utf8(data).unwrap())) - }) - .collect::>(); - - let mut state = OperationState::::new(); - - let not_in_sawtooth = addresses_to_load - .iter() - .filter(|required_addr| { - !sawtooth_entries.iter().any(|(addr, _)| addr == *required_addr) - }) - .map(|addr| (addr.clone(), None)) - .collect::>(); - - state.update_state(sawtooth_entries.into_iter()); - state.update_state(not_in_sawtooth.into_iter()); - - Ok(state) - } - - async fn tp_operations(submission: Submission) -> Result { - use chronicle_protocol::protocol::messages::submission::IdentityVariant; - use common::prov::{transaction, transaction::ToChronicleTransaction}; - - let identity = chronicle_identity_from_submission( - match submission - .identity_variant - .ok_or_else(|| ApplyError::InternalError("missing identity".to_string()))? - { - IdentityVariant::IdentityOld(id) => id, - IdentityVariant::Identity(id) => id.payload, - }, - ) - .await - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - match &*submission.version { - "1" => { - use transaction::v1::ChronicleTransaction; - #[allow(deprecated)] - let ops = chronicle_operations_from_submission_v1(submission.body_old) - .await - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - let tx = ChronicleTransaction::new(ops, identity); - Ok(tx.to_current()) - }, - "2" => { - use transaction::v2::ChronicleTransaction; - let ops = chronicle_operations_from_submission_v2( - match submission.body_variant.unwrap() { - chronicle_protocol::protocol::messages::submission::BodyVariant::Body( - body, - ) => body.payload, - }, - ) - .await - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - let tx = ChronicleTransaction::new(ops, identity); - Ok(tx.to_current()) - }, - v => Err(ApplyError::InternalError(format!("unknown protocol version: {v}"))), - } - } - - async fn tp( - opa_executor: ExecutorContext, - request: &TpProcessRequest, - submission: Submission, - operations: ChronicleTransaction, - mut state: OperationState, - ) -> Result { - let mut effects = TPSideEffects::new(); - - let _protocol_version = submission.version; - let span = submission.span_id; - let id = request.get_signature().to_owned(); - - info!(transaction_id = %id, span = %span, operation_count = %operations.tx.len(), identity = ?submission.identity_variant); - - //precompute dependencies - let deps = operations.tx.iter().flat_map(|tx| tx.dependencies()).collect::>(); - - let deps_as_sawtooth = deps.iter().map(SawtoothAddress::from).collect::>(); - - trace!( - input_chronicle_addresses=?deps, - ); - - let mut model = ProvModel::default(); - - // Now apply operations to the model - for operation in operations.tx { - Self::enforce_opa(opa_executor.clone(), &operations.identity, &operation, &state) - .await?; - - let res = operation.process(model, state.input()).await; - match res { - // A contradiction raises an event and shortcuts processing - Err(ProcessorError::Contradiction(source)) => { - info!(contradiction = %source); - let ev = chronicle_contradicted(span, &source, &operations.identity) - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - effects.add_event( - "chronicle/prov-update".to_string(), - vec![("transaction_id".to_owned(), request.signature.clone())], - ev.encode_to_vec(), - ); - return Ok(effects) - }, - // Severe errors should be logged - Err(e) => { - error!(chronicle_prov_failure = %e); - - return Ok(effects) - }, - Ok((tx_output, updated_model)) => { - state.update_state( - tx_output - .into_iter() - .map(|output| { - trace!(output_state = %output.data); - (SawtoothAddress::from(&output.address), Some(output.data)) - }) - .collect::>() - .into_iter(), - ); - model = updated_model; - }, - } - } - - let dirty = state.dirty().collect::>(); - - trace!(dirty = ?dirty); - - let mut delta = ProvModel::default(); - for output in dirty - .into_iter() - .map(|output: StateOutput| { - if deps_as_sawtooth.contains(&output.address) { - Ok(output) - } else { - Err(SubmissionError::processor( - &ChronicleTransactionId::from(&*id), - ProcessorError::Address {}, - )) - } - }) - .collect::, SubmissionError>>() - .into_iter() - .flat_map(|v: Vec>| v.into_iter()) - { - let state: serde_json::Value = serde_json::from_str(&output.data) - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - - delta - .apply_json_ld_str(&output.data) - .await - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - - effects.set_state_entry( - output.address.to_string(), - serde_json::to_vec(&state).map_err(|e| ApplyError::InternalError(e.to_string()))?, - ) - } - - // Finally emit the delta as an event - let ev = chronicle_committed(span, delta, &operations.identity) - .await - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - - effects.add_event( - "chronicle/prov-update".to_string(), - vec![("transaction_id".to_owned(), request.signature.clone())], - ev.encode_to_vec(), - ); - - Ok(effects) - } - - /// Get identity, the content of the compact json-ld representation of the operation, and a more - /// readable serialization of the @graph from a provmodel containing the operation's - /// dependencies and then pass them as the context to an OPA rule check, returning an error upon - /// OPA policy failure - async fn enforce_opa( - opa_executor: ExecutorContext, - identity: &SignedIdentity, - tx: &ChronicleOperation, - state: &OperationState, - ) -> Result<(), ApplyError> { - let identity = AuthId::try_from(identity) - .map_err(|e| ApplyError::InternalError(ProcessorError::SerdeJson(e).to_string()))?; - - // Set up Context for OPA rule check - let operation = - tx.to_json().compact().await.map_err(|e| { - ApplyError::InternalError(ProcessorError::Compaction(e).to_string()) - })?; - - // Get the dependencies - let deps = tx - .dependencies() - .into_iter() - .collect::>() - .iter() - .map(SawtoothAddress::from) - .collect::>(); - - let operation_state = state.opa_context(deps); - - let state = serde_json::Value::Array( - tx.opa_context_state(ProvModel::default(), operation_state) - .await - .map_err(|e| ApplyError::InternalError(e.to_string()))?, - ); - - let opa_data = OpaData::operation(&identity, &operation, &state); - - info!(opa_evaluation_context = ?opa_data); - - match opa_executor.evaluate(&identity, &opa_data).await { - Ok(()) => Ok(()), - Err(e) => Err(ApplyError::InvalidTransaction(e.to_string())), - } - } -} - -impl TransactionHandler for ChronicleTransactionHandler { - fn family_name(&self) -> String { - self.family_name.clone() - } - - fn family_versions(&self) -> Vec { - self.family_versions.clone() - } - - fn namespaces(&self) -> Vec { - self.namespaces.clone() - } - - #[instrument( - name = "apply", - level = "debug", - skip(request,context), - fields( - transaction_id = %request.signature, - inputs = ?request.header.as_ref().map(|x| &x.inputs), - outputs = ?request.header.as_ref().map(|x| &x.outputs), - dependencies = ?request.header.as_ref().map(|x| &x.dependencies) - ) - )] - fn apply( - &self, - request: &TpProcessRequest, - context: &mut dyn TransactionContext, - ) -> Result<(), ApplyError> { - let submission = Self::tp_parse(request)?; - let submission_clone = submission.clone(); - - let opa_exec_context = self.opa_executor.executor_context(context)?; - - let operations = - futures::executor::block_on( - async move { Self::tp_operations(submission.clone()).await }, - )?; - - info!(transaction_id = %request.signature, operation_count = %operations.tx.len()); - - let state = Self::tp_state(context, &operations)?; - let effects = futures::executor::block_on(async move { - Self::tp(opa_exec_context, request, submission_clone, operations, state).await - }) - .map_err(|e| ApplyError::InternalError(e.to_string()))?; - - effects.apply(context).map_err(|e| ApplyError::InternalError(e.to_string())) - } -} - -#[cfg(test)] -pub mod test { - use std::{ - cell::RefCell, - collections::{hash_map::DefaultHasher, BTreeMap}, - hash::{Hash, Hasher}, - }; - - use async_stl_client::sawtooth::TransactionPayload; - use chronicle_protocol::{ - async_stl_client::{ledger::LedgerTransaction, sawtooth::MessageBuilder}, - messages::ChronicleSubmitTransaction, - protocol::messages::Submission, - }; - use chronicle_signing::{ - chronicle_secret_names, ChronicleSecretsOptions, ChronicleSigning, BATCHER_NAMESPACE, - CHRONICLE_NAMESPACE, - }; - use chrono::{NaiveDateTime, TimeZone, Utc}; - use common::{ - identity::{AuthId, SignedIdentity}, - prov::{ - operations::{ - ActsOnBehalfOf, AgentExists, ChronicleOperation, CreateNamespace, EndActivity, - StartActivity, - }, - ActivityId, AgentId, ChronicleTransaction, DelegationId, ExternalId, ExternalIdPart, - NamespaceId, Role, - }, - }; - use prost::Message; - - use sawtooth_sdk::{ - messages::{processor::TpProcessRequest, transaction::TransactionHeader}, - processor::handler::{ContextError, TransactionContext, TransactionHandler}, - }; - use serde_json::Value; - - use uuid::Uuid; - - use crate::{abstract_tp::TP, tp::ChronicleTransactionHandler}; - - type TestTxEvents = Vec<(String, Vec<(String, String)>, Vec)>; - - pub struct TestTransactionContext { - pub state: RefCell>>, - pub events: RefCell, - } - - type PrintableEvent = Vec<(String, Vec<(String, String)>, Value)>; - - impl TestTransactionContext { - pub fn new() -> Self { - Self { state: RefCell::new(BTreeMap::new()), events: RefCell::new(vec![]) } - } - - pub fn readable_state(&self) -> Vec<(String, Value)> { - self.state - .borrow() - .iter() - .map(|(k, v)| { - ( - k.clone(), - serde_json::from_str(&String::from_utf8(v.clone()).unwrap()).unwrap(), - ) - }) - .collect() - } - - pub fn readable_events(&self) -> PrintableEvent { - self.events - .borrow() - .iter() - .map(|(k, attr, data)| { - ( - k.clone(), - attr.clone(), - serde_json::from_str( - &chronicle_protocol::sawtooth::Event::decode(&**data).unwrap().delta, - ) - .unwrap(), - ) - }) - .collect() - } - } - - impl Default for TestTransactionContext { - fn default() -> Self { - Self::new() - } - } - - impl TransactionContext for TestTransactionContext { - fn add_receipt_data( - self: &TestTransactionContext, - _data: &[u8], - ) -> Result<(), ContextError> { - unimplemented!() - } - - fn add_event( - self: &TestTransactionContext, - event_type: String, - attributes: Vec<(String, String)>, - data: &[u8], - ) -> Result<(), ContextError> { - self.events.borrow_mut().push((event_type, attributes, data.to_vec())); - Ok(()) - } - - fn delete_state_entries( - self: &TestTransactionContext, - _addresses: &[std::string::String], - ) -> Result, ContextError> { - unimplemented!() - } - - fn get_state_entries( - &self, - addresses: &[String], - ) -> Result)>, ContextError> { - Ok(self - .state - .borrow() - .iter() - .filter(|(k, _)| addresses.contains(k)) - .map(|(k, v)| (k.clone(), v.clone())) - .collect()) - } - - fn set_state_entries( - self: &TestTransactionContext, - entries: Vec<(String, Vec)>, - ) -> std::result::Result<(), sawtooth_sdk::processor::handler::ContextError> { - for entry in entries { - self.state.borrow_mut().insert(entry.0, entry.1); - } - - Ok(()) - } - } - - #[derive(Debug, Clone)] - struct SameUuid; - - fn uuid() -> Uuid { - Uuid::parse_str("5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea").unwrap() - } - - fn create_namespace_id_helper(tag: Option) -> NamespaceId { - let external_id = if tag.is_none() || tag == Some(0) { - "testns".to_string() - } else { - format!("testns{}", tag.unwrap()) - }; - NamespaceId::from_external_id(external_id, uuid()) - } - - fn create_namespace_helper(tag: Option) -> ChronicleOperation { - let id = create_namespace_id_helper(tag); - let external_id = &id.external_id_part().to_string(); - ChronicleOperation::CreateNamespace(CreateNamespace::new(id, external_id, uuid())) - } - - fn agent_exists_helper() -> ChronicleOperation { - let namespace: NamespaceId = NamespaceId::from_external_id("testns", uuid()); - let external_id: ExternalId = - ExternalIdPart::external_id_part(&AgentId::from_external_id("test_agent")).clone(); - ChronicleOperation::AgentExists(AgentExists { namespace, external_id }) - } - - fn create_agent_acts_on_behalf_of() -> ChronicleOperation { - let namespace: NamespaceId = NamespaceId::from_external_id("testns", uuid()); - let responsible_id = AgentId::from_external_id("test_agent"); - let delegate_id = AgentId::from_external_id("test_delegate"); - let activity_id = ActivityId::from_external_id("test_activity"); - let role = "test_role"; - let id = DelegationId::from_component_ids( - &delegate_id, - &responsible_id, - Some(&activity_id), - Some(role), - ); - let role = Role::from(role.to_string()); - ChronicleOperation::AgentActsOnBehalfOf(ActsOnBehalfOf { - namespace, - id, - responsible_id, - delegate_id, - activity_id: Some(activity_id), - role: Some(role), - }) - } - - #[tokio::test] - async fn simple_non_contradicting_operation() { - chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); - - let secrets = ChronicleSigning::new( - chronicle_secret_names(), - vec![ - (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::test_keys()), - (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::test_keys()), - ], - ) - .await - .unwrap(); - let signed_identity = AuthId::chronicle().signed_identity(&secrets).unwrap(); - - // Example transaction payload of `CreateNamespace`, - // `AgentExists`, and `AgentActsOnBehalfOf` `ChronicleOperation`s - let tx = ChronicleTransaction::new( - vec![ - create_namespace_helper(None), - agent_exists_helper(), - create_agent_acts_on_behalf_of(), - ], - signed_identity, - ); - - let submit_tx = - ChronicleSubmitTransaction { tx, signer: secrets.clone(), policy_name: None }; - - let message_builder = MessageBuilder::new_deterministic("TEST", "1.0"); - // Get a signed tx from sawtooth protocol - let (tx, _id) = submit_tx.as_sawtooth_tx(&message_builder).await.unwrap(); - - let header = - ::parse_from_bytes(&tx.header).unwrap(); - - let mut request = TpProcessRequest::default(); - request.set_header(header); - request.set_payload(tx.payload); - request.set_signature("TRANSACTION_SIGNATURE".to_string()); - - let (policy, entrypoint) = ("allow_transactions", "allow_transactions.allowed_users"); - - tokio::task::spawn_blocking(move || { - // Create a `TestTransactionContext` to pass to the `tp` function - let mut context = TestTransactionContext::new(); - let handler = ChronicleTransactionHandler::new(policy, entrypoint).unwrap(); - handler.apply(&request, &mut context).unwrap(); - - insta::assert_yaml_snapshot!(context.readable_events(), @r###" - --- - - - chronicle/prov-update - - - - transaction_id - - TRANSACTION_SIGNATURE - - "@context": "https://btp.works/chr/1.0/c.jsonld" - "@graph": - - "@id": "chronicle:activity:test%5Factivity" - "@type": "prov:Activity" - externalId: test_activity - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - value: {} - - "@id": "chronicle:agent:test%5Fagent" - "@type": "prov:Agent" - externalId: test_agent - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - value: {} - - "@id": "chronicle:agent:test%5Fdelegate" - "@type": "prov:Agent" - actedOnBehalfOf: - - "chronicle:agent:test%5Fagent" - externalId: test_delegate - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - "prov:qualifiedDelegation": - "@id": "chronicle:delegation:test%5Fdelegate:test%5Fagent:role=test%5Frole:activity=test%5Factivity" - value: {} - - "@id": "chronicle:delegation:test%5Fdelegate:test%5Fagent:role=test%5Frole:activity=test%5Factivity" - "@type": "prov:Delegation" - actedOnBehalfOf: - - "chronicle:agent:test%5Fagent" - agent: "chronicle:agent:test%5Fdelegate" - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - "prov:hadActivity": - "@id": "chronicle:activity:test%5Factivity" - "prov:hadRole": test_role - - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - "@type": "chronicle:Namespace" - externalId: testns - "###); - insta::assert_yaml_snapshot!(context.readable_state(), @r###" - --- - - - 43a52b235b2c3e3735c87de6688c5e30596cd12fa3bc9d013c616035292f842fed5077 - - "@id": "chronicle:agent:test%5Fdelegate" - "@type": "prov:Agent" - actedOnBehalfOf: - - "chronicle:agent:test%5Fagent" - externalId: test_delegate - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - "prov:qualifiedDelegation": - "@id": "chronicle:delegation:test%5Fdelegate:test%5Fagent:role=test%5Frole:activity=test%5Factivity" - value: {} - - - 43a52b23e8079f2f7d6e21587c560d0d3e665c94adcbb3aed368b04eb73fcce3dc15a9 - - "@id": "chronicle:activity:test%5Factivity" - "@type": "prov:Activity" - externalId: test_activity - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - value: {} - - - 43a52b549abebadfd16401dc74e089fb79d0143453a060dc05453da719d0897097c08f - - "@id": "chronicle:delegation:test%5Fdelegate:test%5Fagent:role=test%5Frole:activity=test%5Factivity" - "@type": "prov:Delegation" - actedOnBehalfOf: - - "chronicle:agent:test%5Fagent" - agent: "chronicle:agent:test%5Fdelegate" - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - "prov:hadActivity": - "@id": "chronicle:activity:test%5Factivity" - "prov:hadRole": test_role - - - 43a52be8b6d53163d3edd7e93e139a5f9adddb39e5481ee73a1b0326f26cf9abe90930 - - "@id": "chronicle:agent:test%5Fagent" - "@type": "prov:Agent" - externalId: test_agent - namespace: "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - value: {} - - - 43a52bfdc37432b62f2f32862673fbbd3b7dbd1574c441fee886c5f80be47854c3a06e - - "@id": "chronicle:ns:testns:5a0ab5b8-eeb7-4812-9fe3-6dd69bd20cea" - "@type": "chronicle:Namespace" - externalId: testns - "###); - }) - .await - .unwrap(); - } - - pub fn construct_operations() -> Vec { - let mut hasher = DefaultHasher::new(); - "foo".hash(&mut hasher); - let n1 = hasher.finish(); - "bar".hash(&mut hasher); - let n2 = hasher.finish(); - let uuid = Uuid::from_u64_pair(n1, n2); - - let base_ms = 1234567654321; - let activity_start = - Utc.from_utc_datetime(&NaiveDateTime::from_timestamp_millis(base_ms).unwrap()); - let activity_end = - Utc.from_utc_datetime(&NaiveDateTime::from_timestamp_millis(base_ms + 12345).unwrap()); - - let start = ChronicleOperation::StartActivity(StartActivity { - namespace: NamespaceId::from_external_id("test-namespace", uuid), - id: ActivityId::from_external_id("test-activity"), - time: activity_start, - }); - let end = ChronicleOperation::EndActivity(EndActivity { - namespace: NamespaceId::from_external_id("test-namespace", uuid), - id: ActivityId::from_external_id("test-activity"), - time: activity_end, - }); - - vec![start, end] - } - - async fn construct_submission(operations: Vec) -> Submission { - let secrets = ChronicleSigning::new( - chronicle_secret_names(), - vec![ - (CHRONICLE_NAMESPACE.to_string(), ChronicleSecretsOptions::test_keys()), - (BATCHER_NAMESPACE.to_string(), ChronicleSecretsOptions::test_keys()), - ], - ) - .await - .unwrap(); - - let tx_sub = ChronicleSubmitTransaction::new( - ChronicleTransaction { tx: operations, identity: SignedIdentity::new_no_identity() }, - secrets, - None, - ); - Submission::decode(tx_sub.to_bytes().await.unwrap().as_slice()).unwrap() - } - - #[tokio::test] - async fn get_operations_from_submission() { - chronicle_telemetry::telemetry(None, chronicle_telemetry::ConsoleLogging::Pretty); - let expected_operations = construct_operations(); - let submission = construct_submission(expected_operations.clone()).await; - let actual_operations = - ChronicleTransactionHandler::tp_operations(submission).await.unwrap().tx; - assert_eq!(expected_operations, actual_operations); - } -} diff --git a/node/node-chronicle/Cargo.toml b/node/node-chronicle/Cargo.toml index bb31c7626..ddff0b35e 100644 --- a/node/node-chronicle/Cargo.toml +++ b/node/node-chronicle/Cargo.toml @@ -1,79 +1,82 @@ [package] -name = "node-chronicle" -version = "4.0.0-dev" +authors = ["Substrate DevHub "] +build = "build.rs" description = "A fresh FRAME-based Substrate node, ready for hacking." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io/" -edition = "2021" -license = "MIT-0" -publish = false -repository = "https://github.com/substrate-developer-hub/substrate-node-template/" -build = "build.rs" +edition = "2021" +homepage = "https://substrate.io/" +license = "MIT-0" +name = "node-chronicle" +publish = false +repository = "https://github.com/substrate-developer-hub/substrate-node-template/" +version = "4.0.0-dev" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [[bin]] name = "node-chronicle" +path = "src/main.rs" -[dependencies] -clap = { version = "4.4.2", features = ["derive"] } -futures = { version = "0.3.21", features = ["thread-pool"]} +[lib] +name = "node_chronicle" +path = "src/lib.rs" -sc-cli = { version = "0.32.0" } -sp-core = { version= "24.0.0" } -sc-executor = { version = "0.28.0" } -sc-network = { version = "0.30.0" } -sc-service = { version = "0.31.0" } -sc-telemetry = { version = "11.0.0" } -sc-transaction-pool = { version = "24.0.0" } -sc-transaction-pool-api = { version = "24.0.0" } -sc-offchain = { version = "25.0.0" } -sc-statement-store = { version = "6.0.0" } -sc-consensus-aura = { version = "0.30.0" } -sp-consensus-aura = { version = "0.28.0" } -sc-consensus = { version = "0.29.0" } -sc-consensus-grandpa = { version = "0.15.0" } -sp-consensus-grandpa = { version = "9.0.0" } -sc-client-api = { version = "24.0.0" } -sp-runtime = { version = "27.0.0" } -sp-io = { version = "26.0.0" } -sp-timestamp = { version = "22.0.0" } -sp-inherents = { version = "22.0.0" } -sp-keyring = { version = "27.0.0" } -frame-system = { version = "24.0.0" } -pallet-transaction-payment = { version = "24.0.0", default-features = false } +[dependencies] +clap = { version = "4.4.2", features = ["derive"] } +frame-system = { version = "25.0.0" } +futures = { version = "0.3.21", features = ["thread-pool"] } +sc-cli = { version = "0.33.0" } +sc-client-api = { version = "25.0.0" } +sc-consensus = { version = "0.30.0" } +sc-consensus-aura = { version = "0.31.0" } +sc-consensus-grandpa = { version = "0.16.0" } +sc-executor = { version = "0.29.0" } +sc-network = { version = "0.31.0" } +sc-offchain = { version = "26.0.0" } +sc-service = { version = "0.32.0" } +sc-statement-store = { version = "7.0.0" } +sc-telemetry = { version = "12.0.0" } +sc-transaction-pool = { version = "25.0.0" } +sc-transaction-pool-api = { version = "25.0.0" } +sp-consensus-aura = { version = "0.29.0" } +sp-consensus-grandpa = { version = "10.0.0" } +sp-core = { version = "25.0.0" } +sp-inherents = { version = "23.0.0" } +sp-io = { version = "27.0.0" } +sp-keyring = { version = "28.0.0" } +sp-runtime = { version = "28.0.0" } +sp-timestamp = { version = "23.0.0" } +tracing = { workspace = true } # These dependencies are used for the node template's RPCs -jsonrpsee = { version = "0.16.3", features = ["server"] } -sp-api = { version = "22.0.0" } -sc-rpc-api = { version = "0.29.0" } -sp-blockchain = { version = "24.0.0" } -sp-block-builder = { version = "22.0.0" } -sc-basic-authorship = { version = "0.30.0" } -substrate-frame-rpc-system = { version = "24.0.0" } -pallet-transaction-payment-rpc = { version = "26.0.0" } +jsonrpsee = { version = "0.16", features = ["server"] } +sc-basic-authorship = { version = "0.31.0" } +sc-rpc-api = { version = "0.30.0" } +sp-api = { version = "23.0.0" } +sp-block-builder = { version = "23.0.0" } +sp-blockchain = { version = "25.0.0" } +substrate-frame-rpc-system = { version = "25.0.0" } # These dependencies are used for runtime benchmarking -frame-benchmarking = { version = "24.0.0" } -frame-benchmarking-cli = { version = "28.0.0" } +frame-benchmarking = { version = "25.0.0" } +frame-benchmarking-cli = { version = "29.0.0" } # Local Dependencies runtime-chronicle = { path = "../runtime-chronicle" } # CLI-specific dependencies -try-runtime-cli = { version = "0.34.0", optional = true } +try-runtime-cli = { version = "0.35.0", optional = true } [build-dependencies] -substrate-build-script-utils = { version = "8.0.0" } +substrate-build-script-utils = { version = "9.0.0" } [features] default = [] # Dependencies that are only required if runtime benchmarking should be build. runtime-benchmarks = [ - "runtime-chronicle/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks", - "frame-benchmarking-cli/runtime-benchmarks", + "runtime-chronicle/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-benchmarking-cli/runtime-benchmarks", ] # Enable features that allow the runtime to be tried and debugged. Name might be subject to change # in the near future. diff --git a/node/node-chronicle/src/benchmarking.rs b/node/node-chronicle/src/benchmarking.rs index 848237244..17d3b32b8 100644 --- a/node/node-chronicle/src/benchmarking.rs +++ b/node/node-chronicle/src/benchmarking.rs @@ -4,7 +4,7 @@ use crate::service::FullClient; -use runtime::{AccountId, Balance, BalancesCall, SystemCall}; +use runtime::{AccountId, Balance, SystemCall}; use runtime_chronicle as runtime; use sc_cli::Result; use sc_client_api::BlockBackend; @@ -68,30 +68,6 @@ impl TransferKeepAliveBuilder { } } -impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder { - fn pallet(&self) -> &str { - "balances" - } - - fn extrinsic(&self) -> &str { - "transfer_keep_alive" - } - - fn build(&self, nonce: u32) -> std::result::Result { - let acc = Sr25519Keyring::Bob.pair(); - let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic( - self.client.as_ref(), - acc, - BalancesCall::transfer_keep_alive { dest: self.dest.clone().into(), value: self.value } - .into(), - nonce, - ) - .into(); - - Ok(extrinsic) - } -} - /// Create a transaction using the given `call`. /// /// Note: Should only be used for benchmarking. @@ -118,9 +94,8 @@ pub fn create_benchmark_extrinsic( period, best_block.saturated_into(), )), - frame_system::CheckNonce::::from(nonce), + runtime_chronicle::no_nonce_fees::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), ); let raw_payload = runtime::SignedPayload::from_raw( @@ -134,7 +109,6 @@ pub fn create_benchmark_extrinsic( best_hash, (), (), - (), ), ); let signature = raw_payload.using_encoded(|e| sender.sign(e)); diff --git a/node/node-chronicle/src/chain_spec.rs b/node/node-chronicle/src/chain_spec.rs index 608eefdfb..9133ac0bf 100644 --- a/node/node-chronicle/src/chain_spec.rs +++ b/node/node-chronicle/src/chain_spec.rs @@ -1,8 +1,9 @@ use runtime_chronicle::{ - AccountId, AuraConfig, BalancesConfig, GrandpaConfig, RuntimeGenesisConfig, Signature, - SudoConfig, SystemConfig, WASM_BINARY, + pallet_chronicle, AccountId, AuraConfig, GrandpaConfig, Runtime, RuntimeGenesisConfig, + Signature, SudoConfig, SystemConfig, WASM_BINARY, }; use sc_service::ChainType; +use sc_telemetry::log; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{sr25519, Pair, Public}; @@ -38,7 +39,7 @@ pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { pub fn development_config() -> Result { let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; - + log::info!("development configuration"); Ok(ChainSpec::from_genesis( // Name "Development", @@ -53,12 +54,6 @@ pub fn development_config() -> Result { // Sudo account get_account_id_from_seed::("Alice"), // Pre-funded accounts - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - ], true, ) }, @@ -79,6 +74,7 @@ pub fn development_config() -> Result { pub fn local_testnet_config() -> Result { let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; + log::info!("testnet configuration"); Ok(ChainSpec::from_genesis( // Name "Local Testnet", @@ -93,20 +89,6 @@ pub fn local_testnet_config() -> Result { // Sudo account get_account_id_from_seed::("Alice"), // Pre-funded accounts - vec![ - get_account_id_from_seed::("Alice"), - get_account_id_from_seed::("Bob"), - get_account_id_from_seed::("Charlie"), - get_account_id_from_seed::("Dave"), - get_account_id_from_seed::("Eve"), - get_account_id_from_seed::("Ferdie"), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - get_account_id_from_seed::("Charlie//stash"), - get_account_id_from_seed::("Dave//stash"), - get_account_id_from_seed::("Eve//stash"), - get_account_id_from_seed::("Ferdie//stash"), - ], true, ) }, @@ -129,7 +111,6 @@ fn testnet_genesis( wasm_binary: &[u8], initial_authorities: Vec<(AuraId, GrandpaId)>, root_key: AccountId, - endowed_accounts: Vec, _enable_println: bool, ) -> RuntimeGenesisConfig { RuntimeGenesisConfig { @@ -138,10 +119,6 @@ fn testnet_genesis( code: wasm_binary.to_vec(), ..Default::default() }, - balances: BalancesConfig { - // Configure endowed accounts with initial balance of 1 << 60. - balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), - }, aura: AuraConfig { authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), }, @@ -153,6 +130,6 @@ fn testnet_genesis( // Assign network admin rights. key: Some(root_key), }, - transaction_payment: Default::default(), + chronicle: pallet_chronicle::GenesisConfig:: { ..Default::default() }, } } diff --git a/node/node-chronicle/src/command.rs b/node/node-chronicle/src/command.rs index cae7ab7b8..05ee8e997 100644 --- a/node/node-chronicle/src/command.rs +++ b/node/node-chronicle/src/command.rs @@ -1,14 +1,13 @@ use crate::{ - benchmarking::{inherent_benchmark_data, RemarkBuilder, TransferKeepAliveBuilder}, + benchmarking::{inherent_benchmark_data, RemarkBuilder}, chain_spec, cli::{Cli, Subcommand}, service, }; -use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE}; -use runtime_chronicle::{Block, EXISTENTIAL_DEPOSIT}; +use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; +use runtime_chronicle::Block; use sc_cli::SubstrateCli; use sc_service::PartialComponents; -use sp_keyring::Sr25519Keyring; #[cfg(feature = "try-runtime")] use try_runtime_cli::block_building_info::timestamp_with_aura_info; @@ -40,8 +39,8 @@ impl SubstrateCli for Cli { fn load_spec(&self, id: &str) -> Result, String> { Ok(match id { - "dev" => Box::new(chain_spec::development_config()?), - "" | "local" => Box::new(chain_spec::local_testnet_config()?), + "" | "dev" => Box::new(chain_spec::development_config()?), + "local" => Box::new(chain_spec::local_testnet_config()?), path => Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?), }) @@ -152,19 +151,8 @@ pub fn run() -> sc_cli::Result<()> { &ext_builder, ) }, - BenchmarkCmd::Extrinsic(cmd) => { - let PartialComponents { client, .. } = service::new_partial(&config)?; - // Register the *Remark* and *TKA* builders. - let ext_factory = ExtrinsicFactory(vec![ - Box::new(RemarkBuilder::new(client.clone())), - Box::new(TransferKeepAliveBuilder::new( - client.clone(), - Sr25519Keyring::Alice.to_account_id(), - EXISTENTIAL_DEPOSIT, - )), - ]); - - cmd.run(client, inherent_benchmark_data()?, Vec::new(), &ext_factory) + BenchmarkCmd::Extrinsic(_cmd) => { + todo!() // use chronicle here }, BenchmarkCmd::Machine(cmd) => cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone()), diff --git a/node/node-chronicle/src/lib.rs b/node/node-chronicle/src/lib.rs index f117b8aae..98fb4a23e 100644 --- a/node/node-chronicle/src/lib.rs +++ b/node/node-chronicle/src/lib.rs @@ -1,3 +1,6 @@ +pub mod benchmarking; pub mod chain_spec; +pub mod cli; +pub mod command; pub mod rpc; pub mod service; diff --git a/node/node-chronicle/src/rpc.rs b/node/node-chronicle/src/rpc.rs index 00a2c4a1a..db91f7ec4 100644 --- a/node/node-chronicle/src/rpc.rs +++ b/node/node-chronicle/src/rpc.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use jsonrpsee::RpcModule; -use runtime_chronicle::{opaque::Block, AccountId, Balance, Nonce}; +use runtime_chronicle::{opaque::Block, AccountId, Nonce}; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; @@ -35,18 +35,15 @@ where C: HeaderBackend + HeaderMetadata + 'static, C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, - C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: BlockBuilder, P: TransactionPool + 'static, { - use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; let mut module = RpcModule::new(()); let FullDeps { client, pool, deny_unsafe } = deps; module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; - module.merge(TransactionPayment::new(client).into_rpc())?; // Extend this RPC with a custom API by using the following syntax. // `YourRpcStruct` should have a reference to a client, which is needed diff --git a/node/runtime-chronicle/Cargo.toml b/node/runtime-chronicle/Cargo.toml index 60dd683db..83a1e96fb 100644 --- a/node/runtime-chronicle/Cargo.toml +++ b/node/runtime-chronicle/Cargo.toml @@ -1,114 +1,112 @@ [package] -name = "runtime-chronicle" -version = "4.0.0" +authors = ["Substrate DevHub "] description = "A fresh FRAME-based Substrate node, ready for hacking." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io/" -edition = "2021" -license = "MIT-0" -publish = false +edition = "2021" +homepage = "https://substrate.io/" +license = "MIT-0" +name = "runtime-chronicle" +publish = false +version = "4.0.0" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -parity-scale-codec = { version="3.6.5", default-features = false, features = ["derive"] } -scale-info = { version="2.10.0", default-features = false, features = ["derive"] } -pallet-aura = { version = "23.0.0", default-features=false } -pallet-balances = { version = "24.0.0", default-features = false } -frame-support = { version="24.0.0" , default-features=false } -pallet-grandpa = { version = "24.0.0", default-features = false } -pallet-sudo = { version = "24.0.0", default-features = false } -frame-system = { version= "24.0.0", default-features=false } -frame-try-runtime = { version= "0.30.0", default-features = false, optional=true} -pallet-timestamp = { version = "23.0.0", default-features=false } -pallet-transaction-payment = { version ="24.0.0",default-features=false} -frame-executive = { version = "24.0.0", default-features = false } -sp-api = { version = "22.0.0", default-features = false } -sp-block-builder = { version = "22.0.0", default-features = false } -sp-consensus-aura = { version = "0.28.0", default-features = false } -sp-consensus-grandpa = { version = "9.0.0", default-features = false} -sp-core = { version="24.0.0" ,default-features=false } -sp-inherents = { version = "22.0.0", default-features = false } -sp-offchain = { version = "22.0.0", default-features = false } -sp-runtime = { version="27.0.0", default-features = false} -sp-session = { version = "23.0.0", default-features = false} -sp-std = { version="11.0.0", default-features = false} -sp-transaction-pool = { version = "22.0.0", default-features = false} -sp-version = { version = "25.0.0", default-features = false} +frame-executive = { version = "25.0.0", default-features = false } +frame-support = { version = "25.0.0", default-features = false } +frame-system = { version = "25.0.0", default-features = false } +frame-try-runtime = { version = "0.31.0", default-features = false, optional = true } +pallet-aura = { version = "24.0.0", default-features = false } +pallet-grandpa = { version = "25.0.0", default-features = false } +pallet-sudo = { version = "25.0.0", default-features = false } +pallet-timestamp = { version = "24.0.0", default-features = false } +parity-scale-codec = { version = "3.6.5", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } +sp-api = { version = "23.0.0", default-features = false } +sp-block-builder = { version = "23.0.0", default-features = false } +sp-consensus-aura = { version = "0.29.0", default-features = false } +sp-consensus-grandpa = { version = "10.0.0", default-features = false } +sp-core = { version = "25.0.0", default-features = false } +sp-inherents = { version = "23.0.0", default-features = false } +sp-offchain = { version = "23.0.0", default-features = false } +sp-runtime = { version = "28.0.0", default-features = false } +sp-session = { version = "24.0.0", default-features = false } +sp-std = { version = "12.0.0", default-features = false } +sp-transaction-pool = { version = "23.0.0", default-features = false } +sp-version = { version = "26.0.0", default-features = false } # Used for the node template's RPCs -frame-system-rpc-runtime-api = { version = "22.0.0", default-features = false} -pallet-transaction-payment-rpc-runtime-api = { version = "24.0.0", default-features = false} +frame-system-rpc-runtime-api = { version = "23.0.0", default-features = false } # Used for runtime benchmarking -frame-benchmarking = { version = "24.0.0", default-features = false, optional=true} -frame-system-benchmarking = { version = "24.0.0", default-features = false, optional=true} +frame-benchmarking = { version = "25.0.0", default-features = false, optional = true } +frame-system-benchmarking = { version = "25.0.0", default-features = false, optional = true } # Local Dependencies -pallet-chronicle = { default-features = false, path = "../../crates/pallet-chronicle"} +pallet-chronicle = { default-features = false, path = "../../crates/pallet-chronicle" } +pallet-opa = { default-features = false, path = "../../crates/pallet-opa" } +runtime-api-chronicle = { default-features = false, path = "../../crates/runtime-api-chronicle" } [build-dependencies] -substrate-wasm-builder = { version = "13.0.0", optional = true } +substrate-wasm-builder = { version = "14.0.0", optional = true } [features] default = ["std"] -std = [ - "pallet-chronicle/std", - "frame-try-runtime?/std", - "frame-system-benchmarking?/std", - "frame-benchmarking?/std", - "parity-scale-codec/std", - "scale-info/std", - "frame-executive/std", - "frame-support/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "frame-try-runtime/std", - "pallet-aura/std", - "pallet-balances/std", - "pallet-grandpa/std", - "pallet-sudo/std", - "pallet-chronicle/std", - "pallet-timestamp/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "sp-api/std", - "sp-block-builder/std", - "sp-consensus-aura/std", - "sp-consensus-grandpa/std", - "sp-core/std", - "sp-inherents/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-std/std", - "sp-transaction-pool/std", - "sp-version/std", - "substrate-wasm-builder", -] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system-benchmarking/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-grandpa/runtime-benchmarks", - "pallet-sudo/runtime-benchmarks", - "pallet-chronicle/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-chronicle/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +std = [ + "pallet-chronicle/std", + "runtime-api-chronicle/std", + "frame-try-runtime?/std", + "frame-system-benchmarking?/std", + "frame-benchmarking?/std", + "parity-scale-codec/std", + "scale-info/std", + "frame-executive/std", + "frame-support/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "frame-try-runtime/std", + "pallet-aura/std", + "pallet-grandpa/std", + "pallet-sudo/std", + "pallet-chronicle/std", + "pallet-timestamp/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-consensus-grandpa/std", + "sp-core/std", + "sp-inherents/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", + "substrate-wasm-builder", ] try-runtime = [ - "frame-try-runtime/try-runtime", - "frame-executive/try-runtime", - "frame-system/try-runtime", - "frame-support/try-runtime", - "pallet-aura/try-runtime", - "pallet-balances/try-runtime", - "pallet-grandpa/try-runtime", - "pallet-sudo/try-runtime", - "pallet-chronicle/try-runtime", - "pallet-timestamp/try-runtime", - "pallet-transaction-payment/try-runtime", + "frame-try-runtime/try-runtime", + "frame-executive/try-runtime", + "frame-system/try-runtime", + "frame-support/try-runtime", + "pallet-aura/try-runtime", + "pallet-grandpa/try-runtime", + "pallet-sudo/try-runtime", + "pallet-chronicle/try-runtime", + "pallet-timestamp/try-runtime", ] diff --git a/node/runtime-chronicle/src/lib.rs b/node/runtime-chronicle/src/lib.rs index 1d43cbba4..0546af27d 100644 --- a/node/runtime-chronicle/src/lib.rs +++ b/node/runtime-chronicle/src/lib.rs @@ -6,16 +6,13 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use pallet_chronicle::operations; use pallet_grandpa::AuthorityId as GrandpaId; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, One, Verify, - }, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, }; @@ -23,6 +20,7 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; +pub mod no_nonce_fees; // A few exports that help ease life for downstream crates. pub use frame_support::{ @@ -40,15 +38,13 @@ pub use frame_support::{ StorageValue, }; pub use frame_system::Call as SystemCall; -pub use pallet_balances::Call as BalancesCall; pub use pallet_timestamp::Call as TimestampCall; -use pallet_transaction_payment::{ConstFeeMultiplier, CurrencyAdapter, Multiplier}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; -/// Import the template pallet. pub use pallet_chronicle; +pub use pallet_opa; /// An index to a block. pub type BlockNumber = u32; @@ -61,7 +57,7 @@ pub type Signature = MultiSignature; pub type AccountId = <::Signer as IdentifyAccount>::AccountId; /// Balance of an account. -pub type Balance = u128; +pub type Balance = (); /// Index of a transaction in the chain. pub type Nonce = u32; @@ -97,8 +93,8 @@ pub mod opaque { // https://docs.substrate.io/main-docs/build/upgrade#runtime-versioning #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("node-template"), - impl_name: create_runtime_str!("node-template"), + spec_name: create_runtime_str!("runtime-chronicle"), + impl_name: create_runtime_str!("runtime-chronicle"), authoring_version: 1, // The version of the runtime specification. A full node will not attempt to use its native // runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, @@ -154,6 +150,7 @@ parameter_types! { // Configure FRAME pallets to include in runtime. impl frame_system::Config for Runtime { + type AccountData = (); /// The basic call filter to use in dispatchable. type BaseCallFilter = frame_support::traits::Everything; /// The block type for the runtime. @@ -193,7 +190,6 @@ impl frame_system::Config for Runtime { /// What to do if an account is fully reaped from the system. type OnKilledAccount = (); /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = (); /// This is used as an identifier of the chain. 42 is the generic substrate prefix. @@ -230,40 +226,6 @@ impl pallet_timestamp::Config for Runtime { type WeightInfo = (); } -/// Existential deposit. -pub const EXISTENTIAL_DEPOSIT: u128 = 500; - -impl pallet_balances::Config for Runtime { - type MaxLocks = ConstU32<50>; - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ConstU128; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; - type FreezeIdentifier = (); - type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); -} - -parameter_types! { - pub FeeMultiplier: Multiplier = Multiplier::one(); -} - -impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = CurrencyAdapter; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = IdentityFee; - type FeeMultiplierUpdate = ConstFeeMultiplier; -} - impl pallet_sudo::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; @@ -274,7 +236,13 @@ impl pallet_sudo::Config for Runtime { impl pallet_chronicle::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_chronicle::weights::SubstrateWeight; - type OperationList = Vec; + type OperationSubmission = pallet_chronicle::chronicle_core::OperationSubmission; +} + +impl pallet_opa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_opa::weights::SubstrateWeight; + type OpaSubmission = pallet_opa::opa_core::codec::OpaSubmissionV1; } // Create the runtime by composing the FRAME pallets that were previously configured. @@ -284,11 +252,9 @@ construct_runtime!( Timestamp: pallet_timestamp, Aura: pallet_aura, Grandpa: pallet_grandpa, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, Sudo: pallet_sudo, - // Include the custom logic from the pallet-template in the runtime. Chronicle: pallet_chronicle, + Opa: pallet_opa, } ); @@ -298,6 +264,7 @@ pub type Address = sp_runtime::MultiAddress; pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; + /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( frame_system::CheckNonZeroSender, @@ -305,9 +272,8 @@ pub type SignedExtra = ( frame_system::CheckTxVersion, frame_system::CheckGenesis, frame_system::CheckEra, - frame_system::CheckNonce, + no_nonce_fees::CheckNonce, frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. @@ -333,7 +299,6 @@ mod benches { define_benchmarks!( [frame_benchmarking, BaselineBench::] [frame_system, SystemBench::] - [pallet_balances, Balances] [pallet_timestamp, Timestamp] [pallet_sudo, Sudo] [pallet_chronicle, Chronicle] @@ -341,6 +306,13 @@ mod benches { } impl_runtime_apis! { + impl runtime_api_chronicle::ChronicleApi for Runtime { + // Purely to keep runtime api dependencies in place + fn placeholder() -> u32 { + 0 + } + } + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION @@ -464,91 +436,6 @@ impl_runtime_apis! { } } - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi - for Runtime - { - fn query_call_info( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::RuntimeDispatchInfo { - TransactionPayment::query_call_info(call, len) - } - fn query_call_fee_details( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_call_fee_details(call, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - - let mut list = Vec::::new(); - list_benchmarks!(list, extra); - - let storage_info = AllPalletsWithSystem::storage_info(); - - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, TrackedStorageKey}; - - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - - impl frame_system_benchmarking::Config for Runtime {} - impl baseline::Config for Runtime {} - - use frame_support::traits::WhitelistedStorageKeys; - let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - add_benchmarks!(params, batches); - - Ok(batches) - } - } - #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { diff --git a/node/runtime-chronicle/src/no_nonce_fees.rs b/node/runtime-chronicle/src/no_nonce_fees.rs new file mode 100644 index 000000000..f65d480f9 --- /dev/null +++ b/node/runtime-chronicle/src/no_nonce_fees.rs @@ -0,0 +1,106 @@ +use frame_support::dispatch::DispatchInfo; +use frame_system::{Account, Config}; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{DispatchInfoOf, Dispatchable, One, SignedExtension}, + transaction_validity::{ + InvalidTransaction, TransactionLongevity, TransactionValidity, TransactionValidityError, + ValidTransaction, + }, +}; +use sp_std::vec; + +/// Nonce check and increment to give replay protection for transactions. +/// +/// # Transaction Validity +/// +/// This extension affects `requires` and `provides` tags of validity, but DOES NOT +/// set the `priority` field. Make sure that AT LEAST one of the signed extension sets +/// some kind of priority upon validating transactions. +#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct CheckNonce(#[codec(compact)] pub T::Nonce); + +impl CheckNonce { + /// utility constructor. Used only in client/factory code. + pub fn from(nonce: T::Nonce) -> Self { + Self(nonce) + } +} + +impl sp_std::fmt::Debug for CheckNonce { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckNonce({})", self.0) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl SignedExtension for CheckNonce +where + T::RuntimeCall: Dispatchable, +{ + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); + type Pre = (); + const IDENTIFIER: &'static str = "CheckNonce"; + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result<(), TransactionValidityError> { + let mut account = Account::::get(who); + if self.0 != account.nonce { + return Err(if self.0 < account.nonce { + InvalidTransaction::Stale + } else { + InvalidTransaction::Future + } + .into()) + } + account.nonce += T::Nonce::one(); + Account::::insert(who, account); + Ok(()) + } + + fn validate( + &self, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + let account = Account::::get(who); + if self.0 < account.nonce { + return InvalidTransaction::Stale.into() + } + + let provides = vec![Encode::encode(&(who, self.0))]; + let requires = if account.nonce < self.0 { + vec![Encode::encode(&(who, self.0 - One::one()))] + } else { + vec![] + }; + + Ok(ValidTransaction { + priority: 0, + requires, + provides, + longevity: TransactionLongevity::max_value(), + propagate: true, + }) + } +} diff --git a/node/runtime-chronicle/tree.txt b/node/runtime-chronicle/tree.txt new file mode 100644 index 000000000..d72bd583d --- /dev/null +++ b/node/runtime-chronicle/tree.txt @@ -0,0 +1,896 @@ +runtime-chronicle v4.0.0 (/Users/ryan/code/chronicle/node/runtime-chronicle) +├── frame-executive v24.0.0 +│ ├── frame-support v24.0.0 +│ │ ├── aquamarine v0.3.2 (proc-macro) +│ │ │ ├── include_dir v0.7.3 +│ │ │ │ └── include_dir_macros v0.7.3 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 +│ │ │ │ │ └── unicode-ident v1.0.12 +│ │ │ │ └── quote v1.0.33 +│ │ │ │ └── proc-macro2 v1.0.69 (*) +│ │ │ ├── itertools v0.10.5 +│ │ │ │ └── either v1.9.0 +│ │ │ ├── proc-macro-error v1.0.4 +│ │ │ │ ├── proc-macro-error-attr v1.0.4 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ └── quote v1.0.33 (*) +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v1.0.109 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── unicode-ident v1.0.12 +│ │ │ │ [build-dependencies] +│ │ │ │ └── version_check v0.9.4 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── bitflags v1.3.2 +│ │ ├── docify v0.2.6 +│ │ │ └── docify_macros v0.2.6 (proc-macro) +│ │ │ ├── common-path v1.0.0 +│ │ │ ├── derive-syn-parse v0.1.5 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v1.0.109 (*) +│ │ │ ├── once_cell v1.18.0 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ ├── regex v1.10.2 +│ │ │ │ ├── aho-corasick v1.1.2 +│ │ │ │ │ └── memchr v2.6.4 +│ │ │ │ ├── memchr v2.6.4 +│ │ │ │ ├── regex-automata v0.4.3 +│ │ │ │ │ ├── aho-corasick v1.1.2 (*) +│ │ │ │ │ ├── memchr v2.6.4 +│ │ │ │ │ └── regex-syntax v0.8.2 +│ │ │ │ └── regex-syntax v0.8.2 +│ │ │ ├── syn v2.0.38 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── unicode-ident v1.0.12 +│ │ │ ├── termcolor v1.3.0 +│ │ │ ├── toml v0.7.8 +│ │ │ │ ├── serde v1.0.190 +│ │ │ │ │ └── serde_derive v1.0.190 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── serde_spanned v0.6.4 +│ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ ├── toml_datetime v0.6.5 +│ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ └── toml_edit v0.19.15 +│ │ │ │ ├── indexmap v2.0.2 +│ │ │ │ │ ├── equivalent v1.0.1 +│ │ │ │ │ └── hashbrown v0.14.2 +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── serde_spanned v0.6.4 (*) +│ │ │ │ ├── toml_datetime v0.6.5 (*) +│ │ │ │ └── winnow v0.5.17 +│ │ │ └── walkdir v2.4.0 +│ │ │ └── same-file v1.0.6 +│ │ ├── environmental v1.1.4 +│ │ ├── frame-metadata v16.0.0 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── parity-scale-codec v3.6.5 +│ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ ├── byte-slice-cast v1.2.2 +│ │ │ │ ├── bytes v1.5.0 +│ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ ├── parity-scale-codec-derive v3.6.5 (proc-macro) +│ │ │ │ │ ├── proc-macro-crate v1.1.3 +│ │ │ │ │ │ ├── thiserror v1.0.50 +│ │ │ │ │ │ │ └── thiserror-impl v1.0.50 (proc-macro) +│ │ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ │ └── toml v0.5.11 +│ │ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v1.0.109 (*) +│ │ │ │ └── serde v1.0.190 +│ │ │ │ └── serde_derive v1.0.190 (proc-macro) (*) +│ │ │ └── scale-info v2.10.0 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── derive_more v0.99.17 (proc-macro) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v1.0.109 (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info-derive v2.10.0 (proc-macro) +│ │ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v1.0.109 (*) +│ │ │ └── serde v1.0.190 (*) +│ │ ├── frame-support-procedural v19.0.0 (proc-macro) +│ │ │ ├── Inflector v0.11.4 +│ │ │ │ ├── lazy_static v1.4.0 +│ │ │ │ └── regex v1.10.2 (*) +│ │ │ ├── cfg-expr v0.15.5 +│ │ │ │ └── smallvec v1.11.1 +│ │ │ ├── derive-syn-parse v0.1.5 (proc-macro) (*) +│ │ │ ├── expander v2.0.0 +│ │ │ │ ├── blake2 v0.10.6 +│ │ │ │ │ └── digest v0.10.7 +│ │ │ │ │ ├── block-buffer v0.10.4 +│ │ │ │ │ │ └── generic-array v0.14.7 +│ │ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ │ ├── crypto-common v0.1.6 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── fs-err v2.9.0 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── frame-support-procedural-tools v8.0.0 +│ │ │ │ ├── frame-support-procedural-tools-derive v9.0.0 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── itertools v0.10.5 (*) +│ │ │ ├── macro_magic v0.4.2 +│ │ │ │ ├── macro_magic_core v0.4.2 +│ │ │ │ │ ├── const-random v0.1.16 +│ │ │ │ │ │ └── const-random-macro v0.1.16 (proc-macro) +│ │ │ │ │ │ ├── getrandom v0.2.10 +│ │ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ │ └── libc v0.2.149 +│ │ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ │ └── tiny-keccak v2.0.2 +│ │ │ │ │ │ └── crunchy v0.2.2 +│ │ │ │ │ ├── derive-syn-parse v0.1.5 (proc-macro) (*) +│ │ │ │ │ ├── macro_magic_core_macros v0.4.3 (proc-macro) +│ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── macro_magic_macros v0.4.2 (proc-macro) +│ │ │ │ │ ├── macro_magic_core v0.4.2 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── proc-macro-warning v0.4.2 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ ├── k256 v0.13.1 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── ecdsa v0.16.8 +│ │ │ │ ├── der v0.7.8 +│ │ │ │ │ ├── const-oid v0.9.5 +│ │ │ │ │ └── zeroize v1.6.0 +│ │ │ │ │ └── zeroize_derive v1.4.2 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── digest v0.10.7 +│ │ │ │ │ ├── block-buffer v0.10.4 +│ │ │ │ │ │ └── generic-array v0.14.7 +│ │ │ │ │ │ ├── typenum v1.17.0 +│ │ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ │ ├── const-oid v0.9.5 +│ │ │ │ │ ├── crypto-common v0.1.6 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ ├── elliptic-curve v0.13.6 +│ │ │ │ │ ├── base16ct v0.2.0 +│ │ │ │ │ ├── crypto-bigint v0.5.3 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ ├── ff v0.13.0 +│ │ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ ├── group v0.13.0 +│ │ │ │ │ │ ├── ff v0.13.0 (*) +│ │ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ ├── sec1 v0.7.3 +│ │ │ │ │ │ ├── base16ct v0.2.0 +│ │ │ │ │ │ ├── der v0.7.8 (*) +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── rfc6979 v0.4.0 +│ │ │ │ │ ├── hmac v0.12.1 +│ │ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ └── signature v2.1.0 +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ └── rand_core v0.6.4 +│ │ │ ├── elliptic-curve v0.13.6 (*) +│ │ │ └── sha2 v0.10.8 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ └── digest v0.10.7 (*) +│ │ ├── log v0.4.20 +│ │ ├── macro_magic v0.4.2 +│ │ │ └── macro_magic_macros v0.4.2 (proc-macro) (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── paste v1.0.14 (proc-macro) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── serde_json v1.0.107 +│ │ │ ├── itoa v1.0.9 +│ │ │ ├── ryu v1.0.15 +│ │ │ └── serde v1.0.190 (*) +│ │ ├── smallvec v1.11.1 +│ │ ├── sp-api v22.0.0 +│ │ │ ├── log v0.4.20 +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── sp-api-proc-macro v11.0.0 (proc-macro) +│ │ │ │ ├── Inflector v0.11.4 (*) +│ │ │ │ ├── blake2 v0.10.6 (*) +│ │ │ │ ├── expander v2.0.0 (*) +│ │ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── sp-core v24.0.0 +│ │ │ │ ├── array-bytes v6.1.0 +│ │ │ │ ├── bitflags v1.3.2 +│ │ │ │ ├── blake2 v0.10.6 +│ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ ├── bounded-collections v0.1.9 +│ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ ├── bs58 v0.5.0 +│ │ │ │ ├── hash-db v0.16.0 +│ │ │ │ ├── hash256-std-hasher v0.15.2 +│ │ │ │ │ └── crunchy v0.2.2 +│ │ │ │ ├── impl-serde v0.4.0 +│ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ ├── log v0.4.20 +│ │ │ │ ├── merlin v2.0.1 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── keccak v0.1.4 +│ │ │ │ │ ├── rand_core v0.5.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── paste v1.0.14 (proc-macro) +│ │ │ │ ├── primitive-types v0.12.2 +│ │ │ │ │ ├── fixed-hash v0.8.0 +│ │ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ │ ├── impl-codec v0.6.0 +│ │ │ │ │ │ └── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── impl-serde v0.4.0 (*) +│ │ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ │ └── uint v0.9.5 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── crunchy v0.2.2 +│ │ │ │ │ ├── hex v0.4.3 +│ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ ├── schnorrkel v0.9.1 +│ │ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ │ ├── arrayvec v0.5.2 +│ │ │ │ │ ├── curve25519-dalek v2.1.3 +│ │ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ │ ├── digest v0.8.1 +│ │ │ │ │ │ │ └── generic-array v0.12.4 +│ │ │ │ │ │ │ └── typenum v1.17.0 +│ │ │ │ │ │ ├── rand_core v0.5.1 +│ │ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ │ ├── merlin v2.0.1 (*) +│ │ │ │ │ ├── rand_core v0.5.1 +│ │ │ │ │ ├── sha2 v0.8.2 +│ │ │ │ │ │ ├── block-buffer v0.7.3 +│ │ │ │ │ │ │ ├── block-padding v0.1.5 +│ │ │ │ │ │ │ │ └── byte-tools v0.3.1 +│ │ │ │ │ │ │ ├── byte-tools v0.3.1 +│ │ │ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ │ │ └── generic-array v0.12.4 (*) +│ │ │ │ │ │ ├── digest v0.8.1 (*) +│ │ │ │ │ │ ├── fake-simd v0.1.2 +│ │ │ │ │ │ └── opaque-debug v0.2.3 +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── secrecy v0.8.0 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── sp-core-hashing v12.0.0 +│ │ │ │ │ ├── blake2b_simd v1.0.2 +│ │ │ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ │ │ └── constant_time_eq v0.3.0 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ ├── sha2 v0.10.8 (*) +│ │ │ │ │ ├── sha3 v0.10.8 +│ │ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ │ └── keccak v0.1.4 +│ │ │ │ │ └── twox-hash v1.6.3 +│ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ ├── sp-debug-derive v11.0.0 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── sp-runtime-interface v20.0.0 +│ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── primitive-types v0.12.2 (*) +│ │ │ │ │ ├── sp-externalities v0.22.0 +│ │ │ │ │ │ ├── environmental v1.1.4 +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ │ └── sp-storage v16.0.0 +│ │ │ │ │ │ ├── impl-serde v0.4.0 (*) +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ ├── ref-cast v1.0.20 +│ │ │ │ │ │ │ └── ref-cast-impl v1.0.20 (proc-macro) +│ │ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ │ ├── sp-debug-derive v11.0.0 (proc-macro) (*) +│ │ │ │ │ │ └── sp-std v11.0.0 +│ │ │ │ │ ├── sp-runtime-interface-proc-macro v14.0.0 (proc-macro) +│ │ │ │ │ │ ├── Inflector v0.11.4 (*) +│ │ │ │ │ │ ├── proc-macro-crate v1.1.3 (*) +│ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ ├── sp-storage v16.0.0 (*) +│ │ │ │ │ ├── sp-tracing v13.0.0 +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ │ ├── tracing v0.1.40 +│ │ │ │ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ │ │ │ ├── tracing-attributes v0.1.27 (proc-macro) +│ │ │ │ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ │ │ │ └── tracing-core v0.1.32 +│ │ │ │ │ │ └── tracing-core v0.1.32 +│ │ │ │ │ ├── sp-wasm-interface v17.0.0 +│ │ │ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ └── sp-std v11.0.0 +│ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ ├── sp-storage v16.0.0 (*) +│ │ │ │ ├── ss58-registry v1.43.0 +│ │ │ │ │ [build-dependencies] +│ │ │ │ │ ├── Inflector v0.11.4 (*) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ ├── serde_json v1.0.107 +│ │ │ │ │ │ ├── itoa v1.0.9 +│ │ │ │ │ │ ├── ryu v1.0.15 +│ │ │ │ │ │ └── serde v1.0.190 (*) +│ │ │ │ │ └── unicode-xid v0.2.4 +│ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ ├── sp-metadata-ir v0.3.0 +│ │ │ │ ├── frame-metadata v16.0.0 (*) +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ └── sp-std v11.0.0 +│ │ │ ├── sp-runtime v27.0.0 +│ │ │ │ ├── either v1.9.0 +│ │ │ │ ├── hash256-std-hasher v0.15.2 (*) +│ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ │ ├── log v0.4.20 +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── paste v1.0.14 (proc-macro) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── sp-application-crypto v26.0.0 +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ │ ├── sp-io v26.0.0 +│ │ │ │ │ │ ├── bytes v1.5.0 +│ │ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ │ │ ├── sp-externalities v0.22.0 (*) +│ │ │ │ │ │ ├── sp-runtime-interface v20.0.0 (*) +│ │ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ │ ├── sp-tracing v13.0.0 (*) +│ │ │ │ │ │ ├── tracing v0.1.40 (*) +│ │ │ │ │ │ └── tracing-core v0.1.32 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── rustversion v1.0.14 (proc-macro) +│ │ │ │ │ └── sp-std v11.0.0 +│ │ │ │ ├── sp-arithmetic v19.0.0 +│ │ │ │ │ ├── integer-sqrt v0.1.5 +│ │ │ │ │ │ └── num-traits v0.2.17 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── autocfg v1.1.0 +│ │ │ │ │ ├── num-traits v0.2.17 (*) +│ │ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ ├── sp-io v26.0.0 (*) +│ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ └── sp-weights v23.0.0 +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ ├── serde v1.0.190 (*) +│ │ │ │ ├── smallvec v1.11.1 +│ │ │ │ ├── sp-arithmetic v19.0.0 (*) +│ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ ├── sp-debug-derive v11.0.0 (proc-macro) (*) +│ │ │ │ └── sp-std v11.0.0 +│ │ │ ├── sp-std v11.0.0 +│ │ │ └── sp-version v25.0.0 +│ │ │ ├── impl-serde v0.4.0 (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── sp-core-hashing-proc-macro v12.0.0 (proc-macro) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ ├── sp-core-hashing v12.0.0 +│ │ │ │ │ ├── blake2b_simd v1.0.2 +│ │ │ │ │ │ ├── arrayref v0.3.7 +│ │ │ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ │ │ └── constant_time_eq v0.3.0 +│ │ │ │ │ ├── byteorder v1.5.0 +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ ├── sha2 v0.10.8 +│ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ ├── cpufeatures v0.2.11 +│ │ │ │ │ │ │ └── libc v0.2.149 +│ │ │ │ │ │ └── digest v0.10.7 (*) +│ │ │ │ │ ├── sha3 v0.10.8 +│ │ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ │ └── keccak v0.1.4 +│ │ │ │ │ │ └── cpufeatures v0.2.11 (*) +│ │ │ │ │ └── twox-hash v1.6.3 +│ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ └── static_assertions v1.1.0 +│ │ │ │ └── syn v2.0.38 (*) +│ │ │ ├── sp-runtime v27.0.0 (*) +│ │ │ ├── sp-std v11.0.0 +│ │ │ └── sp-version-proc-macro v11.0.0 (proc-macro) +│ │ │ ├── parity-scale-codec v3.6.5 +│ │ │ │ ├── arrayvec v0.7.4 +│ │ │ │ ├── byte-slice-cast v1.2.2 +│ │ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ │ ├── parity-scale-codec-derive v3.6.5 (proc-macro) (*) +│ │ │ │ └── serde v1.0.190 (*) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── sp-arithmetic v19.0.0 (*) +│ │ ├── sp-core v24.0.0 (*) +│ │ ├── sp-core-hashing-proc-macro v12.0.0 (proc-macro) (*) +│ │ ├── sp-debug-derive v11.0.0 (proc-macro) (*) +│ │ ├── sp-genesis-builder v0.3.0 +│ │ │ ├── serde_json v1.0.107 (*) +│ │ │ ├── sp-api v22.0.0 (*) +│ │ │ ├── sp-runtime v27.0.0 (*) +│ │ │ └── sp-std v11.0.0 +│ │ ├── sp-inherents v22.0.0 +│ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ └── sp-std v11.0.0 +│ │ ├── sp-io v26.0.0 (*) +│ │ ├── sp-metadata-ir v0.3.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ ├── sp-staking v22.0.0 +│ │ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ ├── sp-core v24.0.0 (*) +│ │ │ ├── sp-runtime v27.0.0 (*) +│ │ │ └── sp-std v11.0.0 +│ │ ├── sp-std v11.0.0 +│ │ ├── sp-tracing v13.0.0 (*) +│ │ ├── sp-weights v23.0.0 (*) +│ │ ├── static_assertions v1.1.0 +│ │ └── tt-call v1.0.9 +│ ├── frame-system v24.0.0 +│ │ ├── cfg-if v1.0.0 +│ │ ├── frame-support v24.0.0 (*) +│ │ ├── log v0.4.20 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── sp-core v24.0.0 (*) +│ │ ├── sp-io v26.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ ├── sp-std v11.0.0 +│ │ ├── sp-version v25.0.0 (*) +│ │ └── sp-weights v23.0.0 (*) +│ ├── log v0.4.20 +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-core v24.0.0 (*) +│ ├── sp-io v26.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ ├── sp-std v11.0.0 +│ └── sp-tracing v13.0.0 (*) +├── frame-support v24.0.0 (*) +├── frame-system v24.0.0 (*) +├── frame-system-rpc-runtime-api v22.0.0 +│ ├── parity-scale-codec v3.6.5 (*) +│ └── sp-api v22.0.0 (*) +├── pallet-aura v23.0.0 +│ ├── frame-support v24.0.0 (*) +│ ├── frame-system v24.0.0 (*) +│ ├── log v0.4.20 +│ ├── pallet-timestamp v23.0.0 +│ │ ├── docify v0.2.6 (*) +│ │ ├── frame-support v24.0.0 (*) +│ │ ├── frame-system v24.0.0 (*) +│ │ ├── log v0.4.20 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── sp-inherents v22.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ ├── sp-std v11.0.0 +│ │ ├── sp-storage v16.0.0 (*) +│ │ └── sp-timestamp v22.0.0 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── sp-inherents v22.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-application-crypto v26.0.0 (*) +│ ├── sp-consensus-aura v0.28.0 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── sp-api v22.0.0 (*) +│ │ ├── sp-application-crypto v26.0.0 (*) +│ │ ├── sp-consensus-slots v0.28.0 +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── sp-std v11.0.0 +│ │ │ └── sp-timestamp v22.0.0 (*) +│ │ ├── sp-inherents v22.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ ├── sp-std v11.0.0 +│ │ └── sp-timestamp v22.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ └── sp-std v11.0.0 +├── pallet-balances v24.0.0 +│ ├── frame-support v24.0.0 (*) +│ ├── frame-system v24.0.0 (*) +│ ├── log v0.4.20 +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ └── sp-std v11.0.0 +├── pallet-chronicle v0.7.5 (/Users/ryan/code/chronicle/crates/pallet-chronicle) +│ ├── common v0.7.5 (/Users/ryan/code/chronicle/crates/common) +│ │ ├── anyhow v1.0.75 +│ │ ├── async-trait v0.1.74 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v2.0.38 (*) +│ │ ├── chrono v0.4.31 +│ │ │ ├── js-sys v0.3.64 +│ │ │ │ └── wasm-bindgen v0.2.87 +│ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ └── wasm-bindgen-macro v0.2.87 (proc-macro) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ └── wasm-bindgen-macro-support v0.2.87 +│ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ ├── syn v2.0.38 (*) +│ │ │ │ ├── wasm-bindgen-backend v0.2.87 +│ │ │ │ │ ├── bumpalo v3.14.0 +│ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ ├── syn v2.0.38 (*) +│ │ │ │ │ └── wasm-bindgen-shared v0.2.87 +│ │ │ │ └── wasm-bindgen-shared v0.2.87 +│ │ │ ├── num-traits v0.2.17 (*) +│ │ │ ├── serde v1.0.190 (*) +│ │ │ └── wasm-bindgen v0.2.87 (*) +│ │ ├── futures v0.3.29 +│ │ │ ├── futures-channel v0.3.29 +│ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ └── futures-sink v0.3.29 +│ │ │ ├── futures-core v0.3.29 +│ │ │ ├── futures-executor v0.3.29 +│ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ ├── futures-task v0.3.29 +│ │ │ │ └── futures-util v0.3.29 +│ │ │ │ ├── futures-channel v0.3.29 (*) +│ │ │ │ ├── futures-core v0.3.29 +│ │ │ │ ├── futures-io v0.3.29 +│ │ │ │ ├── futures-macro v0.3.29 (proc-macro) +│ │ │ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ │ │ ├── quote v1.0.33 (*) +│ │ │ │ │ └── syn v2.0.38 (*) +│ │ │ │ ├── futures-sink v0.3.29 +│ │ │ │ ├── futures-task v0.3.29 +│ │ │ │ ├── memchr v2.6.4 +│ │ │ │ ├── pin-project-lite v0.2.13 +│ │ │ │ ├── pin-utils v0.1.0 +│ │ │ │ └── slab v0.4.9 +│ │ │ │ [build-dependencies] +│ │ │ │ └── autocfg v1.1.0 +│ │ │ ├── futures-io v0.3.29 +│ │ │ ├── futures-sink v0.3.29 +│ │ │ ├── futures-task v0.3.29 +│ │ │ └── futures-util v0.3.29 (*) +│ │ ├── glob v0.3.1 +│ │ ├── hex v0.4.3 +│ │ ├── iref v2.2.3 +│ │ │ ├── pct-str v1.2.0 +│ │ │ │ └── utf8-decode v1.0.1 +│ │ │ └── smallvec v1.11.1 +│ │ ├── iref-enum v2.1.0 (proc-macro) +│ │ │ ├── iref v2.2.3 +│ │ │ │ ├── pct-str v1.2.0 +│ │ │ │ │ └── utf8-decode v1.0.1 +│ │ │ │ └── smallvec v1.11.1 +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── k256 v0.11.6 +│ │ │ ├── cfg-if v1.0.0 +│ │ │ ├── ecdsa v0.14.8 +│ │ │ │ ├── der v0.6.1 +│ │ │ │ │ └── const-oid v0.9.5 +│ │ │ │ ├── elliptic-curve v0.12.3 +│ │ │ │ │ ├── base16ct v0.1.1 +│ │ │ │ │ ├── crypto-bigint v0.4.9 +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ │ ├── ff v0.12.1 +│ │ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ ├── group v0.12.1 +│ │ │ │ │ │ ├── ff v0.12.1 (*) +│ │ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ │ └── subtle v2.4.1 +│ │ │ │ │ ├── pkcs8 v0.9.0 +│ │ │ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ │ │ └── spki v0.6.0 +│ │ │ │ │ │ └── der v0.6.1 (*) +│ │ │ │ │ ├── rand_core v0.6.4 +│ │ │ │ │ ├── sec1 v0.3.0 +│ │ │ │ │ │ ├── base16ct v0.1.1 +│ │ │ │ │ │ ├── der v0.6.1 (*) +│ │ │ │ │ │ ├── generic-array v0.14.7 (*) +│ │ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ │ ├── subtle v2.4.1 +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ ├── rfc6979 v0.3.1 +│ │ │ │ │ ├── crypto-bigint v0.4.9 (*) +│ │ │ │ │ ├── hmac v0.12.1 (*) +│ │ │ │ │ └── zeroize v1.6.0 (*) +│ │ │ │ └── signature v1.6.4 +│ │ │ │ ├── digest v0.10.7 (*) +│ │ │ │ └── rand_core v0.6.4 +│ │ │ ├── elliptic-curve v0.12.3 (*) +│ │ │ └── sha2 v0.10.8 (*) +│ │ ├── lazy_static v1.4.0 +│ │ ├── locspan v0.7.16 +│ │ ├── macro-attr-2018 v3.0.0 +│ │ ├── mime v0.3.17 +│ │ ├── newtype-derive-2018 v0.2.1 +│ │ │ └── generics v0.5.0 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── percent-encoding v2.3.0 +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── serde_derive v1.0.190 (proc-macro) (*) +│ │ ├── serde_json v1.0.107 (*) +│ │ ├── static-iref v2.0.0 (proc-macro) +│ │ │ └── iref v2.2.3 (*) +│ │ ├── thiserror v1.0.50 +│ │ │ └── thiserror-impl v1.0.50 (proc-macro) (*) +│ │ ├── thiserror-no-std v2.0.2 +│ │ │ └── thiserror-impl-no-std v2.0.2 (proc-macro) +│ │ │ ├── proc-macro2 v1.0.69 (*) +│ │ │ ├── quote v1.0.33 (*) +│ │ │ └── syn v1.0.109 (*) +│ │ ├── tracing v0.1.40 (*) +│ │ ├── url v2.4.1 +│ │ │ ├── form_urlencoded v1.2.0 +│ │ │ │ └── percent-encoding v2.3.0 +│ │ │ ├── idna v0.4.0 +│ │ │ │ ├── unicode-bidi v0.3.13 +│ │ │ │ └── unicode-normalization v0.1.22 +│ │ │ │ └── tinyvec v1.6.0 +│ │ │ │ └── tinyvec_macros v0.1.1 +│ │ │ └── percent-encoding v2.3.0 +│ │ └── uuid v1.5.0 +│ │ └── serde v1.0.190 (*) +│ │ [build-dependencies] +│ │ ├── glob v0.3.1 +│ │ ├── lazy_static v1.4.0 +│ │ └── serde_json v1.0.107 (*) +│ ├── frame-support v24.0.0 (*) +│ ├── frame-system v24.0.0 (*) +│ ├── macro-attr-2018 v3.0.0 +│ ├── newtype-derive-2018 v0.2.1 (*) +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-std v11.0.0 +│ ├── tracing v0.1.40 (*) +│ └── uuid v1.5.0 (*) +├── pallet-grandpa v24.0.0 +│ ├── frame-support v24.0.0 (*) +│ ├── frame-system v24.0.0 (*) +│ ├── log v0.4.20 +│ ├── pallet-authorship v24.0.0 +│ │ ├── frame-support v24.0.0 (*) +│ │ ├── frame-system v24.0.0 (*) +│ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── pallet-session v24.0.0 +│ │ ├── frame-support v24.0.0 (*) +│ │ ├── frame-system v24.0.0 (*) +│ │ ├── impl-trait-for-tuples v0.2.2 (proc-macro) (*) +│ │ ├── log v0.4.20 +│ │ ├── pallet-timestamp v23.0.0 (*) +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── sp-core v24.0.0 (*) +│ │ ├── sp-io v26.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ ├── sp-session v23.0.0 +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── scale-info v2.10.0 (*) +│ │ │ ├── sp-api v22.0.0 (*) +│ │ │ ├── sp-core v24.0.0 (*) +│ │ │ ├── sp-staking v22.0.0 (*) +│ │ │ └── sp-std v11.0.0 +│ │ ├── sp-staking v22.0.0 (*) +│ │ ├── sp-state-machine v0.31.0 +│ │ │ ├── hash-db v0.16.0 +│ │ │ ├── log v0.4.20 +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ ├── smallvec v1.11.1 +│ │ │ ├── sp-core v24.0.0 (*) +│ │ │ ├── sp-externalities v0.22.0 (*) +│ │ │ ├── sp-std v11.0.0 +│ │ │ ├── sp-trie v25.0.0 +│ │ │ │ ├── hash-db v0.16.0 +│ │ │ │ ├── memory-db v0.32.0 +│ │ │ │ │ └── hash-db v0.16.0 +│ │ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ │ ├── scale-info v2.10.0 (*) +│ │ │ │ ├── sp-core v24.0.0 (*) +│ │ │ │ ├── sp-std v11.0.0 +│ │ │ │ ├── trie-db v0.28.0 +│ │ │ │ │ ├── hash-db v0.16.0 +│ │ │ │ │ ├── hashbrown v0.13.2 +│ │ │ │ │ │ └── ahash v0.8.6 +│ │ │ │ │ │ ├── cfg-if v1.0.0 +│ │ │ │ │ │ ├── once_cell v1.18.0 +│ │ │ │ │ │ └── zerocopy v0.7.20 +│ │ │ │ │ │ [build-dependencies] +│ │ │ │ │ │ └── version_check v0.9.4 +│ │ │ │ │ ├── log v0.4.20 +│ │ │ │ │ └── smallvec v1.11.1 +│ │ │ │ └── trie-root v0.18.0 +│ │ │ │ └── hash-db v0.16.0 +│ │ │ └── trie-db v0.28.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-application-crypto v26.0.0 (*) +│ ├── sp-consensus-grandpa v9.0.0 +│ │ ├── finality-grandpa v0.16.2 +│ │ │ ├── either v1.9.0 +│ │ │ ├── futures v0.3.29 (*) +│ │ │ ├── num-traits v0.2.17 (*) +│ │ │ ├── parity-scale-codec v3.6.5 (*) +│ │ │ └── scale-info v2.10.0 (*) +│ │ ├── log v0.4.20 +│ │ ├── parity-scale-codec v3.6.5 (*) +│ │ ├── scale-info v2.10.0 (*) +│ │ ├── serde v1.0.190 (*) +│ │ ├── sp-api v22.0.0 (*) +│ │ ├── sp-application-crypto v26.0.0 (*) +│ │ ├── sp-core v24.0.0 (*) +│ │ ├── sp-runtime v27.0.0 (*) +│ │ └── sp-std v11.0.0 +│ ├── sp-core v24.0.0 (*) +│ ├── sp-io v26.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ ├── sp-session v23.0.0 (*) +│ ├── sp-staking v22.0.0 (*) +│ └── sp-std v11.0.0 +├── pallet-sudo v24.0.0 +│ ├── docify v0.2.6 (*) +│ ├── frame-support v24.0.0 (*) +│ ├── frame-system v24.0.0 (*) +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-io v26.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ └── sp-std v11.0.0 +├── pallet-timestamp v23.0.0 (*) +├── pallet-transaction-payment v24.0.0 +│ ├── frame-support v24.0.0 (*) +│ ├── frame-system v24.0.0 (*) +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── scale-info v2.10.0 (*) +│ ├── sp-core v24.0.0 (*) +│ ├── sp-io v26.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ └── sp-std v11.0.0 +├── pallet-transaction-payment-rpc-runtime-api v24.0.0 +│ ├── pallet-transaction-payment v24.0.0 (*) +│ ├── parity-scale-codec v3.6.5 (*) +│ ├── sp-api v22.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ └── sp-weights v23.0.0 (*) +├── parity-scale-codec v3.6.5 (*) +├── scale-info v2.10.0 (*) +├── sp-api v22.0.0 (*) +├── sp-block-builder v22.0.0 +│ ├── sp-api v22.0.0 (*) +│ ├── sp-inherents v22.0.0 (*) +│ ├── sp-runtime v27.0.0 (*) +│ └── sp-std v11.0.0 +├── sp-consensus-aura v0.28.0 (*) +├── sp-consensus-grandpa v9.0.0 (*) +├── sp-core v24.0.0 (*) +├── sp-inherents v22.0.0 (*) +├── sp-offchain v22.0.0 +│ ├── sp-api v22.0.0 (*) +│ ├── sp-core v24.0.0 (*) +│ └── sp-runtime v27.0.0 (*) +├── sp-runtime v27.0.0 (*) +├── sp-session v23.0.0 (*) +├── sp-std v11.0.0 +├── sp-transaction-pool v22.0.0 +│ ├── sp-api v22.0.0 (*) +│ └── sp-runtime v27.0.0 (*) +└── sp-version v25.0.0 (*) diff --git a/rustfmt.toml b/rustfmt.toml index 441913f61..02c22cd70 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,23 +1,24 @@ # Basic -hard_tabs = true -max_width = 100 +hard_tabs = true +max_width = 100 use_small_heuristics = "Max" # Imports imports_granularity = "Crate" -reorder_imports = true +reorder_imports = true # Consistency newline_style = "Unix" # Format comments comment_width = 100 wrap_comments = true # Misc -chain_width = 80 -spaces_around_ranges = false -binop_separator = "Back" -reorder_impl_items = false -match_arm_leading_pipes = "Preserve" -match_arm_blocks = false +binop_separator = "Back" +chain_width = 80 +match_arm_blocks = false +match_arm_leading_pipes = "Preserve" match_block_trailing_comma = true -trailing_comma = "Vertical" -trailing_semicolon = false -use_field_init_shorthand = true +reorder_impl_items = true +reorder_modules = true +spaces_around_ranges = false +trailing_comma = "Vertical" +trailing_semicolon = false +use_field_init_shorthand = true