diff --git a/CHANGELOG.md b/CHANGELOG.md index ada5aaea8..5dbc090fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). At the moment this project **does not** adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/entropyxyz/entropy-core/compare/release/v0.3.0-rc.1...master) +## [Unreleased](https://github.com/entropyxyz/entropy-core/compare/release/v0.3.0...master) ### Breaking Changes - In [#1104](https://github.com/entropyxyz/entropy-core/pull/1104) the `/validator/rotate_network_key` endpoint was renamed to `rotate_network_key` @@ -17,25 +17,38 @@ At the moment this project **does not** adhere to `AttestationQueue` config types were removed from the Attestation pallet. - In [#1068](https://github.com/entropyxyz/entropy-core/pull/1068) an extra type `PckCertChainVerifier` was added to the staking extension pallet's `Config` trait. -- In [#1134](https://github.com/entropyxyz/entropy-core/pull/1134/) the ```no-sync``` option was removed +- In [#1123](https://github.com/entropyxyz/entropy-core/pull/1123/) the `change_endpoint()` and + `change_threshold_accounts()` extrinsics got new TDX `quote` related parameters added. +- In [#1134](https://github.com/entropyxyz/entropy-core/pull/1134/) the `--no-sync` option was + removed. +- In [#1153](https://github.com/entropyxyz/entropy-core/pull/1153/) the program runtime was updated to accept +multiple oracle inputs, this means any programs that were compiled and used need to be recompiled to the new +runtime +- In [#1179](https://github.com/entropyxyz/entropy-core/pull/1179) the format of TDX Quote input data has + been changed. ### Added - Protocol message versioning ([#1140](https://github.com/entropyxyz/entropy-core/pull/1140)) +- CLI command to get oracle headings ([#1170](https://github.com/entropyxyz/entropy-core/pull/1170)) +- Add TSS endpoint to get TDX quote ([#1173](https://github.com/entropyxyz/entropy-core/pull/1173)) ### Changed - Use correct key rotation endpoint in OCW ([#1104](https://github.com/entropyxyz/entropy-core/pull/1104)) - Change attestation flow to be pull based ([#1109](https://github.com/entropyxyz/entropy-core/pull/1109/)) - Handle PCK certificates ([#1068](https://github.com/entropyxyz/entropy-core/pull/1068)) +- Add quote guards to `ServerInfo` related extrinsics ([#1123](https://github.com/entropyxyz/entropy-core/pull/1123/)) - Remove declare synced ([#1134](https://github.com/entropyxyz/entropy-core/pull/1134/)) +- Update programs to accept multiple oracle data ([#1153](https://github.com/entropyxyz/entropy-core/pull/1153/)) +- Use context, not block number in TDX quote input data ([#1179](https://github.com/entropyxyz/entropy-core/pull/1179)) -## [0.3.0-rc.1](https://github.com/entropyxyz/entropy-core/compare/release/v0.2.0...release/v0.3.0-rc.1) - 2024-10-04 +## [0.3.0](https://github.com/entropyxyz/entropy-core/compare/release/v0.2.0...release/v0.3.0) - 2024-10-22 ### Breaking Changes - In [#799](https://github.com/entropyxyz/entropy-core/pull/799) the concept of subgroups was removed in favour of a single pool of signers. - In [#801](https://github.com/entropyxyz/entropy-core/pull/801) permissioned access mode was removed. -- In [#879](https://github.com/entropyxyz/entropy-core/pull/879) the network migrated from t-of-N +- In [#879](https://github.com/entropyxyz/entropy-core/pull/879) the network migrated from N-of-N cryptography to `t-of-N` cryptography. - In [#938](https://github.com/entropyxyz/entropy-core/pull/938), the chainspec got a couple of new fields, `pallet_staking_extension::initial_signers`, `pallet_parameters::total_signers`, and @@ -56,7 +69,10 @@ At the moment this project **does not** adhere to As such, `UserSignatureRequest` no longer requires the `validators_info` field since the the relayer adds that in after. The response received from the validator is now a `Vec` from the signers. -- In ([#1063](https://github.com/entropyxyz/entropy-core/pull/1063)) the +- In [#1051](https://github.com/entropyxyz/entropy-core/pull/1051) an extra field representing a provisioning certification key (PCK) + was added to the Staking Extension's `threshold_server` genesis configuration in the network + chainspecs. +- In [#1063](https://github.com/entropyxyz/entropy-core/pull/1063) the `pallet_staking_extension::validate()` extrinsic was changed so that in order to populate certain data structures related to a candidates state (namely `ThresholdToStash` and `ThresholdServer`) an attestation from the Attestation pallet must have been received. Success of the `validate()` diff --git a/Cargo.lock b/Cargo.lock index 702a3f9b1..989a41f6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,9 +215,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "approx" @@ -422,7 +422,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.68", "time", ] @@ -511,7 +511,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 0.38.37", + "rustix 0.38.40", "slab", "tracing", "windows-sys 0.52.0", @@ -563,7 +563,7 @@ dependencies = [ "cfg-if", "event-listener 5.3.0", "futures-lite", - "rustix 0.38.37", + "rustix 0.38.40", "tracing", "windows-sys 0.52.0", ] @@ -580,7 +580,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.37", + "rustix 0.38.40", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -647,9 +647,9 @@ checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -1129,7 +1129,7 @@ dependencies = [ "semver 1.0.22", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1301,9 +1301,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -1311,9 +1311,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -2434,7 +2434,7 @@ dependencies = [ [[package]] name = "entropy" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "clap", "entropy-runtime", @@ -2510,7 +2510,7 @@ dependencies = [ [[package]] name = "entropy-client" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -2522,6 +2522,7 @@ dependencies = [ "hex", "js-sys", "num", + "parity-scale-codec", "rand", "rand_core 0.6.4", "reqwest", @@ -2533,7 +2534,8 @@ dependencies = [ "sp-keyring 34.0.0", "subxt", "synedrion", - "thiserror", + "tdx-quote", + "thiserror 2.0.3", "tokio", "tracing", "x25519-dalek 2.0.1", @@ -2541,7 +2543,7 @@ dependencies = [ [[package]] name = "entropy-create-test-keyshares" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "entropy-kvdb", "entropy-shared", @@ -2554,7 +2556,7 @@ dependencies = [ [[package]] name = "entropy-kvdb" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "bincode 1.3.3", "chacha20poly1305 0.9.1", @@ -2568,7 +2570,7 @@ dependencies = [ "sled", "sp-core 31.0.0", "synedrion", - "thiserror", + "thiserror 2.0.3", "tokio", "tracing", "zeroize", @@ -2577,8 +2579,7 @@ dependencies = [ [[package]] name = "entropy-programs-core" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b5d04ed1473cf2ddf65364adfa473f4f4127132525342e85ca15adf97f2cb9" +source = "git+https://github.com/entropyxyz/programs.git?branch=master#b300dab62e0bd77ff9a6341dab4988459dcaed78" dependencies = [ "getrandom 0.2.15", "serde", @@ -2589,17 +2590,16 @@ dependencies = [ [[package]] name = "entropy-programs-runtime" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a50c0e3e7224af04d8bebc6994f7428796de5f88861c89291644f2a85a44d3c" +source = "git+https://github.com/entropyxyz/programs.git?branch=master#b300dab62e0bd77ff9a6341dab4988459dcaed78" dependencies = [ "entropy-programs-core", - "thiserror", + "thiserror 1.0.68", "wasmtime 12.0.2", ] [[package]] name = "entropy-protocol" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "anyhow", "async-trait", @@ -2628,7 +2628,7 @@ dependencies = [ "sp-keyring 34.0.0", "subxt", "synedrion", - "thiserror", + "thiserror 2.0.3", "tokio", "tokio-tungstenite", "tracing", @@ -2641,7 +2641,7 @@ dependencies = [ [[package]] name = "entropy-runtime" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "entropy-shared", "frame-benchmarking", @@ -2726,7 +2726,7 @@ dependencies = [ [[package]] name = "entropy-shared" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "blake2 0.10.6", "hex-literal", @@ -2745,7 +2745,7 @@ dependencies = [ [[package]] name = "entropy-test-cli" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "anyhow", "bincode 1.3.3", @@ -2754,6 +2754,9 @@ dependencies = [ "entropy-client", "entropy-shared", "hex", + "reqwest", + "serde", + "serde_json", "sp-core 31.0.0", "sp-runtime 32.0.0", "subxt", @@ -2763,7 +2766,7 @@ dependencies = [ [[package]] name = "entropy-testing-utils" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "axum", "entropy-kvdb", @@ -2789,7 +2792,7 @@ dependencies = [ [[package]] name = "entropy-tss" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "anyhow", "axum", @@ -2841,10 +2844,10 @@ dependencies = [ "subxt-signer", "synedrion", "tdx-quote", - "thiserror", + "thiserror 2.0.3", "tokio", "tokio-tungstenite", - "tower-http 0.6.1", + "tower-http 0.6.2", "tracing", "tracing-bunyan-formatter", "tracing-loki", @@ -2935,7 +2938,7 @@ dependencies = [ "serde", "serde_json", "sha3", - "thiserror", + "thiserror 1.0.68", "uint", ] @@ -2992,7 +2995,7 @@ dependencies = [ "serde_json", "strum 0.26.3", "tempfile", - "thiserror", + "thiserror 1.0.68", "tiny-keccak", "unicode-xid", ] @@ -3098,7 +3101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -3334,7 +3337,7 @@ dependencies = [ "sp-storage 20.0.0", "sp-trie 30.0.0", "sp-wasm-interface 20.0.0", - "thiserror", + "thiserror 1.0.68", "thousands", ] @@ -3703,7 +3706,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.37", + "rustix 0.38.40", "windows-sys 0.48.0", ] @@ -3971,7 +3974,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -3990,7 +3993,7 @@ dependencies = [ "http 1.1.0", "js-sys", "pin-project", - "thiserror", + "thiserror 1.0.68", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4101,7 +4104,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4908,7 +4911,7 @@ dependencies = [ "rustls-native-certs 0.7.0", "rustls-pki-types", "soketto", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-rustls 0.25.0", "tokio-util", @@ -4934,7 +4937,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", ] @@ -4958,7 +4961,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "tracing", @@ -4978,7 +4981,7 @@ dependencies = [ "jsonrpsee-types 0.22.4", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tokio", "tower 0.4.13", "tracing", @@ -5026,7 +5029,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "tokio-util", @@ -5050,7 +5053,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "tokio-util", @@ -5068,7 +5071,7 @@ dependencies = [ "beef", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tracing", ] @@ -5082,7 +5085,7 @@ dependencies = [ "beef", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -5183,9 +5186,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libloading" @@ -5283,7 +5286,7 @@ dependencies = [ "rand", "rw-stream-sink", "smallvec", - "thiserror", + "thiserror 1.0.68", "unsigned-varint", "void", ] @@ -5320,7 +5323,7 @@ dependencies = [ "quick-protobuf", "quick-protobuf-codec", "smallvec", - "thiserror", + "thiserror 1.0.68", "void", ] @@ -5338,7 +5341,7 @@ dependencies = [ "quick-protobuf", "rand", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -5364,7 +5367,7 @@ dependencies = [ "rand", "sha2 0.10.8", "smallvec", - "thiserror", + "thiserror 1.0.68", "uint", "unsigned-varint", "void", @@ -5423,7 +5426,7 @@ dependencies = [ "sha2 0.10.8", "snow", "static_assertions", - "thiserror", + "thiserror 1.0.68", "x25519-dalek 1.1.1", "zeroize", ] @@ -5463,7 +5466,7 @@ dependencies = [ "quinn-proto", "rand", "rustls 0.20.9", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -5544,7 +5547,7 @@ dependencies = [ "rcgen", "ring 0.16.20", "rustls 0.20.9", - "thiserror", + "thiserror 1.0.68", "webpki", "x509-parser", "yasna", @@ -5592,7 +5595,7 @@ dependencies = [ "futures", "libp2p-core", "log", - "thiserror", + "thiserror 1.0.68", "yamux", ] @@ -5931,7 +5934,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.37", + "rustix 0.38.40", ] [[package]] @@ -6045,7 +6048,7 @@ dependencies = [ "rand_chacha 0.3.1", "rand_distr", "subtle 2.5.0", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -6320,7 +6323,7 @@ dependencies = [ "anyhow", "byteorder", "paste", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -6334,7 +6337,7 @@ dependencies = [ "log", "netlink-packet-core", "netlink-sys", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -6738,7 +6741,7 @@ dependencies = [ [[package]] name = "pallet-attestation" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "entropy-shared", "frame-benchmarking", @@ -7181,7 +7184,7 @@ dependencies = [ [[package]] name = "pallet-oracle" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "frame-benchmarking", "frame-support 29.0.2", @@ -7196,7 +7199,7 @@ dependencies = [ [[package]] name = "pallet-parameters" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "entropy-shared", "frame-benchmarking", @@ -7232,7 +7235,7 @@ dependencies = [ [[package]] name = "pallet-programs" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "frame-benchmarking", "frame-support 29.0.2", @@ -7250,7 +7253,7 @@ dependencies = [ [[package]] name = "pallet-propagation" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "entropy-shared", "frame-benchmarking", @@ -7317,7 +7320,7 @@ dependencies = [ [[package]] name = "pallet-registry" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "bip32", "entropy-shared", @@ -7410,7 +7413,7 @@ dependencies = [ [[package]] name = "pallet-slashing" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7460,7 +7463,7 @@ dependencies = [ [[package]] name = "pallet-staking-extension" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "entropy-shared", "frame-benchmarking", @@ -7566,7 +7569,7 @@ dependencies = [ [[package]] name = "pallet-transaction-pause" -version = "0.3.0-rc.1" +version = "0.3.0" dependencies = [ "frame-benchmarking", "frame-support 29.0.2", @@ -7740,9 +7743,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.12" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +checksum = "8be4817d39f3272f69c59fe05d0535ae6456c2dc2fa1ba02910296c7e0a5c590" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -7750,6 +7753,7 @@ dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec-derive", + "rustversion", "serde", ] @@ -7902,7 +7906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.68", "ucd-trie", ] @@ -8147,7 +8151,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite 0.2.14", - "rustix 0.38.37", + "rustix 0.38.40", "tracing", "windows-sys 0.52.0", ] @@ -8367,7 +8371,7 @@ dependencies = [ "lazy_static", "memchr", "parking_lot 0.12.3", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -8556,7 +8560,7 @@ dependencies = [ "asynchronous-codec", "bytes", "quick-protobuf", - "thiserror", + "thiserror 1.0.68", "unsigned-varint", ] @@ -8583,7 +8587,7 @@ dependencies = [ "rustc-hash", "rustls 0.20.9", "slab", - "thiserror", + "thiserror 1.0.68", "tinyvec", "tracing", "webpki", @@ -8763,7 +8767,7 @@ checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -8913,7 +8917,7 @@ dependencies = [ "nom", "pin-project-lite 0.2.14", "reqwest", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9055,7 +9059,7 @@ dependencies = [ "netlink-packet-route", "netlink-proto", "nix", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -9121,9 +9125,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags 2.5.0", "errno", @@ -9324,7 +9328,7 @@ dependencies = [ "log", "sp-core 29.0.0", "sp-wasm-interface 20.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9336,7 +9340,7 @@ dependencies = [ "log", "sp-core 32.0.0", "sp-wasm-interface 21.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9366,7 +9370,7 @@ dependencies = [ "sp-keystore 0.35.0", "sp-runtime 32.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9528,7 +9532,7 @@ dependencies = [ "sp-panic-handler", "sp-runtime 32.0.0", "sp-version 30.0.0", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -9570,7 +9574,7 @@ dependencies = [ "sp-panic-handler", "sp-runtime 35.0.0", "sp-version 33.0.0", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -9707,7 +9711,7 @@ dependencies = [ "sp-runtime 32.0.0", "sp-state-machine 0.36.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9733,7 +9737,7 @@ dependencies = [ "sp-runtime 35.0.0", "sp-state-machine 0.39.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9770,7 +9774,7 @@ dependencies = [ "sp-keystore 0.35.0", "sp-runtime 32.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9793,7 +9797,7 @@ dependencies = [ "sp-core 29.0.0", "sp-keystore 0.35.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9851,7 +9855,7 @@ dependencies = [ "sp-keystore 0.35.0", "sp-runtime 32.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9872,7 +9876,7 @@ dependencies = [ "sp-blockchain 29.0.0", "sp-core 29.0.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -9955,7 +9959,7 @@ dependencies = [ "sc-allocator 24.0.0", "sp-maybe-compressed-blob", "sp-wasm-interface 20.0.0", - "thiserror", + "thiserror 1.0.68", "wasm-instrument", ] @@ -9969,7 +9973,7 @@ dependencies = [ "sc-allocator 27.0.0", "sp-maybe-compressed-blob", "sp-wasm-interface 21.0.0", - "thiserror", + "thiserror 1.0.68", "wasm-instrument", ] @@ -10071,7 +10075,7 @@ dependencies = [ "sp-application-crypto 31.0.0", "sp-core 29.0.0", "sp-keystore 0.35.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10086,7 +10090,7 @@ dependencies = [ "sp-application-crypto 34.0.0", "sp-core 32.0.0", "sp-keystore 0.38.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10116,7 +10120,7 @@ dependencies = [ "sp-keystore 0.35.0", "sp-mixnet 0.5.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10146,7 +10150,7 @@ dependencies = [ "sp-keystore 0.38.0", "sp-mixnet 0.8.0", "sp-runtime 35.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10185,7 +10189,7 @@ dependencies = [ "sp-core 29.0.0", "sp-runtime 32.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "unsigned-varint", @@ -10229,7 +10233,7 @@ dependencies = [ "sp-core 32.0.0", "sp-runtime 35.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "unsigned-varint", @@ -10254,7 +10258,7 @@ dependencies = [ "sc-network 0.35.0", "sp-blockchain 29.0.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", "unsigned-varint", ] @@ -10275,7 +10279,7 @@ dependencies = [ "sc-network 0.38.0", "sp-blockchain 32.0.0", "sp-runtime 35.0.0", - "thiserror", + "thiserror 1.0.68", "unsigned-varint", ] @@ -10354,7 +10358,7 @@ dependencies = [ "sp-blockchain 29.0.0", "sp-core 29.0.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10376,7 +10380,7 @@ dependencies = [ "sp-blockchain 32.0.0", "sp-core 32.0.0", "sp-runtime 35.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10411,7 +10415,7 @@ dependencies = [ "sp-core 29.0.0", "sp-runtime 32.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", ] @@ -10448,7 +10452,7 @@ dependencies = [ "sp-core 32.0.0", "sp-runtime 35.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", ] @@ -10622,7 +10626,7 @@ dependencies = [ "sp-rpc 27.0.0", "sp-runtime 32.0.0", "sp-version 30.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10643,7 +10647,7 @@ dependencies = [ "sp-rpc 30.0.0", "sp-runtime 35.0.0", "sp-version 33.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10707,7 +10711,7 @@ dependencies = [ "sp-rpc 27.0.0", "sp-runtime 32.0.0", "sp-version 30.0.0", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", ] @@ -10739,7 +10743,7 @@ dependencies = [ "sp-rpc 30.0.0", "sp-runtime 35.0.0", "sp-version 33.0.0", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", ] @@ -10802,7 +10806,7 @@ dependencies = [ "static_init", "substrate-prometheus-endpoint", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", "tracing-futures", @@ -10867,7 +10871,7 @@ dependencies = [ "static_init", "substrate-prometheus-endpoint", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", "tracing-futures", @@ -10907,7 +10911,7 @@ dependencies = [ "fs4", "log", "sp-core 29.0.0", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -10928,7 +10932,7 @@ dependencies = [ "serde_json", "sp-blockchain 29.0.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -10991,7 +10995,7 @@ dependencies = [ "sc-utils 15.0.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "wasm-timer", ] @@ -11011,7 +11015,7 @@ dependencies = [ "sc-utils 17.0.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "wasm-timer", ] @@ -11040,7 +11044,7 @@ dependencies = [ "sp-rpc 27.0.0", "sp-runtime 32.0.0", "sp-tracing 16.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-log 0.1.4", "tracing-subscriber 0.2.25", @@ -11071,7 +11075,7 @@ dependencies = [ "sp-rpc 30.0.0", "sp-runtime 35.0.0", "sp-tracing 17.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-log 0.1.4", "tracing-subscriber 0.2.25", @@ -11114,7 +11118,7 @@ dependencies = [ "sp-tracing 16.0.0", "sp-transaction-pool 27.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -11142,7 +11146,7 @@ dependencies = [ "sp-tracing 17.0.0", "sp-transaction-pool 30.0.0", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -11159,7 +11163,7 @@ dependencies = [ "sp-blockchain 29.0.0", "sp-core 29.0.0", "sp-runtime 32.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -11176,7 +11180,7 @@ dependencies = [ "sp-blockchain 32.0.0", "sp-core 32.0.0", "sp-runtime 35.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -11280,9 +11284,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "bitvec", "cfg-if", @@ -11294,9 +11298,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -11324,7 +11328,7 @@ dependencies = [ "quote", "scale-info", "syn 2.0.87", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -11573,9 +11577,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -11591,9 +11595,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -11613,9 +11617,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -11666,9 +11670,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ "futures", "log", @@ -11680,9 +11684,9 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", @@ -12046,7 +12050,7 @@ dependencies = [ "sp-std 14.0.0", "sp-trie 30.0.0", "sp-version 30.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12069,7 +12073,7 @@ dependencies = [ "sp-std 14.0.0", "sp-trie 33.0.0", "sp-version 33.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12243,7 +12247,7 @@ dependencies = [ "sp-database", "sp-runtime 32.0.0", "sp-state-machine 0.36.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12262,7 +12266,7 @@ dependencies = [ "sp-database", "sp-runtime 35.0.0", "sp-state-machine 0.39.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12278,7 +12282,7 @@ dependencies = [ "sp-inherents 27.0.0", "sp-runtime 32.0.0", "sp-state-machine 0.36.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12294,7 +12298,7 @@ dependencies = [ "sp-inherents 30.0.0", "sp-runtime 35.0.0", "sp-state-machine 0.39.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12455,7 +12459,7 @@ dependencies = [ "sp-storage 20.0.0", "ss58-registry", "substrate-bip39 0.4.6", - "thiserror", + "thiserror 1.0.68", "tracing", "w3f-bls", "zeroize", @@ -12502,7 +12506,7 @@ dependencies = [ "sp-storage 20.0.0", "ss58-registry", "substrate-bip39 0.5.0", - "thiserror", + "thiserror 1.0.68", "tracing", "w3f-bls", "zeroize", @@ -12549,7 +12553,7 @@ dependencies = [ "sp-storage 21.0.0", "ss58-registry", "substrate-bip39 0.6.0", - "thiserror", + "thiserror 1.0.68", "tracing", "w3f-bls", "zeroize", @@ -12671,7 +12675,7 @@ dependencies = [ "scale-info", "sp-runtime 32.0.0", "sp-std 14.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12685,7 +12689,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime 35.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12811,7 +12815,7 @@ dependencies = [ "parking_lot 0.12.3", "sp-core 29.0.0", "sp-externalities 0.26.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -12844,7 +12848,7 @@ version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c768c11afbe698a090386876911da4236af199cd38a5866748df4d8628aeff" dependencies = [ - "thiserror", + "thiserror 1.0.68", "zstd 0.12.4", ] @@ -13205,7 +13209,7 @@ dependencies = [ "sp-panic-handler", "sp-std 14.0.0", "sp-trie 30.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "trie-db", ] @@ -13227,7 +13231,7 @@ dependencies = [ "sp-panic-handler", "sp-std 14.0.0", "sp-trie 32.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "trie-db", ] @@ -13248,7 +13252,7 @@ dependencies = [ "sp-externalities 0.28.0", "sp-panic-handler", "sp-trie 33.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "trie-db", ] @@ -13275,7 +13279,7 @@ dependencies = [ "sp-runtime 32.0.0", "sp-runtime-interface 25.0.0", "sp-std 14.0.0", - "thiserror", + "thiserror 1.0.68", "x25519-dalek 2.0.1", ] @@ -13300,7 +13304,7 @@ dependencies = [ "sp-externalities 0.28.0", "sp-runtime 35.0.0", "sp-runtime-interface 27.0.0", - "thiserror", + "thiserror 1.0.68", "x25519-dalek 2.0.1", ] @@ -13354,7 +13358,7 @@ dependencies = [ "sp-inherents 27.0.0", "sp-runtime 32.0.0", "sp-std 14.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -13367,7 +13371,7 @@ dependencies = [ "parity-scale-codec", "sp-inherents 30.0.0", "sp-runtime 35.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -13465,7 +13469,7 @@ dependencies = [ "sp-core 29.0.0", "sp-externalities 0.26.0", "sp-std 14.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "trie-db", "trie-root", @@ -13490,7 +13494,7 @@ dependencies = [ "sp-core 31.0.0", "sp-externalities 0.27.0", "sp-std 14.0.0", - "thiserror", + "thiserror 1.0.68", "tracing", "trie-db", "trie-root", @@ -13514,7 +13518,7 @@ dependencies = [ "schnellru", "sp-core 32.0.0", "sp-externalities 0.28.0", - "thiserror", + "thiserror 1.0.68", "tracing", "trie-db", "trie-root", @@ -13535,7 +13539,7 @@ dependencies = [ "sp-runtime 32.0.0", "sp-std 14.0.0", "sp-version-proc-macro 13.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -13553,7 +13557,7 @@ dependencies = [ "sp-runtime 35.0.0", "sp-std 14.0.0", "sp-version-proc-macro 14.0.0", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -13900,7 +13904,7 @@ dependencies = [ "hyper 0.14.28", "log", "prometheus", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -13982,7 +13986,7 @@ dependencies = [ "subxt-lightclient", "subxt-macro", "subxt-metadata", - "thiserror", + "thiserror 1.0.68", "tokio-util", "tracing", "url", @@ -14006,7 +14010,7 @@ dependencies = [ "scale-typegen", "subxt-metadata", "syn 2.0.87", - "thiserror", + "thiserror 1.0.68", "tokio", ] @@ -14028,7 +14032,7 @@ dependencies = [ "serde_json", "smoldot", "smoldot-light", - "thiserror", + "thiserror 1.0.68", "tokio", "tokio-stream", "tracing", @@ -14122,7 +14126,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -14244,14 +14248,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", "once_cell", - "rustix 0.38.37", + "rustix 0.38.40", "windows-sys 0.59.0", ] @@ -14270,7 +14274,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ - "rustix 0.38.37", + "rustix 0.38.40", "windows-sys 0.59.0", ] @@ -14286,7 +14290,16 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.68", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -14300,6 +14313,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thousands" version = "0.2.0" @@ -14394,9 +14418,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -14630,9 +14654,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" +checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" dependencies = [ "bitflags 2.5.0", "bytes", @@ -14855,7 +14879,7 @@ dependencies = [ "rand", "smallvec", "socket2 0.4.10", - "thiserror", + "thiserror 1.0.68", "tinyvec", "tokio", "tracing", @@ -14876,7 +14900,7 @@ dependencies = [ "parking_lot 0.12.3", "resolv-conf", "smallvec", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", "trust-dns-proto", @@ -14945,7 +14969,7 @@ dependencies = [ "log", "rand", "sha1", - "thiserror", + "thiserror 1.0.68", "utf-8", ] @@ -15171,7 +15195,7 @@ dependencies = [ "rand_core 0.6.4", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -15355,7 +15379,7 @@ dependencies = [ "strum 0.24.1", "strum_macros 0.24.3", "tempfile", - "thiserror", + "thiserror 1.0.68", "wasm-opt-cxx-sys", "wasm-opt-sys", ] @@ -15620,7 +15644,7 @@ dependencies = [ "directories-next", "file-per-thread-logger 0.2.0", "log", - "rustix 0.38.37", + "rustix 0.38.40", "serde", "sha2 0.10.8", "toml 0.5.11", @@ -15665,7 +15689,7 @@ dependencies = [ "log", "object 0.30.4", "target-lexicon", - "thiserror", + "thiserror 1.0.68", "wasmparser 0.102.0", "wasmtime-cranelift-shared 8.0.1", "wasmtime-environ 8.0.1", @@ -15688,7 +15712,7 @@ dependencies = [ "log", "object 0.31.1", "target-lexicon", - "thiserror", + "thiserror 1.0.68", "wasmparser 0.110.0", "wasmtime-cranelift-shared 12.0.2", "wasmtime-environ 12.0.2", @@ -15740,7 +15764,7 @@ dependencies = [ "object 0.30.4", "serde", "target-lexicon", - "thiserror", + "thiserror 1.0.68", "wasmparser 0.102.0", "wasmtime-types 8.0.1", ] @@ -15759,7 +15783,7 @@ dependencies = [ "object 0.31.1", "serde", "target-lexicon", - "thiserror", + "thiserror 1.0.68", "wasm-encoder 0.31.1", "wasmparser 0.110.0", "wasmprinter", @@ -15775,7 +15799,7 @@ checksum = "fc8c8410c03a79073ea06806ccde3da4854c646bd646b3b2707b99b3746c3f70" dependencies = [ "cc", "cfg-if", - "rustix 0.38.37", + "rustix 0.38.40", "wasmtime-asm-macros 12.0.2", "wasmtime-versioned-export-macros", "windows-sys 0.48.0", @@ -15821,7 +15845,7 @@ dependencies = [ "log", "object 0.31.1", "rustc-demangle", - "rustix 0.38.37", + "rustix 0.38.40", "serde", "target-lexicon", "wasmtime-environ 12.0.2", @@ -15850,7 +15874,7 @@ checksum = "aef27ea6c34ef888030d15560037fe7ef27a5609fbbba8e1e3e41dc4245f5bb2" dependencies = [ "object 0.31.1", "once_cell", - "rustix 0.38.37", + "rustix 0.38.40", "wasmtime-versioned-export-macros", ] @@ -15918,7 +15942,7 @@ dependencies = [ "memoffset 0.9.1", "paste", "rand", - "rustix 0.38.37", + "rustix 0.38.40", "sptr", "wasm-encoder 0.31.1", "wasmtime-asm-macros 12.0.2", @@ -15937,7 +15961,7 @@ checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f" dependencies = [ "cranelift-entity 0.95.1", "serde", - "thiserror", + "thiserror 1.0.68", "wasmparser 0.102.0", ] @@ -15949,7 +15973,7 @@ checksum = "77943729d4b46141538e8d0b6168915dc5f88575ecdfea26753fd3ba8bab244a" dependencies = [ "cranelift-entity 0.99.2", "serde", - "thiserror", + "thiserror 1.0.68", "wasmparser 0.110.0", ] @@ -16053,7 +16077,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.37", + "rustix 0.38.40", ] [[package]] @@ -16642,7 +16666,7 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.68", "time", ] diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 36e5a27e1..869bc5dd1 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="entropy-client" -version ="0.3.0-rc.1" +version ="0.3.0" edition ="2021" authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' @@ -11,35 +11,37 @@ repository ='https://github.com/entropyxyz/entropy-core' [dependencies] sha3 ="0.10.8" serde ={ version="1.0", default-features=false, features=["derive"] } -entropy-shared={ version="0.3.0-rc.1", path="../shared", default-features=false } +entropy-shared={ version="0.3.0", path="../shared", default-features=false } subxt ={ version="0.35.3", default-features=false, features=["jsonrpsee"] } num ="0.4.3" -thiserror ="1.0.68" +thiserror ="2.0.3" futures ="0.3" sp-core ={ version="31.0.0", default-features=false, features=["full_crypto", "serde"] } tracing ="0.1.37" rand ={ version="0.8", default-features=false } +anyhow ="1.0.93" # Present when "full-client" feature is active -blake2 ={ version="0.10.4", optional=true } -rand_core ={ version="0.6.4", optional=true } -serde_json ={ version="1.0", optional=true } -x25519-dalek ={ version="2.0.1", features=["static_secrets"], optional=true } -entropy-protocol={ version="0.3.0-rc.1", path="../protocol", optional=true, default-features=false } -reqwest ={ version="0.12.9", features=["json", "stream"], optional=true } -base64 ={ version="0.22.0", optional=true } -synedrion ={ version="0.2.0-beta.0", optional=true } -hex ={ version="0.4.3", optional=true } -anyhow ="1.0.92" +blake2 ={ version="0.10.4", optional=true } +rand_core ={ version="0.6.4", optional=true } +serde_json ={ version="1.0", optional=true } +x25519-dalek ={ version="2.0.1", features=["static_secrets"], optional=true } +entropy-protocol ={ version="0.3.0", path="../protocol", optional=true, default-features=false } +reqwest ={ version="0.12.9", features=["json", "stream"], optional=true } +base64 ={ version="0.22.0", optional=true } +synedrion ={ version="0.2.0-beta.0", optional=true } +hex ={ version="0.4.3", optional=true } +parity-scale-codec={ version="3.6.3", default-features=false, optional=true } # Only for the browser js-sys={ version="0.3.72", optional=true } tokio ={ version="1.41", features=["time"] } [dev-dependencies] -serial_test ="3.1.1" +serial_test ="3.2.0" sp-keyring ="34.0.0" entropy-testing-utils={ path="../testing-utils" } +tdx-quote ={ version="0.0.1", features=["mock"] } [features] default=["native", "full-client-native"] @@ -63,6 +65,7 @@ full-client=[ "dep:base64", "dep:synedrion", "dep:hex", + "dep:parity-scale-codec", ] full-client-native=["full-client", "entropy-protocol/server"] full-client-wasm=["full-client", "entropy-protocol/wasm", "dep:js-sys"] diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index fcfbd8800..4ee7c5dae 100644 Binary files a/crates/client/entropy_metadata.scale and b/crates/client/entropy_metadata.scale differ diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 5e5ace6e0..062de590a 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -21,6 +21,7 @@ pub use crate::{ }; use anyhow::anyhow; pub use entropy_protocol::{sign_and_encrypt::EncryptedSignedMessage, KeyParams}; +use parity_scale_codec::Decode; use rand::Rng; use std::str::FromStr; pub use synedrion::KeyShare; @@ -39,7 +40,9 @@ use crate::{ }, client::entropy::staking_extension::events::{EndpointChanged, ThresholdAccountChanged}, substrate::{get_registered_details, submit_transaction_with_pair}, - user::{get_all_signers_from_chain, get_validators_not_signer_for_relay, UserSignatureRequest}, + user::{ + self, get_all_signers_from_chain, get_validators_not_signer_for_relay, UserSignatureRequest, + }, Hasher, }; @@ -210,14 +213,14 @@ pub async fn store_program( program: Vec, configuration_interface: Vec, auxiliary_data_interface: Vec, - oracle_data_pointer: Vec, + oracle_data_pointers: Vec>, version_number: u8, ) -> Result<::Hash, ClientError> { let set_program_tx = entropy::tx().programs().set_program( program, configuration_interface, auxiliary_data_interface, - oracle_data_pointer, + BoundedVec(oracle_data_pointers), version_number, ); let in_block = @@ -290,7 +293,7 @@ pub async fn get_accounts( pub async fn get_programs( api: &OnlineClient, rpc: &LegacyRpcMethods, -) -> Result::AccountId>)>, ClientError> { +) -> Result, ClientError> { let block_hash = rpc.chain_get_block_hash(None).await?.ok_or(ClientError::BlockHash)?; let storage_address = entropy::storage().programs().programs_iter(); @@ -341,8 +344,10 @@ pub async fn change_endpoint( rpc: &LegacyRpcMethods, user_keypair: sr25519::Pair, new_endpoint: String, + quote: Vec, ) -> anyhow::Result { - let change_endpoint_tx = entropy::tx().staking_extension().change_endpoint(new_endpoint.into()); + let change_endpoint_tx = + entropy::tx().staking_extension().change_endpoint(new_endpoint.into(), quote); let in_block = submit_transaction_with_pair(api, rpc, &user_keypair, &change_endpoint_tx, None).await?; let result_event = in_block @@ -358,13 +363,18 @@ pub async fn change_threshold_accounts( user_keypair: sr25519::Pair, new_tss_account: String, new_x25519_public_key: String, + new_pck_certificate_chain: Vec>, + quote: Vec, ) -> anyhow::Result { let tss_account = SubxtAccountId32::from_str(&new_tss_account)?; + let x25519_public_key = hex::decode(new_x25519_public_key)? + .try_into() + .map_err(|_| anyhow!("X25519 pub key needs to be 32 bytes"))?; let change_threshold_accounts = entropy::tx().staking_extension().change_threshold_accounts( tss_account, - hex::decode(new_x25519_public_key)? - .try_into() - .map_err(|_| anyhow!("X25519 pub key needs to be 32 bytes"))?, + x25519_public_key, + new_pck_certificate_chain, + quote, ); let in_block = submit_transaction_with_pair(api, rpc, &user_keypair, &change_threshold_accounts, None) @@ -414,3 +424,42 @@ async fn jumpstart_inner( Ok(()) } + +/// An extrinsic to indicate to the chain that it should expect an attestation from the `signer` at +/// some point in the near future. +/// +/// The returned `nonce` must be used when generating a `quote` for the chain. +/// +/// This wraps [user::request_attestation] to convert the error to a [ClientError] consistant with +/// other functions in this module +#[tracing::instrument( + skip_all, + fields( + attestee = ?attestee.public(), + ) +)] +pub async fn request_attestation( + api: &OnlineClient, + rpc: &LegacyRpcMethods, + attestee: &sr25519::Pair, +) -> Result<[u8; 32], ClientError> { + Ok(user::request_attestation(api, rpc, attestee).await?) +} + +/// Get oracle data headings +/// This is useful for program developers to know what oracle data is available +pub async fn get_oracle_headings( + api: &OnlineClient, + _rpc: &LegacyRpcMethods, +) -> Result, ClientError> { + let storage_address = entropy::storage().oracle().oracle_data_iter(); + let mut iter = api.storage().at_latest().await?.iter(storage_address).await?; + let mut headings = Vec::new(); + while let Some(Ok(kv)) = iter.next().await { + // Key is: storage_address || 128 bit hash || key + let mut input = &kv.key_bytes[32 + 16 + 1..]; + let heading = String::decode(&mut input)?; + headings.push(heading); + } + Ok(headings) +} diff --git a/crates/client/src/errors.rs b/crates/client/src/errors.rs index 24705ae55..c2f4ab241 100644 --- a/crates/client/src/errors.rs +++ b/crates/client/src/errors.rs @@ -49,6 +49,17 @@ pub enum SubgroupGetError { JoinError(#[from] tokio::task::JoinError), } +/// An error when making an attestation request +#[derive(Debug, Error)] +pub enum AttestationRequestError { + #[error("Generic Substrate error: {0}")] + GenericSubstrate(#[from] subxt::error::Error), + #[error("Substrate client: {0}")] + SubstrateClient(#[from] crate::substrate::SubstrateError), + #[error("Recieved nonce is not 32 bytes")] + BadNonce, +} + #[cfg(feature = "full-client")] #[derive(Debug, Error)] pub enum ClientError { @@ -108,4 +119,8 @@ pub enum ClientError { BadVerifyingKeyLength, #[error("There are no validators which can act as a relay node for signature requests")] NoNonSigningValidators, + #[error("Scale decode: {0}")] + Codec(#[from] parity_scale_codec::Error), + #[error("Attestation request: {0}")] + AttestationRequest(#[from] AttestationRequestError), } diff --git a/crates/client/src/tests.rs b/crates/client/src/tests.rs index b7e2f81d4..c5773b6bb 100644 --- a/crates/client/src/tests.rs +++ b/crates/client/src/tests.rs @@ -11,18 +11,26 @@ use crate::{ }, get_api, get_rpc, EntropyConfig, }, - change_endpoint, change_threshold_accounts, register, remove_program, store_program, + change_endpoint, change_threshold_accounts, get_oracle_headings, register, remove_program, + request_attestation, store_program, substrate::query_chain, update_programs, }; + +use entropy_shared::{QuoteContext, QuoteInputData}; use entropy_testing_utils::{ - constants::{TEST_PROGRAM_WASM_BYTECODE, TSS_ACCOUNTS}, + constants::{TEST_PROGRAM_WASM_BYTECODE, TSS_ACCOUNTS, X25519_PUBLIC_KEYS}, helpers::{ derive_mock_pck_verifying_key, encode_verifying_key, spawn_tss_nodes_and_start_chain, }, + jump_start_network, spawn_testing_validators, substrate_context::test_context_stationary, ChainSpecType, }; +use rand::{ + rngs::{OsRng, StdRng}, + SeedableRng, +}; use serial_test::serial; use sp_core::{sr25519, Pair, H256}; use sp_keyring::AccountKeyring; @@ -37,7 +45,30 @@ async fn test_change_endpoint() { let api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); - let result = change_endpoint(&api, &rpc, one.into(), "new_endpoint".to_string()).await.unwrap(); + // By using this `Alice` account we can skip the `request_attestation` step since this is + // already set up at genesis. + let tss_account_id = &TSS_ACCOUNTS[0]; + let x25519_public_key = X25519_PUBLIC_KEYS[0]; + + // This nonce is what was used in the genesis config for `Alice`. + let nonce = [0; 32]; + + let quote = { + let signing_key = tdx_quote::SigningKey::random(&mut OsRng); + let public_key = sr25519::Public(tss_account_id.0); + + let input_data = + QuoteInputData::new(public_key, x25519_public_key, nonce, QuoteContext::ChangeEndpoint); + + let mut pck_seeder = StdRng::from_seed(public_key.0); + let pck = tdx_quote::SigningKey::random(&mut pck_seeder); + + tdx_quote::Quote::mock(signing_key.clone(), pck, input_data.0).as_bytes().to_vec() + }; + + let result = + change_endpoint(&api, &rpc, one.into(), "new_endpoint".to_string(), quote).await.unwrap(); + assert_eq!( format!("{:?}", result), format!( @@ -58,22 +89,69 @@ async fn test_change_threshold_accounts() { let api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); - let x25519_public_key = [0u8; 32]; - let result = change_threshold_accounts( + + // We need to use an account that's not a validator (so not our default development/test accounts) + // otherwise we're not able to update the TSS and X25519 keys for our existing validator. + let non_validator_seed = + "gospel prosper cactus remember snap enact refuse review bind rescue guard sock"; + let (tss_signer_pair, x25519_secret) = + entropy_testing_utils::get_signer_and_x25519_secret_from_mnemonic(non_validator_seed) + .unwrap(); + + let tss_public_key = tss_signer_pair.signer().public(); + let x25519_public_key = x25519_dalek::PublicKey::from(&x25519_secret); + + // We need to give our new TSS account some funds before it can request an attestation. + let dest = tss_signer_pair.account_id().clone().into(); + let amount = 10 * entropy_shared::MIN_BALANCE; + let balance_transfer_tx = entropy::tx().balances().transfer_allow_death(dest, amount); + let _transfer_result = crate::substrate::submit_transaction_with_pair( &api, &rpc, - one.into(), - AccountId32(one.pair().public().0.into()).to_string(), - hex::encode(x25519_public_key), + &one.pair(), + &balance_transfer_tx, + None, ) .await .unwrap(); - let provisioning_certification_key = { - let key = derive_mock_pck_verifying_key(&TSS_ACCOUNTS[0]); - BoundedVec(encode_verifying_key(&key).unwrap().to_vec()) + // When we request an attestation we get a nonce back that we must use when generating our quote. + let nonce = request_attestation(&api, &rpc, tss_signer_pair.signer()).await.unwrap(); + let nonce: [u8; 32] = nonce.try_into().unwrap(); + + let mut pck_seeder = StdRng::from_seed(tss_public_key.0.clone()); + let pck = tdx_quote::SigningKey::random(&mut pck_seeder); + let encoded_pck = encode_verifying_key(&pck.verifying_key()).unwrap().to_vec(); + + // Our runtime is using the mock `PckCertChainVerifier`, which means that the expected + // "certificate" basically is just our TSS account ID. This account needs to match the one + // used to sign the following `quote`. + let pck_certificate_chain = vec![tss_public_key.0.to_vec()]; + + let quote = { + let input_data = entropy_shared::QuoteInputData::new( + tss_public_key, + *x25519_public_key.as_bytes(), + nonce, + QuoteContext::ChangeThresholdAccounts, + ); + + let signing_key = tdx_quote::SigningKey::random(&mut OsRng); + tdx_quote::Quote::mock(signing_key.clone(), pck.clone(), input_data.0).as_bytes().to_vec() }; + let result = change_threshold_accounts( + &api, + &rpc, + one.into(), + tss_public_key.to_string(), + hex::encode(*x25519_public_key.as_bytes()), + pck_certificate_chain, + quote, + ) + .await + .unwrap(); + assert_eq!( format!("{:?}", result), format!( @@ -81,10 +159,10 @@ async fn test_change_threshold_accounts() { events::ThresholdAccountChanged( AccountId32(one.pair().public().0), ServerInfo { - tss_account: AccountId32(one.pair().public().0), - x25519_public_key, + tss_account: AccountId32(tss_public_key.0), + x25519_public_key: *x25519_public_key.as_bytes(), endpoint: "127.0.0.1:3001".as_bytes().to_vec(), - provisioning_certification_key, + provisioning_certification_key: BoundedVec(encoded_pck), } ) ) @@ -183,3 +261,22 @@ async fn test_remove_program_reference_counter() { // We can now remove the program because no-one is using it remove_program(&api, &rpc, &program_owner, program_pointer).await.unwrap(); } + +#[tokio::test] +#[serial] +async fn test_get_oracle_headings() { + let force_authoring = true; + let substrate_context = &test_node_process_testing_state(force_authoring).await[0]; + let api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + let mut current_block = 0; + while current_block < 2 { + let finalized_head = rpc.chain_get_finalized_head().await.unwrap(); + current_block = rpc.chain_get_header(Some(finalized_head)).await.unwrap().unwrap().number; + } + + let headings = get_oracle_headings(&api, &rpc).await.unwrap(); + + assert_eq!(headings, vec!["block_number_entropy".to_string()]); +} diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index 9b4aa101b..154924c42 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -15,13 +15,14 @@ //! User interaction related use crate::{ chain_api::{entropy, EntropyConfig}, - substrate::query_chain, + substrate::{query_chain, submit_transaction_with_pair}, }; use entropy_shared::{user::ValidatorInfo, BlockNumber, HashingAlgorithm}; use serde::{Deserialize, Serialize}; +use sp_core::{sr25519, Pair}; use subxt::{backend::legacy::LegacyRpcMethods, OnlineClient}; -pub use crate::errors::SubgroupGetError; +pub use crate::errors::{AttestationRequestError, SubgroupGetError}; /// Represents an unparsed, transaction request coming from the client. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -143,3 +144,33 @@ pub async fn get_all_signers_from_chain( Ok(all_signers) } + +/// An extrinsic to indicate to the chain that it should expect an attestation from the `signer` at +/// some point in the near future. +/// +/// The returned `nonce` must be used when generating a `quote` for the chain. +#[tracing::instrument( + skip_all, + fields( + attestee = ?attestee.public(), + ) +)] +pub async fn request_attestation( + api: &OnlineClient, + rpc: &LegacyRpcMethods, + attestee: &sr25519::Pair, +) -> Result<[u8; 32], AttestationRequestError> { + tracing::debug!("{} is requesting an attestation.", attestee.public()); + + let request_attestation = entropy::tx().attestation().request_attestation(); + + let result = + submit_transaction_with_pair(api, rpc, attestee, &request_attestation, None).await?; + let result_event = result + .find_first::()? + .ok_or(crate::errors::SubstrateError::NoEvent)?; + + let nonce = result_event.0.try_into().map_err(|_| AttestationRequestError::BadNonce)?; + + Ok(nonce) +} diff --git a/crates/kvdb/Cargo.toml b/crates/kvdb/Cargo.toml index 5efcae38b..a379eec23 100644 --- a/crates/kvdb/Cargo.toml +++ b/crates/kvdb/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="entropy-kvdb" description="Encrypted key-value database for the Entropy Theshold Signing Server" -version ="0.3.0-rc.1" +version ="0.3.0" authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -12,7 +12,7 @@ edition ='2021' # Common rand ={ version="0.8", default-features=false } serde ={ version="1.0", features=["derive"] } -thiserror="1.0.68" +thiserror="2.0.3" hex ="0.4.3" # Substrate @@ -32,7 +32,7 @@ tracing={ version="0.1", default-features=false } # Misc sled ="0.34.7" bincode ="1.3.3" -entropy-protocol={ version="0.3.0-rc.1", path="../protocol" } +entropy-protocol={ version="0.3.0", path="../protocol" } [dev-dependencies] -serial_test="3.1.1" +serial_test="3.2.0" diff --git a/crates/protocol/Cargo.toml b/crates/protocol/Cargo.toml index 470013cff..572a14119 100644 --- a/crates/protocol/Cargo.toml +++ b/crates/protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='entropy-protocol' -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] description="Entropy Signing and DKG protocol execution and transport logic" homepage ='https://entropy.xyz/' @@ -10,7 +10,7 @@ edition ='2021' [dependencies] async-trait ="0.1.83" -entropy-shared ={ version="0.3.0-rc.1", path="../shared", default-features=false } +entropy-shared ={ version="0.3.0", path="../shared", default-features=false } synedrion ={ version="0.2.0-beta.0" } serde ={ version="1.0", features=["derive"], default-features=false } subxt ={ version="0.35.3", default-features=false } @@ -20,7 +20,7 @@ x25519-dalek ={ version="2.0.1", features=["static_secrets"] } futures ="0.3" hex ="0.4.3" blake2 ="0.10.4" -thiserror ="1.0.68" +thiserror ="2.0.3" snow ="0.9.6" getrandom ={ version="0.2", features=["js"] } rand_core ={ version="0.6.4", features=["getrandom"] } @@ -34,7 +34,7 @@ hpke-rs-rust-crypto="0.2.0" num ="0.4.3" # Used only with the `server` feature to implement the WsConnection trait -axum ={ version="0.7.7", features=["ws"], optional=true } +axum ={ version="0.7.9", features=["ws"], optional=true } tokio-tungstenite={ version="0.24.0", optional=true } # Used only with the `wasm` feature @@ -47,9 +47,9 @@ base64 ={ version="0.22.1", optional=true } schnorrkel ={ version="0.11.4", default-features=false, features=["std"], optional=true } [dev-dependencies] -serial_test="3.1.1" +serial_test="3.2.0" sp-keyring ="34.0.0" -anyhow ="1.0.92" +anyhow ="1.0.93" num_cpus ="1.16.0" [features] diff --git a/crates/protocol/src/execute_protocol.rs b/crates/protocol/src/execute_protocol.rs index 0e2731f67..89999a267 100644 --- a/crates/protocol/src/execute_protocol.rs +++ b/crates/protocol/src/execute_protocol.rs @@ -40,7 +40,7 @@ use crate::{ KeyParams, KeyShareWithAuxInfo, PartyId, SessionId, Subsession, }; -use std::collections::BTreeSet; +use std::collections::{BTreeSet, VecDeque}; pub type ChannelIn = mpsc::Receiver; pub type ChannelOut = Broadcaster; @@ -134,6 +134,7 @@ where // Receive and process incoming messages let (process_tx, mut process_rx) = mpsc::channel(1024); + let mut messages_for_next_subprotocol = VecDeque::new(); while !session_arc.can_finalize(&accum)? { tokio::select! { // Incoming message from remote peer @@ -160,7 +161,7 @@ where } } else { tracing::warn!("Got protocol message with incorrect session ID - putting back in queue"); - tx.incoming_sender.send(message).await?; + messages_for_next_subprotocol.push_back(message); } } else { tracing::warn!("Got verifying key during protocol - ignoring"); @@ -176,6 +177,10 @@ where } } + for message in messages_for_next_subprotocol { + tx.incoming_sender.send(message).await?; + } + // Get session back out of Arc let session_inner = Arc::try_unwrap(session_arc).map_err(|_| GenericProtocolError::ArcUnwrapError)?; diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs index 27770df46..ab1023e0b 100644 --- a/crates/protocol/src/lib.rs +++ b/crates/protocol/src/lib.rs @@ -33,7 +33,7 @@ use std::{ use blake2::{Blake2s256, Digest}; use errors::{ProtocolExecutionErr, VerifyingKeyError}; -use serde::{Deserialize, Serialize}; +use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use sp_core::{sr25519, Pair}; use subxt::utils::AccountId32; use synedrion::{ @@ -148,6 +148,19 @@ pub struct RecoverableSignature { pub recovery_id: RecoveryId, } +// This cannot be derived because [RecoveryId] does not implement Serialize +impl Serialize for RecoverableSignature { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_struct("RecoverableSignature", 2)?; + state.serialize_field("signature", &self.signature)?; + state.serialize_field("recovery_id", &self.recovery_id.to_byte())?; + state.end() + } +} + impl RecoverableSignature { pub fn to_rsv_bytes(&self) -> [u8; 65] { let mut res = [0u8; 65]; diff --git a/crates/shared/Cargo.toml b/crates/shared/Cargo.toml index 2c5aa8698..10cd726f5 100644 --- a/crates/shared/Cargo.toml +++ b/crates/shared/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="entropy-shared" description="Shared types used by the Entropy chain node and Entropy Threshold Signing Server" -version ="0.3.0-rc.1" +version ="0.3.0" authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -10,7 +10,7 @@ edition ='2021' [dependencies] codec ={ package="parity-scale-codec", version="3.0.0", default-features=false } -scale-info ={ version='2.11.5', default-features=false, features=['derive'] } +scale-info ={ version='2.11.6', default-features=false, features=['derive'] } serde ={ version="1.0", default-features=false, features=["derive"] } serde_derive="1.0.147" strum ="0.26.3" diff --git a/crates/shared/device_key_proxy.wasm b/crates/shared/device_key_proxy.wasm index b7daf3b12..1e50cb3d7 100755 Binary files a/crates/shared/device_key_proxy.wasm and b/crates/shared/device_key_proxy.wasm differ diff --git a/crates/shared/src/types.rs b/crates/shared/src/types.rs index 803c9f57c..d6156a0be 100644 --- a/crates/shared/src/types.rs +++ b/crates/shared/src/types.rs @@ -123,17 +123,29 @@ impl QuoteInputData { tss_account_id: T, x25519_public_key: X25519PublicKey, nonce: [u8; 32], - block_number: u32, + context: QuoteContext, ) -> Self { let mut hasher = Blake2b512::new(); hasher.update(tss_account_id.encode()); hasher.update(x25519_public_key); hasher.update(nonce); - hasher.update(block_number.to_be_bytes()); + hasher.update(context.encode()); Self(hasher.finalize().into()) } } +/// An indicator as to the context in which a quote is intended to be used +#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum QuoteContext { + /// To be used in the `validate` extrinsic + Validate, + /// To be used in the `change_endpoint` extrinsic + ChangeEndpoint, + /// To be used in the `change_threshold_accounts` extrinsic + ChangeThresholdAccounts, +} + /// A trait for types which can handle attestation requests. #[cfg(not(feature = "wasm"))] pub trait AttestationHandler { @@ -143,6 +155,7 @@ pub trait AttestationHandler { x25519_public_key: X25519PublicKey, provisioning_certification_key: BoundedVecEncodedVerifyingKey, quote: Vec, + context: QuoteContext, ) -> Result<(), sp_runtime::DispatchError>; /// Indicate to the attestation handler that a quote is desired. @@ -160,6 +173,7 @@ impl AttestationHandler for () { _x25519_public_key: X25519PublicKey, _provisioning_certification_key: BoundedVecEncodedVerifyingKey, _quote: Vec, + _context: QuoteContext, ) -> Result<(), sp_runtime::DispatchError> { Ok(()) } diff --git a/crates/test-cli/Cargo.toml b/crates/test-cli/Cargo.toml index e4e69ec7b..ef4fdba17 100644 --- a/crates/test-cli/Cargo.toml +++ b/crates/test-cli/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="entropy-test-cli" description="Simple command line interface client for testing Entropy" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -9,15 +9,18 @@ repository ='https://github.com/entropyxyz/entropy-core' edition ='2021' [dependencies] -entropy-client={ version="0.3.0-rc.1", path="../client" } -clap ={ version="4.5.20", features=["derive"] } +entropy-client={ version="0.3.0", path="../client" } +clap ={ version="4.5.21", features=["derive"] } colored ="2.0.4" subxt ="0.35.3" sp-core ="31.0.0" -anyhow ="1.0.92" +anyhow ="1.0.93" tokio ={ version="1.41", features=["macros", "rt-multi-thread", "io-util", "process"] } hex ="0.4.3" bincode ="1.3.3" x25519-dalek ="2.0.1" sp-runtime ={ version="32.0.0", default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../shared" } +entropy-shared={ version="0.3.0", path="../shared" } +serde_json ="1.0.133" +serde ={ version="1.0.215", features=["derive"] } +reqwest ="0.12.9" diff --git a/crates/test-cli/src/lib.rs b/crates/test-cli/src/lib.rs index 9bc063167..8b76fe5f8 100644 --- a/crates/test-cli/src/lib.rs +++ b/crates/test-cli/src/lib.rs @@ -20,19 +20,21 @@ use colored::Colorize; use entropy_client::{ chain_api::{ entropy::runtime_types::{ - bounded_collections::bounded_vec::BoundedVec, pallet_registry::pallet::ProgramInstance, + bounded_collections::bounded_vec::BoundedVec, + pallet_programs::pallet::ProgramInfo, + pallet_registry::pallet::{ProgramInstance, RegisteredInfo}, }, EntropyConfig, }, client::{ - change_endpoint, change_threshold_accounts, get_accounts, get_api, get_programs, get_rpc, - jumpstart_network, register, remove_program, sign, store_program, update_programs, - VERIFYING_KEY_LENGTH, + change_endpoint, change_threshold_accounts, get_accounts, get_api, get_oracle_headings, + get_programs, get_rpc, jumpstart_network, register, remove_program, sign, store_program, + update_programs, VERIFYING_KEY_LENGTH, }, }; pub use entropy_shared::PROGRAM_VERSION_NUMBER; use sp_core::{sr25519, Hasher, Pair}; -use sp_runtime::traits::BlakeTwo256; +use sp_runtime::{traits::BlakeTwo256, Serialize}; use std::{fs, path::PathBuf}; use subxt::{ backend::legacy::LegacyRpcMethods, @@ -46,7 +48,7 @@ use subxt::{ about = "CLI tool for testing Entropy", long_about = "This is a CLI test client.\nIt requires a running deployment of Entropy with at least two chain nodes and two TSS servers." )] -struct Cli { +pub struct Cli { #[clap(subcommand)] command: CliCommand, /// The chain endpoint to use. @@ -57,6 +59,9 @@ struct Cli { /// priority. #[arg(short, long)] chain_endpoint: Option, + /// Whether to give command output as JSON. Defaults to false. + #[arg(short, long)] + pub json: bool, } #[derive(Subcommand, Debug, Clone)] @@ -145,6 +150,11 @@ enum CliCommand { ChangeEndpoint { /// New endpoint to change to (ex. "127.0.0.1:3001") new_endpoint: String, + /// The Intel TDX quote used to prove that this TSS is running on TDX hardware. + /// + /// The quote format is specified in: + /// https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/Intel_TDX_DCAP_Quoting_Library_API.pdf + quote: String, /// The mnemonic for the validator stash account to use for the call, should be stash address #[arg(short, long)] mnemonic_option: Option, @@ -155,6 +165,13 @@ enum CliCommand { new_tss_account: String, /// New x25519 public key new_x25519_public_key: String, + /// The new Provisioning Certification Key (PCK) certificate chain to be used for the TSS. + new_pck_certificate_chain: Vec, + /// The Intel TDX quote used to prove that this TSS is running on TDX hardware. + /// + /// The quote format is specified in: + /// https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/Intel_TDX_DCAP_Quoting_Library_API.pdf + quote: String, /// The mnemonic for the validator stash account to use for the call, should be stash address #[arg(short, long)] mnemonic_option: Option, @@ -172,17 +189,36 @@ enum CliCommand { #[arg(short, long)] mnemonic_option: Option, }, + /// Get headings of oracle data + /// + /// This is useful for program developers to know what oracle data is available. + GetOracleHeadings, + /// Request a TDX quote from a TSS server and write it to a file. + GetTdxQuote { + /// The socket address of the TS server, eg: `127.0.0.1:3002` + tss_endpoint: String, + /// The filename to write the quote to. Defaults to `quote.dat` + #[arg(long)] + output_filename: Option, + }, +} + +impl Cli { + fn log(&self, text: String) { + if !self.json { + println!("{text}"); + } + } } pub async fn run_command( + cli: Cli, program_file_option: Option, config_interface_file_option: Option, aux_data_interface_file_option: Option, program_version_number_option: Option, ) -> anyhow::Result { - let cli = Cli::parse(); - - let endpoint_addr = cli.chain_endpoint.unwrap_or_else(|| { + let endpoint_addr = cli.chain_endpoint.clone().unwrap_or_else(|| { std::env::var("ENTROPY_DEVNET").unwrap_or("ws://localhost:9944".to_string()) }); @@ -191,7 +227,7 @@ pub async fn run_command( let api = get_api(&endpoint_addr).await?; let rpc = get_rpc(&endpoint_addr).await?; - match cli.command { + match cli.command.clone() { CliCommand::Register { mnemonic_option, programs, program_version_numbers } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { mnemonic_option @@ -201,7 +237,7 @@ pub async fn run_command( let program_keypair = ::from_string(&mnemonic, None)?; let program_account = SubxtAccountId32(program_keypair.public().0); - println!("Program account: {}", program_keypair.public()); + cli.log(format!("Program account: {}", program_keypair.public())); let mut programs_info = vec![]; @@ -230,7 +266,12 @@ pub async fn run_command( ) .await?; - Ok(format!("Verifying key: {},\n{:?}", hex::encode(verifying_key), registered_info)) + let verifying_key = hex::encode(verifying_key); + if cli.json { + Ok(serde_json::to_string_pretty(&verifying_key)?) + } else { + Ok(format!("Verifying key: {},\n{:?}", verifying_key, registered_info)) + } }, CliCommand::Sign { signature_verifying_key, message, auxilary_data, mnemonic_option } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { @@ -241,7 +282,7 @@ pub async fn run_command( // If an account name is not provided, use the Alice key let user_keypair = ::from_string(&mnemonic, None)?; - println!("User account for current call: {}", user_keypair.public()); + cli.log(format!("User account for current call: {}", user_keypair.public())); let auxilary_data = if let Some(data) = auxilary_data { Some(hex::decode(data)?) } else { None }; @@ -260,7 +301,12 @@ pub async fn run_command( auxilary_data, ) .await?; - Ok(format!("Message signed: {:?}", recoverable_signature)) + + if cli.json { + Ok(serde_json::to_string_pretty(&recoverable_signature)?) + } else { + Ok(format!("Message signed: {:?}", recoverable_signature)) + } }, CliCommand::StoreProgram { mnemonic_option, @@ -275,7 +321,7 @@ pub async fn run_command( passed_mnemonic.expect("No Mnemonic set") }; let keypair = ::from_string(&mnemonic, None)?; - println!("Storing program using account: {}", keypair.public()); + cli.log(format!("Storing program using account: {}", keypair.public())); let program = match program_file { Some(file_name) => fs::read(file_name)?, @@ -284,16 +330,18 @@ pub async fn run_command( let config_interface = match config_interface_file { Some(file_name) => fs::read(file_name)?, - None => fs::read( - config_interface_file_option.expect("No config interface file passed"), - )?, + None => match config_interface_file_option { + Some(config_interface_file) => fs::read(config_interface_file)?, + None => Vec::new(), + }, }; let aux_data_interface = match aux_data_interface_file { Some(file_name) => fs::read(file_name)?, - None => fs::read( - aux_data_interface_file_option.expect("No aux data interface file passed"), - )?, + None => match aux_data_interface_file_option { + Some(aux_data_interface_file) => fs::read(aux_data_interface_file)?, + None => Vec::new(), + }, }; let program_version_number = match program_version_number_option { @@ -312,7 +360,14 @@ pub async fn run_command( program_version_number, ) .await?; - Ok(format!("Program stored: {}", hex::encode(hash))) + + let hash = hex::encode(hash); + + if cli.json { + Ok(serde_json::to_string_pretty(&hash)?) + } else { + Ok(format!("Program stored: {}", hex::encode(hash))) + } }, CliCommand::RemoveProgram { mnemonic_option, hash } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { @@ -321,7 +376,7 @@ pub async fn run_command( passed_mnemonic.expect("No Mnemonic set") }; let keypair = ::from_string(&mnemonic, None)?; - println!("Removing program using account: {}", keypair.public()); + cli.log(format!("Removing program using account: {}", keypair.public())); let hash: [u8; 32] = hex::decode(hash)? .try_into() @@ -329,7 +384,11 @@ pub async fn run_command( remove_program(&api, &rpc, &keypair, H256(hash)).await?; - Ok("Program removed".to_string()) + if cli.json { + Ok("{}".to_string()) + } else { + Ok("Program removed".to_string()) + } }, CliCommand::UpdatePrograms { signature_verifying_key, @@ -343,7 +402,7 @@ pub async fn run_command( passed_mnemonic.expect("No Mnemonic set") }; let program_keypair = ::from_string(&mnemonic, None)?; - println!("Program account: {}", program_keypair.public()); + cli.log(format!("Program account: {}", program_keypair.public())); let mut programs_info = Vec::new(); @@ -370,70 +429,77 @@ pub async fn run_command( update_programs(&api, &rpc, verifying_key, &program_keypair, BoundedVec(programs_info)) .await?; - Ok("Programs updated".to_string()) + if cli.json { + Ok("{}".to_string()) + } else { + Ok("Programs updated".to_string()) + } }, CliCommand::Status => { let accounts = get_accounts(&api, &rpc).await?; - println!( - "There are {} registered Entropy accounts.\n", - accounts.len().to_string().green() - ); - if !accounts.is_empty() { + let programs = get_programs(&api, &rpc).await?; + + if !cli.json { println!( - "{:<64} {:<12} Programs:", - "Verifying key:".green(), - "Visibility:".purple(), + "There are {} registered Entropy accounts.\n", + accounts.len().to_string().green() ); - for (account_id, info) in accounts { - println!( - "{} {}", - hex::encode(account_id).green(), - format!( - "{:?}", - info.programs_data - .0 - .iter() - .map(|program_instance| format!( - "{}", - program_instance.program_pointer - )) - .collect::>() - ) - .white(), - ); + if !accounts.is_empty() { + println!("{:<66} Programs:", "Verifying key:".green()); + for (account_id, info) in accounts.iter() { + println!( + "{} {}", + hex::encode(account_id).green(), + format!( + "{:?}", + info.programs_data + .0 + .iter() + .map(|program_instance| format!( + "{}", + program_instance.program_pointer + )) + .collect::>() + ) + .white(), + ); + } } - } - let programs = get_programs(&api, &rpc).await?; + println!("\nThere are {} stored programs\n", programs.len().to_string().green()); - println!("\nThere are {} stored programs\n", programs.len().to_string().green()); - - if !programs.is_empty() { - println!( - "{:<64} {:<48} {:<11} {:<14} {} {}", - "Hash".blue(), - "Stored by:".green(), - "Times used:".purple(), - "Size in bytes:".cyan(), - "Configurable?".yellow(), - "Has auxiliary?".yellow(), - ); - for (hash, program_info) in programs { + if !programs.is_empty() { println!( - "{} {} {:>11} {:>14} {:<13} {}", - hex::encode(hash), - program_info.deployer, - program_info.ref_counter, - program_info.bytecode.len(), - !program_info.configuration_schema.is_empty(), - !program_info.auxiliary_data_schema.is_empty(), + "{:<64} {:<48} {:<11} {:<14} {} {}", + "Hash".blue(), + "Stored by:".green(), + "Times used:".purple(), + "Size in bytes:".cyan(), + "Configurable?".yellow(), + "Has auxiliary?".yellow(), ); + for (hash, program_info) in programs.iter() { + println!( + "{} {} {:>11} {:>14} {:<13} {}", + hex::encode(hash), + program_info.deployer, + program_info.ref_counter, + program_info.bytecode.len(), + !program_info.configuration_schema.is_empty(), + !program_info.auxiliary_data_schema.is_empty(), + ); + } } } - Ok("Got status".to_string()) + if cli.json { + let output = StatusOutput::new(accounts, programs); + Ok(serde_json::to_string_pretty(&output)?) + } else { + Ok("Got status".to_string()) + } }, - CliCommand::ChangeEndpoint { new_endpoint, mnemonic_option } => { + CliCommand::ChangeEndpoint { new_endpoint, quote, mnemonic_option } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { mnemonic_option } else { @@ -441,15 +507,23 @@ pub async fn run_command( }; let user_keypair = ::from_string(&mnemonic, None)?; - println!("User account for current call: {}", user_keypair.public()); + cli.log(format!("User account for current call: {}", user_keypair.public())); + + let result_event = + change_endpoint(&api, &rpc, user_keypair, new_endpoint, quote.into()).await?; + cli.log(format!("Event result: {:?}", result_event)); - let result_event = change_endpoint(&api, &rpc, user_keypair, new_endpoint).await?; - println!("Event result: {:?}", result_event); - Ok("Endpoint changed".to_string()) + if cli.json { + Ok("{}".to_string()) + } else { + Ok("Endpoint changed".to_string()) + } }, CliCommand::ChangeThresholdAccounts { new_tss_account, new_x25519_public_key, + new_pck_certificate_chain, + quote, mnemonic_option, } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { @@ -458,19 +532,27 @@ pub async fn run_command( passed_mnemonic.expect("No Mnemonic set") }; let user_keypair = ::from_string(&mnemonic, None)?; - println!("User account for current call: {}", user_keypair.public()); + cli.log(format!("User account for current call: {}", user_keypair.public())); + let new_pck_certificate_chain = + new_pck_certificate_chain.iter().cloned().map(|i| i.into()).collect::<_>(); let result_event = change_threshold_accounts( &api, &rpc, user_keypair, new_tss_account, new_x25519_public_key, + new_pck_certificate_chain, + quote.into(), ) .await?; - println!("Event result: {:?}", result_event); + cli.log(format!("Event result: {:?}", result_event)); - Ok("Threshold accounts changed".to_string()) + if cli.json { + Ok("{}".to_string()) + } else { + Ok("Threshold accounts changed".to_string()) + } }, CliCommand::JumpstartNetwork { mnemonic_option } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { @@ -480,11 +562,31 @@ pub async fn run_command( }; let signer = ::from_string(&mnemonic, None)?; - println!("Account being used for jumpstart: {}", signer.public()); + cli.log(format!("Account being used for jumpstart: {}", signer.public())); jumpstart_network(&api, &rpc, signer).await?; - Ok("Succesfully jumpstarted network.".to_string()) + if cli.json { + Ok("{}".to_string()) + } else { + Ok("Succesfully jumpstarted network.".to_string()) + } + }, + CliCommand::GetOracleHeadings => { + let headings = get_oracle_headings(&api, &rpc).await?; + Ok(serde_json::to_string_pretty(&headings)?) + }, + CliCommand::GetTdxQuote { tss_endpoint, output_filename } => { + let quote_bytes = + reqwest::get(format!("http://{}/attest", tss_endpoint)).await?.bytes().await?; + let output_filename = output_filename.unwrap_or("quote.dat".into()); + + std::fs::write(&output_filename, quote_bytes)?; + if cli.json { + Ok("{}".to_string()) + } else { + Ok(format!("Succesfully written quote to {}", output_filename)) + } }, } } @@ -582,7 +684,7 @@ impl Program { Ok(hash) => Ok(Self::new(hash, configuration)), Err(error) => { if error.to_string().ends_with("ProgramAlreadySet") { - println!("Program is already stored - using existing one"); + // Use existing program as it is already stored let hash = BlakeTwo256::hash(&program_bytecode); Ok(Self::new(H256(hash.into()), configuration)) } else { @@ -592,3 +694,22 @@ impl Program { } } } + +#[derive(Serialize)] +/// Output from the status command +struct StatusOutput { + accounts: Vec, + programs: Vec, +} + +impl StatusOutput { + fn new(accounts: Vec<([u8; 33], RegisteredInfo)>, programs: Vec<(H256, ProgramInfo)>) -> Self { + let accounts = accounts + .into_iter() + .map(|(verifying_key, _registered_info)| hex::encode(verifying_key)) + .collect(); + let programs = + programs.into_iter().map(|(hash, _program_info)| hex::encode(hash.0)).collect(); + Self { accounts, programs } + } +} diff --git a/crates/test-cli/src/main.rs b/crates/test-cli/src/main.rs index e554a995e..5e176d074 100644 --- a/crates/test-cli/src/main.rs +++ b/crates/test-cli/src/main.rs @@ -14,22 +14,30 @@ // along with this program. If not, see . //! Simple CLI to test registering, updating programs and signing -use std::time::Instant; - +use clap::Parser; use colored::Colorize; -use entropy_test_cli::run_command; +use entropy_test_cli::{run_command, Cli}; +use std::time::Instant; #[tokio::main] async fn main() -> anyhow::Result<()> { let now = Instant::now(); - match run_command(None, None, None, None).await { + let cli = Cli::parse(); + let json_ouput = cli.json; + match run_command(cli, None, None, None, None).await { Ok(output) => { - println!("Success: {}", output.green()); - println!("{}", format!("That took {:?}", now.elapsed()).yellow()); + if json_ouput { + println!("{}", output); + } else { + println!("Success: {}", output.green()); + println!("{}", format!("That took {:?}", now.elapsed()).yellow()); + } Ok(()) }, Err(err) => { - println!("{}", "Failed!".red()); + if !json_ouput { + eprintln!("{}", "Failed!".red()); + } Err(err) }, } diff --git a/crates/testing-utils/Cargo.toml b/crates/testing-utils/Cargo.toml index 68b37361d..2aea25152 100644 --- a/crates/testing-utils/Cargo.toml +++ b/crates/testing-utils/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="entropy-testing-utils" description="Utilities for testing the Entropy Threshold Signature Server" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -9,26 +9,24 @@ repository ='https://github.com/entropyxyz/entropy-core' edition ='2021' [dependencies] -subxt="0.35.3" -sp-keyring="34.0.0" -project-root="0.2.2" -sp-core={ version="31.0.0", default-features=false } -parity-scale-codec="3.6.12" -lazy_static="1.5.0" -hex-literal="0.4.1" -tokio={ version="1.41", features=["macros", "fs", "rt-multi-thread", "io-util", "process"] } -axum={ version="0.7.7" } -entropy-shared={ version="0.3.0-rc.1", path="../shared" } -entropy-kvdb={ version="0.3.0-rc.1", path="../kvdb", default-features=false } -entropy-tss={ version="0.3.0-rc.1", path="../threshold-signature-server", features=[ - "test_helpers", -] } -entropy-protocol={ version="0.3.0-rc.1", path="../protocol" } -synedrion={ version="0.2.0-beta.0" } -hex="0.4.3" -rand_core="0.6.4" -rand="0.8.5" -tdx-quote={ version="0.0.1", features=["mock"] } +subxt ="0.35.3" +sp-keyring ="34.0.0" +project-root ="0.2.2" +sp-core ={ version="31.0.0", default-features=false } +parity-scale-codec="3.7.0" +lazy_static ="1.5.0" +hex-literal ="0.4.1" +tokio ={ version="1.41", features=["macros", "fs", "rt-multi-thread", "io-util", "process"] } +axum ={ version="0.7.9" } +entropy-shared ={ version="0.3.0", path="../shared" } +entropy-kvdb ={ version="0.3.0", path="../kvdb", default-features=false } +entropy-tss ={ version="0.3.0", path="../threshold-signature-server", features=["test_helpers"] } +entropy-protocol ={ version="0.3.0", path="../protocol" } +synedrion ={ version="0.2.0-beta.0" } +hex ="0.4.3" +rand_core ="0.6.4" +rand ="0.8.5" +tdx-quote ={ version="0.0.1", features=["mock"] } # Logging tracing ="0.1.37" diff --git a/crates/testing-utils/example_barebones_with_auxilary.wasm b/crates/testing-utils/example_barebones_with_auxilary.wasm index 8a5084582..3eaf5e2a6 100755 Binary files a/crates/testing-utils/example_barebones_with_auxilary.wasm and b/crates/testing-utils/example_barebones_with_auxilary.wasm differ diff --git a/crates/testing-utils/example_custom_hash.wasm b/crates/testing-utils/example_custom_hash.wasm index 9bc00fe38..4a47aad90 100755 Binary files a/crates/testing-utils/example_custom_hash.wasm and b/crates/testing-utils/example_custom_hash.wasm differ diff --git a/crates/testing-utils/faucet_program.wasm b/crates/testing-utils/faucet_program.wasm index cf1da0813..ec535d929 100755 Binary files a/crates/testing-utils/faucet_program.wasm and b/crates/testing-utils/faucet_program.wasm differ diff --git a/crates/testing-utils/infinite_loop.wasm b/crates/testing-utils/infinite_loop.wasm index a19e84182..c8bb9c5a4 100755 Binary files a/crates/testing-utils/infinite_loop.wasm and b/crates/testing-utils/infinite_loop.wasm differ diff --git a/crates/testing-utils/oracle_example.wasm b/crates/testing-utils/oracle_example.wasm new file mode 100755 index 000000000..9d85953c6 Binary files /dev/null and b/crates/testing-utils/oracle_example.wasm differ diff --git a/crates/testing-utils/src/constants.rs b/crates/testing-utils/src/constants.rs index ada142829..ab937e67a 100644 --- a/crates/testing-utils/src/constants.rs +++ b/crates/testing-utils/src/constants.rs @@ -83,6 +83,8 @@ pub const TEST_PROGRAM_WASM_BYTECODE: &[u8] = pub const FAUCET_PROGRAM: &[u8] = include_bytes!("../faucet_program.wasm"); /// `infinite_loop.wasm` from the `programs` repo. pub const TEST_INFINITE_LOOP_BYTECODE: &[u8] = include_bytes!("../infinite_loop.wasm"); +/// `oracle_example.wasm` from the `programs` repo. +pub const TEST_ORACLE_BYTECODE: &[u8] = include_bytes!("../oracle_example.wasm"); /// `template_basic_transaction.wasm` from the `programs` repo. pub const TEST_BASIC_TRANSACTION: &[u8] = include_bytes!("../template_basic_transaction.wasm"); /// `example_custom_hash.wasm` from the `programs` repo. diff --git a/crates/testing-utils/src/lib.rs b/crates/testing-utils/src/lib.rs index 812792b1e..8fea4daa3 100644 --- a/crates/testing-utils/src/lib.rs +++ b/crates/testing-utils/src/lib.rs @@ -25,3 +25,5 @@ pub mod substrate_context; pub use entropy_tss::helpers::tests::{spawn_testing_validators, ChainSpecType}; pub use node_proc::TestNodeProcess; pub use substrate_context::*; + +pub use entropy_tss::helpers::validator::get_signer_and_x25519_secret_from_mnemonic; diff --git a/crates/testing-utils/template_barebones.wasm b/crates/testing-utils/template_barebones.wasm index d54d0dcbc..81fa8ecdc 100755 Binary files a/crates/testing-utils/template_barebones.wasm and b/crates/testing-utils/template_barebones.wasm differ diff --git a/crates/testing-utils/template_basic_transaction.wasm b/crates/testing-utils/template_basic_transaction.wasm index 0c95c3303..1c22d3552 100755 Binary files a/crates/testing-utils/template_basic_transaction.wasm and b/crates/testing-utils/template_basic_transaction.wasm differ diff --git a/crates/threshold-signature-server/Cargo.toml b/crates/threshold-signature-server/Cargo.toml index ef2652f41..ac390f102 100644 --- a/crates/threshold-signature-server/Cargo.toml +++ b/crates/threshold-signature-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="entropy-tss" -version ="0.3.0-rc.1" +version ="0.3.0" authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' description='Entropy threshold signature scheme (TSS) server' @@ -12,8 +12,8 @@ edition ='2021' # Common serde ={ version="1.0", default-features=false, features=["derive"] } serde_json ="1.0" -anyhow ="1.0.92" -thiserror ="1.0.68" +thiserror ="2.0.3" +anyhow ="1.0.93" blake2 ="0.10.4" x25519-dalek ={ version="2.0.1", features=["static_secrets"] } rand_core ="0.6.4" @@ -32,29 +32,27 @@ tokio ={ version="1.41", features=["macros", "fs", "rt-multi-thread", "io-util" # HTTP reqwest={ version="0.12.9", features=["json", "stream"] } -axum ={ version="0.7.7", features=["ws"] } +axum ={ version="0.7.9", features=["ws"] } # Substrate subxt ="0.35.3" -parity-scale-codec="3.6.12" +parity-scale-codec="3.7.0" sp-core ={ version="31.0.0", default-features=false } # Entropy -entropy-shared={ version="0.3.0-rc.1", path="../shared" } -entropy-kvdb={ version="0.3.0-rc.1", path="../kvdb", default-features=false } -entropy-protocol={ version="0.3.0-rc.1", path="../protocol", features=["server"] } -entropy-client={ version="0.3.0-rc.1", path="../client", default-features=false, features=[ - "native", -] } +entropy-shared ={ version="0.3.0", path="../shared" } +entropy-kvdb ={ version="0.3.0", path="../kvdb", default-features=false } +entropy-protocol={ version="0.3.0", path="../protocol", features=["server"] } +entropy-client ={ version="0.3.0", path="../client", default-features=false, features=["native"] } # Programs -entropy-programs-runtime="0.10.0" +entropy-programs-runtime={ git="https://github.com/entropyxyz/programs.git", branch="master" } # Logging tracing ="0.1.37" tracing-subscriber ={ version="0.3.18", features=["env-filter", "json"] } tracing-loki ="0.2" -tower-http ={ version="0.6.1", features=["trace", "cors"] } +tower-http ={ version="0.6.2", features=["trace", "cors"] } tracing-bunyan-formatter="0.3.9" uuid ={ version="1.11.0", features=["v4"] } @@ -65,7 +63,7 @@ bip32 ={ version="0.5.2" } bip39 ={ version="2.1.0", features=["zeroize"] } bytes ={ version="1.8", default-features=false, features=["serde"] } base64 ="0.22.1" -clap ={ version="4.5.20", features=["derive"] } +clap ={ version="4.5.21", features=["derive"] } num ="0.4.3" snow ="0.9.6" sha3 ="0.10.8" @@ -78,7 +76,7 @@ tdx-quote ={ version="0.0.1", optional=true, features=["mock"] } configfs-tsm ={ version="0.0.1", optional=true } [dev-dependencies] -serial_test ="3.1.1" +serial_test ="3.2.0" hex-literal ="0.4.1" project-root="0.2.2" sp-keyring ="34.0.0" diff --git a/crates/threshold-signature-server/src/attestation/api.rs b/crates/threshold-signature-server/src/attestation/api.rs index fe984108d..8ab443ab5 100644 --- a/crates/threshold-signature-server/src/attestation/api.rs +++ b/crates/threshold-signature-server/src/attestation/api.rs @@ -23,10 +23,16 @@ use crate::{ }, AppState, }; -use axum::{body::Bytes, extract::State, http::StatusCode}; +use axum::{ + body::Bytes, + extract::{Query, State}, + http::StatusCode, +}; +use entropy_client::user::request_attestation; use entropy_kvdb::kv_manager::KvManager; -use entropy_shared::OcwMessageAttestationRequest; +use entropy_shared::{OcwMessageAttestationRequest, QuoteContext}; use parity_scale_codec::Decode; +use serde::Deserialize; use sp_core::Pair; use subxt::tx::PairSigner; use x25519_dalek::StaticSecret; @@ -67,8 +73,10 @@ pub async fn attest( .ok_or_else(|| AttestationErr::Unexpected)? }; - // We add 1 to the block number as this will be processed in the next block - let quote = create_quote(block_number + 1, nonce, &signer, &x25519_secret).await?; + // TODO (#1181): since this endpoint is currently only used in tests we don't know what the context should be + let context = QuoteContext::Validate; + + let quote = create_quote(nonce, &signer, &x25519_secret, context).await?; // Submit the quote let attest_tx = entropy::tx().attestation().attest(quote.clone()); @@ -77,13 +85,36 @@ pub async fn attest( Ok(StatusCode::OK) } +/// Retrieve a quote by requesting a nonce from the chain and return the quote in the HTTP response +/// body. +/// +/// This is used by node operators to get a quote for use in the `validate`, `change_endpoint` +/// and `change_tss_accounts` extrinsics. +pub async fn get_attest( + State(app_state): State, + Query(context_querystring): Query, +) -> Result<(StatusCode, Vec), AttestationErr> { + let (signer, x25519_secret) = get_signer_and_x25519_secret(&app_state.kv_store).await?; + let api = get_api(&app_state.configuration.endpoint).await?; + let rpc = get_rpc(&app_state.configuration.endpoint).await?; + + // Request attestation to get nonce + let nonce = request_attestation(&api, &rpc, signer.signer()).await?; + + let context = context_querystring.as_quote_context()?; + + let quote = create_quote(nonce, &signer, &x25519_secret, context).await?; + + Ok((StatusCode::OK, quote)) +} + /// Create a mock quote for testing on non-TDX hardware #[cfg(not(feature = "production"))] pub async fn create_quote( - block_number: u32, nonce: [u8; 32], signer: &PairSigner, x25519_secret: &StaticSecret, + context: QuoteContext, ) -> Result, AttestationErr> { use rand::{rngs::StdRng, SeedableRng}; use rand_core::OsRng; @@ -98,7 +129,7 @@ pub async fn create_quote( signer.signer().public(), *public_key.as_bytes(), nonce, - block_number, + context, ); // This is generated deterministically from TSS account id @@ -141,10 +172,10 @@ pub async fn validate_new_attestation( /// Create a TDX quote in production #[cfg(feature = "production")] pub async fn create_quote( - block_number: u32, nonce: [u8; 32], signer: &PairSigner, x25519_secret: &StaticSecret, + context: QuoteContext, ) -> Result, AttestationErr> { let public_key = x25519_dalek::PublicKey::from(x25519_secret); @@ -152,8 +183,29 @@ pub async fn create_quote( signer.signer().public(), *public_key.as_bytes(), nonce, - block_number, + context, ); Ok(configfs_tsm::create_quote(input_data.0)?) } + +/// Querystring for the GET `/attest` endpoint +#[derive(Deserialize)] +pub struct QuoteContextQuery { + /// The context in which the requested quote will be used. + /// + /// Must be one of `validate`, `change_endpoint`, `change_threshold_accounts`. + /// Eg: `http://127.0.0.1:3001/attest?context=validate` + context: String, +} + +impl QuoteContextQuery { + fn as_quote_context(&self) -> Result { + match self.context.as_str() { + "validate" => Ok(QuoteContext::Validate), + "change_endpoint" => Ok(QuoteContext::ChangeEndpoint), + "change_threshold_accounts" => Ok(QuoteContext::ChangeThresholdAccounts), + _ => Err(AttestationErr::UnknownContext), + } + } +} diff --git a/crates/threshold-signature-server/src/attestation/errors.rs b/crates/threshold-signature-server/src/attestation/errors.rs index 7fc2ccd00..14ace080b 100644 --- a/crates/threshold-signature-server/src/attestation/errors.rs +++ b/crates/threshold-signature-server/src/attestation/errors.rs @@ -48,6 +48,10 @@ pub enum AttestationErr { Kv(#[from] entropy_kvdb::kv_manager::error::KvError), #[error("Data is stale")] StaleData, + #[error("Attestation request: {0}")] + AttestationRequest(#[from] entropy_client::errors::AttestationRequestError), + #[error("Invalid or unknown context value given in query string")] + UnknownContext, } impl IntoResponse for AttestationErr { diff --git a/crates/threshold-signature-server/src/attestation/tests.rs b/crates/threshold-signature-server/src/attestation/tests.rs index 16e49821d..8ba451305 100644 --- a/crates/threshold-signature-server/src/attestation/tests.rs +++ b/crates/threshold-signature-server/src/attestation/tests.rs @@ -27,10 +27,44 @@ use crate::{ use entropy_kvdb::clean_tests; use entropy_shared::OcwMessageAttestationRequest; use entropy_testing_utils::{ - constants::TSS_ACCOUNTS, + constants::{BOB_STASH_ADDRESS, TSS_ACCOUNTS}, substrate_context::{test_context_stationary, test_node_process_stationary}, }; use serial_test::serial; +use subxt::utils::AccountId32; +use tdx_quote::{decode_verifying_key, Quote}; + +#[tokio::test] +#[serial] +async fn test_get_attest() { + initialize_test_logger().await; + clean_tests(); + + let cxt = test_node_process_stationary().await; + let (_validator_ips, _validator_ids) = + spawn_testing_validators(ChainSpecType::Integration).await; + + let api = get_api(&cxt.ws_url).await.unwrap(); + let rpc = get_rpc(&cxt.ws_url).await.unwrap(); + + let quote_bytes = reqwest::get("http://127.0.0.1:3002/attest?context=validate") + .await + .unwrap() + .bytes() + .await + .unwrap(); + let quote = Quote::from_bytes("e_bytes).unwrap(); + + let query = + entropy::storage().staking_extension().threshold_servers(&AccountId32(BOB_STASH_ADDRESS.0)); + let server_info = query_chain(&api, &rpc, query, None).await.unwrap().unwrap(); + + let provisioning_certification_key = + decode_verifying_key(&server_info.provisioning_certification_key.0.try_into().unwrap()) + .unwrap(); + + assert!(quote.verify_with_pck(provisioning_certification_key).is_ok()) +} #[ignore] #[tokio::test] diff --git a/crates/threshold-signature-server/src/helpers/substrate.rs b/crates/threshold-signature-server/src/helpers/substrate.rs index a23da6503..ee8a27df5 100644 --- a/crates/threshold-signature-server/src/helpers/substrate.rs +++ b/crates/threshold-signature-server/src/helpers/substrate.rs @@ -52,7 +52,7 @@ pub async fn get_program( api: &OnlineClient, rpc: &LegacyRpcMethods, program_pointer: &::Hash, -) -> Result, UserErr> { +) -> Result { let bytecode_address = entropy::storage().programs().programs(program_pointer); let program_info = query_chain(api, rpc, bytecode_address, None) .await? @@ -64,12 +64,17 @@ pub async fn get_program( pub async fn get_oracle_data( api: &OnlineClient, rpc: &LegacyRpcMethods, - program_oracle_data: Vec, -) -> Result, UserErr> { - let oracle_data_call = entropy::storage().oracle().oracle_data(BoundedVec(program_oracle_data)); - let oracle_info = - query_chain(api, rpc, oracle_data_call, None).await?.unwrap_or(BoundedVec(vec![])); - Ok(oracle_info.0) + program_oracle_datas: Vec>, +) -> Result>, UserErr> { + let mut oracle_infos = vec![]; + for program_oracle_data in program_oracle_datas { + let oracle_data_call = + entropy::storage().oracle().oracle_data(BoundedVec(program_oracle_data)); + let oracle_info = + query_chain(api, rpc, oracle_data_call, None).await?.unwrap_or(BoundedVec(vec![])); + oracle_infos.push(oracle_info.0); + } + Ok(oracle_infos) } /// Takes Stash keys and returns validator info from chain diff --git a/crates/threshold-signature-server/src/helpers/validator.rs b/crates/threshold-signature-server/src/helpers/validator.rs index b571e0181..3811b0414 100644 --- a/crates/threshold-signature-server/src/helpers/validator.rs +++ b/crates/threshold-signature-server/src/helpers/validator.rs @@ -88,7 +88,7 @@ fn get_x25519_secret_from_hkdf(hkdf: &Hkdf) -> Result Router { .route("/validator/reshare", post(new_reshare)) .route("/rotate_network_key", post(rotate_network_key)) .route("/attest", post(attest)) + .route("/attest", get(get_attest)) .route("/healthz", get(healthz)) .route("/version", get(get_version)) .route("/hashes", get(hashes)) diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 7f10931d6..c9397de91 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -689,7 +689,7 @@ pub async fn pre_sign_checks( for (i, program_data) in user_details.programs_data.0.iter().enumerate() { let program_info = get_program(api, rpc, &program_data.program_pointer).await?; - let oracle_data = get_oracle_data(api, rpc, program_info.oracle_data_pointer).await?; + let oracle_data = get_oracle_data(api, rpc, program_info.oracle_data_pointers.0).await?; let auxilary_data = auxilary_data_vec[i].as_ref().map(hex::decode).transpose()?; let signature_request = SignatureRequest { message: message.clone(), auxilary_data }; runtime.evaluate( diff --git a/crates/threshold-signature-server/src/user/tests.rs b/crates/threshold-signature-server/src/user/tests.rs index 2f740428b..9d3d724fb 100644 --- a/crates/threshold-signature-server/src/user/tests.rs +++ b/crates/threshold-signature-server/src/user/tests.rs @@ -39,7 +39,8 @@ use entropy_testing_utils::{ constants::{ AUXILARY_DATA_SHOULD_SUCCEED, FAUCET_PROGRAM, FERDIE_X25519_SECRET_KEY, PREIMAGE_SHOULD_SUCCEED, TEST_BASIC_TRANSACTION, TEST_INFINITE_LOOP_BYTECODE, - TEST_PROGRAM_CUSTOM_HASH, TEST_PROGRAM_WASM_BYTECODE, X25519_PUBLIC_KEYS, + TEST_ORACLE_BYTECODE, TEST_PROGRAM_CUSTOM_HASH, TEST_PROGRAM_WASM_BYTECODE, + X25519_PUBLIC_KEYS, }, helpers::spawn_tss_nodes_and_start_chain, substrate_context::{test_context_stationary, testing_context}, @@ -1075,6 +1076,69 @@ async fn test_fail_infinite_program() { ); } +#[tokio::test] +#[serial] +async fn test_oracle_program() { + initialize_test_logger().await; + clean_tests(); + + let one = AccountKeyring::One; + let two = AccountKeyring::Two; + + let (_validator_ips, _validator_ids) = + spawn_testing_validators(ChainSpecType::Integration).await; + + let mnemonic = development_mnemonic(&Some(ValidatorName::Alice)); + let (_tss_signer, _static_secret) = + get_signer_and_x25519_secret_from_mnemonic(&mnemonic.to_string()).unwrap(); + + let force_authoring = true; + let substrate_context = &test_node_process_testing_state(force_authoring).await[0]; + + let api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + let non_signer = jump_start_network(&api, &rpc).await.unwrap(); + let (relayer_ip_and_key, _) = validator_name_to_relayer_info(non_signer, &api, &rpc).await; + + let program_hash = test_client::store_program( + &api, + &rpc, + &two.pair(), + TEST_ORACLE_BYTECODE.to_owned(), + vec![], + vec![], + vec!["block_number_entropy".encode()], + 0u8, + ) + .await + .unwrap(); + + let (verifying_key, _registered_info) = test_client::register( + &api, + &rpc, + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), + ) + .await + .unwrap(); + + // Now we'll send off a signature request using the new program + let (_validators_info, signature_request, _validator_ips_and_keys) = + get_sign_tx_data(&api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED), verifying_key).await; + + let test_user_res = + submit_transaction_request(relayer_ip_and_key.clone(), signature_request.clone(), one) + .await; + + let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); + let decoded_verifying_key = + decode_verifying_key(verifying_key.as_slice().try_into().unwrap()).unwrap(); + let all_signers_info = get_all_signers_from_chain(&api, &rpc).await.unwrap(); + verify_signature(test_user_res, message_hash, &decoded_verifying_key, &all_signers_info).await; +} + #[tokio::test] #[serial] async fn test_device_key_proxy() { @@ -1536,13 +1600,17 @@ async fn test_get_oracle_data() { let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap(); run_to_block(&rpc, 1).await; - let oracle_data = get_oracle_data(&api, &rpc, "block_number_entropy".encode()).await.unwrap(); + let oracle_data = + get_oracle_data(&api, &rpc, vec!["block_number_entropy".encode()]).await.unwrap(); let current_block = rpc.chain_get_header(None).await.unwrap().unwrap().number; - assert_eq!(current_block.encode(), oracle_data); + assert_eq!(oracle_data.len(), 1); + assert_eq!(current_block.encode(), oracle_data[0]); // fails gracefully - let oracle_data_fail = get_oracle_data(&api, &rpc, "random_heading".encode()).await.unwrap(); - assert_eq!(oracle_data_fail.len(), 0); + let oracle_data_fail = + get_oracle_data(&api, &rpc, vec!["random_heading".encode()]).await.unwrap(); + assert_eq!(oracle_data_fail.len(), 1); + assert_eq!(oracle_data_fail[0].len(), 0); } pub async fn submit_transaction_request( diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 885e2629d..5a1cd29fc 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='entropy' -version ='0.3.0-rc.1' +version ='0.3.0' description="Entropy substrate node" authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' @@ -19,7 +19,7 @@ name='entropy' [dependencies] # Third-party dependencies -clap ={ version="4.5.20", features=["derive"], optional=true } +clap ={ version="4.5.21", features=["derive"], optional=true } codec ={ package="parity-scale-codec", version="3.0.0" } futures ="0.3.31" hex-literal ="0.4.1" @@ -29,8 +29,8 @@ lazy_static ={ version="1.5.0", features=["spin_no_std"] } log ="0.4.22" pallet-im-online={ version="28.0.0" } rand ="0.8.5" -serde ={ version="1.0.214", features=["derive"] } -serde_json ='1.0.132' +serde ={ version="1.0.215", features=["derive"] } +serde_json ='1.0.133' # Substrate Client @@ -90,23 +90,23 @@ pallet-transaction-payment ={ version="29.0.0" } pallet-transaction-payment-rpc={ version="31.0.0" } # Entropy Dependencies -entropy-runtime={ version="0.3.0-rc.1", path="../../runtime" } -entropy-shared={ version="0.3.0-rc.1", path="../../crates/shared", default-features=false, features=[ +entropy-runtime={ version="0.3.0", path="../../runtime" } +entropy-shared={ version="0.3.0", path="../../crates/shared", default-features=false, features=[ "wasm-no-std", ] } -pallet-registry={ version="0.3.0-rc.1", path="../../pallets/registry" } -pallet-staking-extension={ version="0.3.0-rc.1", path="../../pallets/staking" } +pallet-registry={ version="0.3.0", path="../../pallets/registry" } +pallet-staking-extension={ version="0.3.0", path="../../pallets/staking" } project-root="0.2.2" [build-dependencies] -clap={ version="4.5.20", optional=true } +clap={ version="4.5.21", optional=true } pallet-balances ={ version="29.0.0" } substrate-build-script-utils={ version="11.0.0" } try-runtime-cli ={ version="0.42.0" } [dev-dependencies] -tempfile ="3.13.0" +tempfile ="3.14.0" sp-tracing={ version="16.0.0" } [features] diff --git a/pallets/attestation/Cargo.toml b/pallets/attestation/Cargo.toml index a5e282d9d..e9b7356bd 100644 --- a/pallets/attestation/Cargo.toml +++ b/pallets/attestation/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="pallet-attestation" -version ="0.3.0-rc.1" +version ="0.3.0" authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -23,11 +23,11 @@ sp-std ={ version="14.0.0", default-features=false } pallet-session ={ version="29.0.0", default-features=false, optional=true } rand_chacha ={ version="0.3", default-features=false } -pallet-parameters={ version="0.3.0-rc.1", path="../parameters", default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../../crates/shared", features=[ +pallet-parameters={ version="0.3.0", path="../parameters", default-features=false } +entropy-shared={ version="0.3.0", path="../../crates/shared", features=[ "wasm-no-std", ], default-features=false } -pallet-staking-extension={ version="0.3.0-rc.1", path="../staking", default-features=false } +pallet-staking-extension={ version="0.3.0", path="../staking", default-features=false } tdx-quote="0.0.1" [dev-dependencies] diff --git a/pallets/attestation/src/lib.rs b/pallets/attestation/src/lib.rs index d51887fd2..ec046b851 100644 --- a/pallets/attestation/src/lib.rs +++ b/pallets/attestation/src/lib.rs @@ -47,7 +47,7 @@ mod tests; #[frame_support::pallet] pub mod pallet { - use entropy_shared::{AttestationHandler, QuoteInputData}; + use entropy_shared::{AttestationHandler, QuoteContext, QuoteInputData}; use frame_support::pallet_prelude::*; use frame_support::traits::Randomness; use frame_system::pallet_prelude::*; @@ -205,6 +205,7 @@ pub mod pallet { x25519_public_key: entropy_shared::X25519PublicKey, provisioning_certification_key: entropy_shared::BoundedVecEncodedVerifyingKey, quote: Vec, + context: QuoteContext, ) -> Result<(), DispatchError> { // Check that we were expecting a quote from this validator by getting the associated // nonce from PendingAttestations. @@ -214,15 +215,9 @@ pub mod pallet { // Parse the quote (which internally verifies the attestation key signature) let quote = Quote::from_bytes("e).map_err(|_| Error::::BadQuote)?; - // Get current block number - let block_number: u32 = { - let block_number = >::block_number(); - BlockNumberFor::::try_into(block_number).unwrap_or_default() - }; - // Check report input data matches the nonce, TSS details and block number let expected_input_data = - QuoteInputData::new(attestee, x25519_public_key, nonce, block_number); + QuoteInputData::new(attestee, x25519_public_key, nonce, context); ensure!( quote.report_input_data() == expected_input_data.0, Error::::IncorrectInputData diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 324c210cf..113d5cd15 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -14,7 +14,7 @@ // along with this program. If not, see . use crate::mock::*; -use entropy_shared::{AttestationHandler, QuoteInputData}; +use entropy_shared::{AttestationHandler, QuoteContext, QuoteInputData}; use frame_support::{assert_noop, assert_ok}; use rand_core::OsRng; @@ -32,13 +32,12 @@ fn verify_quote_works() { let pck_encoded = tdx_quote::encode_verifying_key(pck.verifying_key()).unwrap(); let x25519_public_key = [0; 32]; - let block_number = 0; let input_data = QuoteInputData::new( ATTESTEE, // TSS Account ID x25519_public_key, nonce, - block_number, + QuoteContext::Validate, ); let quote = tdx_quote::Quote::mock(attestation_key.clone(), pck, input_data.0); @@ -47,6 +46,7 @@ fn verify_quote_works() { x25519_public_key, sp_runtime::BoundedVec::try_from(pck_encoded.to_vec()).unwrap(), quote.as_bytes().to_vec(), + QuoteContext::Validate, )); }) } @@ -63,13 +63,12 @@ fn verify_quote_fails_with_mismatched_input_data() { let pck_encoded = tdx_quote::encode_verifying_key(pck.verifying_key()).unwrap(); let x25519_public_key = [0; 32]; - let block_number = 0; let input_data = QuoteInputData::new( ATTESTEE, // TSS Account ID x25519_public_key, nonce, - block_number, + QuoteContext::Validate, ); let quote = tdx_quote::Quote::mock(attestation_key.clone(), pck, input_data.0); @@ -83,6 +82,7 @@ fn verify_quote_fails_with_mismatched_input_data() { x25519_public_key, sp_runtime::BoundedVec::try_from(pck_encoded.to_vec()).unwrap(), quote.as_bytes().to_vec(), + QuoteContext::Validate, ), crate::Error::::UnexpectedAttestation, ); @@ -96,6 +96,7 @@ fn verify_quote_fails_with_mismatched_input_data() { mismatched_x25519_public_key, sp_runtime::BoundedVec::try_from(pck_encoded.to_vec()).unwrap(), quote.as_bytes().to_vec(), + QuoteContext::Validate, ), crate::Error::::IncorrectInputData, ); @@ -116,6 +117,7 @@ fn verify_quote_fails_with_mismatched_input_data() { x25519_public_key, sp_runtime::BoundedVec::try_from(mismatched_pck_encoded.to_vec()).unwrap(), quote.as_bytes().to_vec(), + QuoteContext::Validate, ), crate::Error::::PckVerification ); diff --git a/pallets/oracle/Cargo.toml b/pallets/oracle/Cargo.toml index 81f3612dd..0c3e43c2a 100644 --- a/pallets/oracle/Cargo.toml +++ b/pallets/oracle/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="pallet-oracle" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' diff --git a/pallets/parameters/Cargo.toml b/pallets/parameters/Cargo.toml index ad3932b32..cb20c9ff2 100644 --- a/pallets/parameters/Cargo.toml +++ b/pallets/parameters/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="pallet-parameters" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -19,7 +19,7 @@ sp-runtime ={ version="32.0.0", default-features=false } sp-std ={ version="14.0.0", default-features=false } pallet-session ={ version="29.0.0", default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../../crates/shared", features=[ +entropy-shared={ version="0.3.0", path="../../crates/shared", features=[ "wasm-no-std", ], default-features=false } diff --git a/pallets/programs/Cargo.toml b/pallets/programs/Cargo.toml index d4d3c3002..0091d4aee 100644 --- a/pallets/programs/Cargo.toml +++ b/pallets/programs/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='pallet-programs' -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' diff --git a/pallets/programs/src/benchmarking.rs b/pallets/programs/src/benchmarking.rs index 81e0cb145..43b726dd8 100644 --- a/pallets/programs/src/benchmarking.rs +++ b/pallets/programs/src/benchmarking.rs @@ -41,19 +41,21 @@ fn assert_last_event(generic_event: ::RuntimeEvent) { benchmarks! { set_program { + let o in 0 .. T::MaxOracleLookups::get(); let program = vec![10]; let configuration_schema = vec![11]; let auxiliary_data_schema = vec![12]; - let oracle_data_pointer = vec![13]; + let oracle_data_pointers = BoundedVec::try_from([vec![13u8; o as usize]].to_vec()).unwrap(); let version_number = 0u8; let mut hash_input: Vec = vec![]; hash_input.extend(&program); hash_input.extend(&configuration_schema); hash_input.extend(&auxiliary_data_schema); - hash_input.extend(&oracle_data_pointer); hash_input.extend(&vec![version_number]); + let (_oracle_length, hash_input_with_oracle) = + ProgramsPallet::::get_length_and_hash_of_oracle(&oracle_data_pointers, hash_input).unwrap(); - let program_hash = T::Hashing::hash(&hash_input); + let program_hash = T::Hashing::hash(&hash_input_with_oracle); let deployer: T::AccountId = whitelisted_caller(); let sig_req_account: T::AccountId = whitelisted_caller(); @@ -65,7 +67,7 @@ benchmarks! { program.clone(), configuration_schema.clone(), auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number ) verify { @@ -75,7 +77,7 @@ benchmarks! { program_hash, configuration_schema, auxiliary_data_schema, - oracle_data_pointer, + oracle_data_pointers, version_number }.into() ); @@ -83,26 +85,29 @@ benchmarks! { remove_program { let p in 0..T::MaxOwnedPrograms::get(); + let o in 0 .. T::MaxOracleLookups::get(); + let program = vec![10]; let configuration_schema = vec![11]; let auxiliary_data_schema = vec![12]; - let oracle_data_pointer = vec![13]; + let oracle_data_pointers = BoundedVec::try_from([vec![13u8; o as usize]].to_vec()).unwrap(); let version_number = 0u8; let mut hash_input: Vec = vec![]; hash_input.extend(&program); hash_input.extend(&configuration_schema); hash_input.extend(&auxiliary_data_schema); - hash_input.extend(&oracle_data_pointer); hash_input.extend(&vec![version_number]); + let (_oracle_length, hash_input_with_oracle) = + ProgramsPallet::::get_length_and_hash_of_oracle(&oracle_data_pointers, hash_input).unwrap(); - let program_hash = T::Hashing::hash(&hash_input); + let program_hash = T::Hashing::hash(&hash_input_with_oracle); let random_program = vec![11]; let random_hash = T::Hashing::hash(&random_program); let deployer: T::AccountId = whitelisted_caller(); let value = CurrencyOf::::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = CurrencyOf::::make_free_balance_be(&deployer, value); - >::insert(program_hash.clone(), ProgramInfo {bytecode: program, configuration_schema, auxiliary_data_schema, oracle_data_pointer, deployer: deployer.clone(), ref_counter: 0u128, version_number}); + >::insert(program_hash.clone(), ProgramInfo {bytecode: program, configuration_schema, auxiliary_data_schema, oracle_data_pointers, deployer: deployer.clone(), ref_counter: 0u128, version_number}); let mut program_hashes = vec![random_hash.clone(); p as usize]; // remove one to make room for the targetted removal program hash program_hashes.pop(); diff --git a/pallets/programs/src/lib.rs b/pallets/programs/src/lib.rs index 5e061278d..bdf61e4c5 100644 --- a/pallets/programs/src/lib.rs +++ b/pallets/programs/src/lib.rs @@ -75,6 +75,9 @@ pub mod pallet { /// The maximum amount of owned programs. type MaxOwnedPrograms: Get; + /// The maximum amount of oracle lookups allowed. + type MaxOracleLookups: Get; + /// The amount to charge, per byte, for storing a program on-chain. type ProgramDepositPerByte: Get>; @@ -85,6 +88,8 @@ pub mod pallet { type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + pub type OraclePointers = BoundedVec, ::MaxOracleLookups>; + #[pallet::genesis_config] #[derive(frame_support::DefaultNoBound)] pub struct GenesisConfig { @@ -108,7 +113,7 @@ pub mod pallet { configuration_schema: program_info.2.clone(), auxiliary_data_schema: program_info.3.clone(), deployer: program_info.4.clone(), - oracle_data_pointer: vec![], + oracle_data_pointers: BoundedVec::try_from([].to_vec()).unwrap(), ref_counter: program_info.5, version_number: 0, }, @@ -123,7 +128,8 @@ pub mod pallet { /// Information on the program #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] - pub struct ProgramInfo { + #[scale_info(skip_type_params(T))] + pub struct ProgramInfo { /// The bytecode of the program. pub bytecode: Vec, /// The schema for the Program's configuration parameters. @@ -138,10 +144,10 @@ pub mod pallet { /// [JSON Schema](https://json-schema.org/) in order to simplify the life of off-chain /// actors. pub auxiliary_data_schema: Vec, - /// The location of the oracle data needed for this program - pub oracle_data_pointer: Vec, + /// The locations of the oracle data needed for this program + pub oracle_data_pointers: OraclePointers, /// Deployer of the program - pub deployer: AccountId, + pub deployer: T::AccountId, /// Accounts that use this program pub ref_counter: u128, /// The user submitted version number of the program's runtime @@ -154,7 +160,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn programs)] pub type Programs = - StorageMap<_, Blake2_128Concat, T::Hash, ProgramInfo, OptionQuery>; + StorageMap<_, Blake2_128Concat, T::Hash, ProgramInfo, OptionQuery>; /// Maps an account to all the programs it owns #[pallet::storage] @@ -184,8 +190,8 @@ pub mod pallet { /// The new program auxiliary data schema. auxiliary_data_schema: Vec, - /// The oracle data location needed for the program - oracle_data_pointer: Vec, + /// The oracle data locations needed for the program + oracle_data_pointers: OraclePointers, /// The version number of runtime for which the program was written version_number: u8, @@ -224,30 +230,33 @@ pub mod pallet { /// /// Note that the caller becomes the deployer account. #[pallet::call_index(0)] - #[pallet::weight({::WeightInfo::set_program()})] + #[pallet::weight({::WeightInfo::set_program(::MaxOracleLookups::get())})] pub fn set_program( origin: OriginFor, new_program: Vec, configuration_schema: Vec, auxiliary_data_schema: Vec, - oracle_data_pointer: Vec, + oracle_data_pointers: OraclePointers, version_number: u8, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let deployer = ensure_signed(origin)?; let mut hash_input = vec![]; hash_input.extend(&new_program); hash_input.extend(&configuration_schema); hash_input.extend(&auxiliary_data_schema); - hash_input.extend(&oracle_data_pointer); + hash_input.extend(&vec![version_number]); - let program_hash = T::Hashing::hash(&hash_input); + let (oracle_length, hash_input_with_oracle) = + Self::get_length_and_hash_of_oracle(&oracle_data_pointers, hash_input)?; + let program_hash = T::Hashing::hash(&hash_input_with_oracle); + let new_program_length = new_program .len() .checked_add(configuration_schema.len()) .ok_or(Error::::ArithmeticError)? .checked_add(auxiliary_data_schema.len()) .ok_or(Error::::ArithmeticError)? - .checked_add(oracle_data_pointer.len()) + .checked_add(oracle_length) .ok_or(Error::::ArithmeticError)?; ensure!( new_program_length as u32 <= T::MaxBytecodeLength::get(), @@ -263,7 +272,7 @@ pub mod pallet { bytecode: new_program.clone(), configuration_schema: configuration_schema.clone(), auxiliary_data_schema: auxiliary_data_schema.clone(), - oracle_data_pointer: oracle_data_pointer.clone(), + oracle_data_pointers: oracle_data_pointers.clone(), deployer: deployer.clone(), ref_counter: 0u128, version_number, @@ -283,17 +292,18 @@ pub mod pallet { program_hash, configuration_schema, auxiliary_data_schema, - oracle_data_pointer, + oracle_data_pointers: oracle_data_pointers.clone(), version_number, }); - Ok(()) + Ok(Some(::WeightInfo::set_program(oracle_data_pointers.len() as u32)) + .into()) } /// Removes a program at a specific hash /// /// Caller must be the deployer account for said program. #[pallet::call_index(1)] - #[pallet::weight({::WeightInfo::remove_program( ::MaxOwnedPrograms::get())})] + #[pallet::weight({::WeightInfo::remove_program( ::MaxOracleLookups::get(), ::MaxOwnedPrograms::get())})] pub fn remove_program( origin: OriginFor, program_hash: T::Hash, @@ -303,12 +313,18 @@ pub mod pallet { Self::programs(program_hash).ok_or(Error::::NoProgramDefined)?; ensure!(old_program_info.deployer == deployer, Error::::NotAuthorized); ensure!(old_program_info.ref_counter == 0, Error::::ProgramInUse); + + let mut oracle_length: usize = 0; + for oracle_data_pointer in &old_program_info.oracle_data_pointers { + oracle_length += oracle_data_pointer.len(); + } + Self::unreserve_program_deposit( &old_program_info.deployer, old_program_info.bytecode.len() + old_program_info.configuration_schema.len() + old_program_info.auxiliary_data_schema.len() - + old_program_info.oracle_data_pointer.len(), + + oracle_length, ); let mut owned_programs_length = 0; OwnedPrograms::::try_mutate( @@ -325,7 +341,11 @@ pub mod pallet { )?; Programs::::remove(program_hash); Self::deposit_event(Event::ProgramRemoved { deployer, old_program_hash: program_hash }); - Ok(Some(::WeightInfo::remove_program(owned_programs_length as u32)).into()) + Ok(Some(::WeightInfo::remove_program( + old_program_info.oracle_data_pointers.len() as u32, + owned_programs_length as u32, + )) + .into()) } } @@ -372,5 +392,19 @@ pub mod pallet { Ok(()) } + + /// Gets hash input and length of each oracle data pointer + pub fn get_length_and_hash_of_oracle( + oracle_datas: &OraclePointers, + mut hash_input: Vec, + ) -> Result<(usize, Vec), Error> { + let mut length: usize = 0; + for oracle_data in oracle_datas { + hash_input.extend(oracle_data); + length = + length.checked_add(oracle_data.len()).ok_or(Error::::ArithmeticError)?; + } + Ok((length, hash_input)) + } } } diff --git a/pallets/programs/src/mock.rs b/pallets/programs/src/mock.rs index 8d4891333..20ece9a7b 100644 --- a/pallets/programs/src/mock.rs +++ b/pallets/programs/src/mock.rs @@ -71,6 +71,7 @@ parameter_types! { pub const MaxBytecodeLength: u32 = 5; pub const ProgramDepositPerByte: u32 = 5; pub const MaxOwnedPrograms: u32 = 1; + pub const MaxOracleLookups: u32 = 2; } parameter_types! { @@ -99,6 +100,7 @@ impl pallet_programs::Config for Test { type MaxBytecodeLength = MaxBytecodeLength; type ProgramDepositPerByte = ProgramDepositPerByte; type MaxOwnedPrograms = MaxOwnedPrograms; + type MaxOracleLookups = MaxOracleLookups; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } diff --git a/pallets/programs/src/tests.rs b/pallets/programs/src/tests.rs index d930b7acd..365e12025 100644 --- a/pallets/programs/src/tests.rs +++ b/pallets/programs/src/tests.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use frame_support::{assert_noop, assert_ok, traits::Currency}; +use frame_support::{assert_noop, assert_ok, traits::Currency, BoundedVec}; use pallet_balances::Error as BalancesError; use sp_runtime::traits::Hash; @@ -29,17 +29,19 @@ fn set_program() { let program_2 = vec![12u8, 13u8]; let configuration_schema = vec![14u8]; let auxiliary_data_schema = vec![15u8]; - let oracle_data_pointer = vec![16u8]; + let oracle_data_pointers = BoundedVec::try_from([vec![16u8]].to_vec()).unwrap(); let version_number = 0u8; let too_long = vec![1u8, 2u8, 3u8, 4u8, 5u8]; let mut hash_input: Vec = vec![]; hash_input.extend(&program); hash_input.extend(&configuration_schema); hash_input.extend(&auxiliary_data_schema); - hash_input.extend(&oracle_data_pointer); hash_input.extend(&vec![version_number]); + let (_oracle_length, hash_input_with_oracle) = + ProgramsPallet::get_length_and_hash_of_oracle(&oracle_data_pointers, hash_input) + .unwrap(); - let program_hash = ::Hashing::hash(&hash_input); + let program_hash = ::Hashing::hash(&hash_input_with_oracle); // can't pay deposit assert_noop!( ProgramsPallet::set_program( @@ -47,7 +49,7 @@ fn set_program() { program.clone(), configuration_schema.clone(), auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number ), BalancesError::::InsufficientBalance @@ -60,14 +62,14 @@ fn set_program() { program.clone(), configuration_schema.clone(), auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number )); let program_result = ProgramInfo { bytecode: program.clone(), configuration_schema: configuration_schema.clone(), auxiliary_data_schema: auxiliary_data_schema.clone(), - oracle_data_pointer: oracle_data_pointer.clone(), + oracle_data_pointers: oracle_data_pointers.clone(), deployer: PROGRAM_MODIFICATION_ACCOUNT, ref_counter: 0u128, version_number, @@ -92,7 +94,7 @@ fn set_program() { program.clone(), configuration_schema.clone(), auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number ), Error::::ProgramAlreadySet @@ -105,7 +107,7 @@ fn set_program() { program_2.clone(), configuration_schema.clone(), auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number ), Error::::TooManyProgramsOwned @@ -117,7 +119,7 @@ fn set_program() { too_long, configuration_schema, auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number ), Error::::ProgramLengthExceeded @@ -131,15 +133,18 @@ fn remove_program() { let program = vec![10u8, 11u8]; let configuration_schema = vec![14u8]; let auxiliary_data_schema = vec![15u8]; - let oracle_data_pointer = vec![16u8]; + let oracle_data_pointers = BoundedVec::try_from([vec![16u8]].to_vec()).unwrap(); let version_number = 0u8; let mut hash_input: Vec = vec![]; hash_input.extend(&program); hash_input.extend(&configuration_schema); hash_input.extend(&auxiliary_data_schema); - hash_input.extend(&oracle_data_pointer); hash_input.extend(&vec![version_number]); - let program_hash = ::Hashing::hash(&hash_input); + + let (_oracle_length, hash_input_with_oracle) = + ProgramsPallet::get_length_and_hash_of_oracle(&oracle_data_pointers, hash_input) + .unwrap(); + let program_hash = ::Hashing::hash(&hash_input_with_oracle); // no program assert_noop!( @@ -157,7 +162,7 @@ fn remove_program() { program.clone(), configuration_schema.clone(), auxiliary_data_schema.clone(), - oracle_data_pointer.clone(), + oracle_data_pointers.clone(), version_number )); assert_eq!( @@ -206,7 +211,7 @@ fn remove_program_fails_ref_count() { let program_hash = ::Hashing::hash(&program); let configuration_schema = vec![14u8]; let auxiliary_data_schema = vec![15u8]; - let oracle_data_pointer = vec![16u8]; + let oracle_data_pointers = BoundedVec::try_from([vec![16u8]].to_vec()).unwrap(); let version_number = 0u8; Programs::::insert( @@ -215,7 +220,7 @@ fn remove_program_fails_ref_count() { bytecode: program, configuration_schema, auxiliary_data_schema, - oracle_data_pointer, + oracle_data_pointers, deployer: PROGRAM_MODIFICATION_ACCOUNT, ref_counter: 1u128, version_number, diff --git a/pallets/programs/src/weights.rs b/pallets/programs/src/weights.rs index 2a8934e95..29e3f509d 100644 --- a/pallets/programs/src/weights.rs +++ b/pallets/programs/src/weights.rs @@ -52,79 +52,85 @@ use core::marker::PhantomData; /// Weight functions needed for pallet_programs. pub trait WeightInfo { - fn set_program() -> Weight; - fn remove_program(p: u32) -> Weight; + fn set_program(o: u32) -> Weight; + fn remove_program(o: u32, p: u32) -> Weight; } /// Weights for pallet_programs using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Programs::Bytecode` (r:1 w:1) - /// Proof: `Programs::Bytecode` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Programs::Programs` (r:1 w:1) + /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Programs::OwnedPrograms` (r:1 w:1) /// Proof: `Programs::OwnedPrograms` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn set_program() -> Weight { + /// The range of component `o` is `[0, 10]`. + fn set_program(_o: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 26_000_000 picoseconds. - Weight::from_parts(27_000_000, 0) - .saturating_add(Weight::from_parts(0, 3607)) + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(26_554_140, 0) + .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Programs::Bytecode` (r:1 w:1) - /// Proof: `Programs::Bytecode` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Programs::Programs` (r:1 w:1) + /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Programs::OwnedPrograms` (r:1 w:1) /// Proof: `Programs::OwnedPrograms` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[0, 25]`. - fn remove_program(p: u32, ) -> Weight { + /// The range of component `p` is `[0, 250]`. + /// The range of component `o` is `[0, 10]`. + fn remove_program(p: u32, o: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `326 + p * (32 ±0)` - // Estimated: `3809 + p * (31 ±0)` - // Minimum execution time: 26_000_000 picoseconds. - Weight::from_parts(26_938_669, 0) - .saturating_add(Weight::from_parts(0, 3809)) - // Standard Error: 47_904 - .saturating_add(Weight::from_parts(136_174, 0).saturating_mul(p.into())) + // Measured: `353 + o * (1 ±0) + p * (32 ±0)` + // Estimated: `3842 + o * (1 ±0) + p * (32 ±0)` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(28_023_735, 0) + .saturating_add(Weight::from_parts(0, 3842)) + // Standard Error: 11_641 + .saturating_add(Weight::from_parts(103_353, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) - .saturating_add(Weight::from_parts(0, 31).saturating_mul(p.into())) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into())) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) } } // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Programs::Bytecode` (r:1 w:1) - /// Proof: `Programs::Bytecode` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Programs::Programs` (r:1 w:1) + /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Programs::OwnedPrograms` (r:1 w:1) /// Proof: `Programs::OwnedPrograms` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn set_program() -> Weight { + /// The range of component `o` is `[0, 10]`. + fn set_program(_o: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 26_000_000 picoseconds. - Weight::from_parts(27_000_000, 0) - .saturating_add(Weight::from_parts(0, 3607)) + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(26_554_140, 0) + .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(RocksDbWeight::get().reads(2)) .saturating_add(RocksDbWeight::get().writes(2)) } - /// Storage: `Programs::Bytecode` (r:1 w:1) - /// Proof: `Programs::Bytecode` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Programs::Programs` (r:1 w:1) + /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Programs::OwnedPrograms` (r:1 w:1) /// Proof: `Programs::OwnedPrograms` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[0, 25]`. - fn remove_program(p: u32, ) -> Weight { + /// The range of component `p` is `[0, 250]`. + /// The range of component `o` is `[0, 10]`. + fn remove_program(p: u32, o: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `326 + p * (32 ±0)` - // Estimated: `3809 + p * (31 ±0)` - // Minimum execution time: 26_000_000 picoseconds. - Weight::from_parts(26_938_669, 0) - .saturating_add(Weight::from_parts(0, 3809)) - // Standard Error: 47_904 - .saturating_add(Weight::from_parts(136_174, 0).saturating_mul(p.into())) + // Measured: `353 + o * (1 ±0) + p * (32 ±0)` + // Estimated: `3842 + o * (1 ±0) + p * (32 ±0)` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(28_023_735, 0) + .saturating_add(Weight::from_parts(0, 3842)) + // Standard Error: 11_641 + .saturating_add(Weight::from_parts(103_353, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2)) .saturating_add(RocksDbWeight::get().writes(2)) - .saturating_add(Weight::from_parts(0, 31).saturating_mul(p.into())) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into())) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) } } diff --git a/pallets/propagation/Cargo.toml b/pallets/propagation/Cargo.toml index b21818add..c6734fd05 100644 --- a/pallets/propagation/Cargo.toml +++ b/pallets/propagation/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='pallet-propagation' -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -26,13 +26,13 @@ sp-io ={ version="31.0.0", default-features=false } sp-runtime ={ version="32.0.0", default-features=false } sp-staking ={ version="27.0.0", default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../../crates/shared", default-features=false, features=[ +entropy-shared={ version="0.3.0", path="../../crates/shared", default-features=false, features=[ "wasm-no-std", ] } -pallet-registry={ version="0.3.0-rc.1", path="../registry", default-features=false } -pallet-programs={ version="0.3.0-rc.1", path="../programs", default-features=false } -pallet-staking-extension={ version="0.3.0-rc.1", path="../staking", default-features=false } -pallet-attestation={ version="0.3.0-rc.1", path="../attestation", default-features=false } +pallet-registry={ version="0.3.0", path="../registry", default-features=false } +pallet-programs={ version="0.3.0", path="../programs", default-features=false } +pallet-staking-extension={ version="0.3.0", path="../staking", default-features=false } +pallet-attestation={ version="0.3.0", path="../attestation", default-features=false } [dev-dependencies] parking_lot="0.12.3" @@ -47,7 +47,7 @@ pallet-staking-reward-curve ={ version="11.0.0" } pallet-timestamp ={ version="28.0.0", default-features=false } sp-keystore ={ version="0.35.0" } sp-npos-elections ={ version="27.0.0", default-features=false } -pallet-parameters ={ version="0.3.0-rc.1", path="../parameters", default-features=false } +pallet-parameters ={ version="0.3.0", path="../parameters", default-features=false } [features] default=['std'] diff --git a/pallets/propagation/src/mock.rs b/pallets/propagation/src/mock.rs index 2b227bcea..cde2bb725 100644 --- a/pallets/propagation/src/mock.rs +++ b/pallets/propagation/src/mock.rs @@ -351,6 +351,7 @@ parameter_types! { pub const MaxBytecodeLength: u32 = 3; pub const ProgramDepositPerByte: u32 = 5; pub const MaxOwnedPrograms: u32 = 5; + pub const MaxOracleLookups: u32 = 5; } impl pallet_programs::Config for Test { @@ -358,6 +359,7 @@ impl pallet_programs::Config for Test { type MaxBytecodeLength = MaxBytecodeLength; type ProgramDepositPerByte = ProgramDepositPerByte; type MaxOwnedPrograms = MaxOwnedPrograms; + type MaxOracleLookups = MaxOracleLookups; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } diff --git a/pallets/registry/Cargo.toml b/pallets/registry/Cargo.toml index a8bbc0922..e172ac17d 100644 --- a/pallets/registry/Cargo.toml +++ b/pallets/registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='pallet-registry' -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -29,12 +29,12 @@ sp-core ={ version="29.0.0", default-features=false } sp-runtime ={ version="32.0.0", default-features=false } sp-std ={ version="14.0.0", default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../../crates/shared", features=[ +entropy-shared={ version="0.3.0", path="../../crates/shared", features=[ "wasm-no-std", ], default-features=false } -pallet-programs={ version="0.3.0-rc.1", path="../programs", default-features=false } -pallet-staking-extension={ version="0.3.0-rc.1", path="../staking", default-features=false } -pallet-parameters={ version="0.3.0-rc.1", path="../parameters", default-features=false } +pallet-programs={ version="0.3.0", path="../programs", default-features=false } +pallet-staking-extension={ version="0.3.0", path="../staking", default-features=false } +pallet-parameters={ version="0.3.0", path="../parameters", default-features=false } [dev-dependencies] frame-election-provider-support={ version="29.0.0", default-features=false } diff --git a/pallets/registry/src/benchmarking.rs b/pallets/registry/src/benchmarking.rs index dee1c07f2..65849c535 100644 --- a/pallets/registry/src/benchmarking.rs +++ b/pallets/registry/src/benchmarking.rs @@ -22,7 +22,7 @@ use frame_support::{ BoundedVec, }; use frame_system::{EventRecord, RawOrigin}; -use pallet_programs::{ProgramInfo, Programs}; +use pallet_programs::{OraclePointers, ProgramInfo, Programs}; use pallet_session::Validators; use pallet_staking_extension::{ benchmarking::create_validators, JumpStartDetails, JumpStartProgress, JumpStartStatus, @@ -165,7 +165,7 @@ benchmarks! { let program = vec![0u8]; let configuration_schema = vec![1u8]; let auxiliary_data_schema = vec![2u8]; - let oracle_data_pointer = vec![3u8]; + let oracle_data_pointers: OraclePointers = BoundedVec::try_from([vec![3u8]].to_vec()).unwrap(); let program_hash = T::Hashing::hash(&program); let programs_info = BoundedVec::try_from(vec![ ProgramInstance { @@ -182,7 +182,7 @@ benchmarks! { bytecode: program, configuration_schema, auxiliary_data_schema, - oracle_data_pointer, + oracle_data_pointers, deployer: program_modification_account.clone(), ref_counter: 0, version_number: 0, @@ -251,7 +251,7 @@ benchmarks! { let program = vec![0u8]; let configuration_schema = vec![1u8]; let auxiliary_data_schema = vec![2u8]; - let oracle_data_pointer = vec![3u8]; + let oracle_data_pointers: OraclePointers = BoundedVec::try_from([vec![3u8]].to_vec()).unwrap(); let program_hash = T::Hashing::hash(&program); let programs_info = BoundedVec::try_from(vec![ProgramInstance { program_pointer: program_hash, @@ -266,8 +266,8 @@ benchmarks! { }; n as usize]) .unwrap(); let sig_req_account: T::AccountId = whitelisted_caller(); - Programs::::insert(program_hash, ProgramInfo {bytecode: program, configuration_schema: configuration_schema.clone(), auxiliary_data_schema: auxiliary_data_schema.clone(), oracle_data_pointer: oracle_data_pointer.clone(), deployer: program_modification_account.clone(), ref_counter: 0, version_number: 0}); - Programs::::insert(new_program_hash, ProgramInfo {bytecode: new_program, configuration_schema, auxiliary_data_schema, oracle_data_pointer, deployer: program_modification_account.clone(), ref_counter: o as u128, version_number: 0}); + Programs::::insert(program_hash, ProgramInfo {bytecode: program, configuration_schema: configuration_schema.clone(), auxiliary_data_schema: auxiliary_data_schema.clone(), oracle_data_pointers: oracle_data_pointers.clone(), deployer: program_modification_account.clone(), ref_counter: 0, version_number: 0}); + Programs::::insert(new_program_hash, ProgramInfo {bytecode: new_program, configuration_schema, auxiliary_data_schema, oracle_data_pointers, deployer: program_modification_account.clone(), ref_counter: o as u128, version_number: 0}); let balance = ::Currency::minimum_balance() * 100u32.into(); let _ = ::Currency::make_free_balance_be(&sig_req_account, balance); >::insert( @@ -291,7 +291,7 @@ benchmarks! { let program = vec![0u8]; let configuration_schema = vec![1u8]; let auxiliary_data_schema = vec![2u8]; - let oracle_data_pointer = vec![3u8]; + let oracle_data_pointers: OraclePointers = BoundedVec::try_from([vec![3u8]].to_vec()).unwrap(); let program_hash = T::Hashing::hash(&program); let programs_info = BoundedVec::try_from(vec![ProgramInstance { program_pointer: program_hash, diff --git a/pallets/registry/src/mock.rs b/pallets/registry/src/mock.rs index b9451ff8b..85c5c1fe6 100644 --- a/pallets/registry/src/mock.rs +++ b/pallets/registry/src/mock.rs @@ -348,6 +348,7 @@ parameter_types! { pub const MaxBytecodeLength: u32 = 3; pub const ProgramDepositPerByte: u32 = 5; pub const MaxOwnedPrograms: u32 = 5; + pub const MaxOracleLookups: u32 = 5; } impl pallet_programs::Config for Test { @@ -355,6 +356,7 @@ impl pallet_programs::Config for Test { type MaxBytecodeLength = MaxBytecodeLength; type ProgramDepositPerByte = ProgramDepositPerByte; type MaxOwnedPrograms = MaxOwnedPrograms; + type MaxOracleLookups = MaxOracleLookups; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } diff --git a/pallets/registry/src/tests.rs b/pallets/registry/src/tests.rs index f382bd34c..206f7ce4f 100644 --- a/pallets/registry/src/tests.rs +++ b/pallets/registry/src/tests.rs @@ -43,7 +43,8 @@ fn setup_programs( bytecode: empty_program.clone(), configuration_schema: empty_program.clone(), auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), + oracle_data_pointers: BoundedVec::try_from(vec![empty_program.clone()].to_vec()) + .unwrap(), deployer: alice, ref_counter: 0, version_number: 0, @@ -479,7 +480,8 @@ fn it_changes_a_program_instance() { bytecode: empty_program.clone(), configuration_schema: empty_program.clone(), auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), + oracle_data_pointers: BoundedVec::try_from(vec![empty_program.clone()].to_vec()) + .unwrap(), deployer: 1, ref_counter: 1, version_number: 0, @@ -500,7 +502,8 @@ fn it_changes_a_program_instance() { bytecode: new_program, configuration_schema: empty_program.clone(), auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), + oracle_data_pointers: BoundedVec::try_from(vec![empty_program.clone()].to_vec()) + .unwrap(), deployer: 1, ref_counter: 1, version_number: 0, diff --git a/pallets/slashing/Cargo.toml b/pallets/slashing/Cargo.toml index 7e3c90df8..d360f0925 100644 --- a/pallets/slashing/Cargo.toml +++ b/pallets/slashing/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='pallet-slashing' -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' diff --git a/pallets/staking/Cargo.toml b/pallets/staking/Cargo.toml index 4aa83ec0e..70da4e1c2 100644 --- a/pallets/staking/Cargo.toml +++ b/pallets/staking/Cargo.toml @@ -1,6 +1,6 @@ [package] name ='pallet-staking-extension' -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -15,7 +15,7 @@ targets=['x86_64-unknown-linux-gnu'] codec ={ package="parity-scale-codec", version="3.6.3", default-features=false, features=["derive"] } scale-info ={ version="2.11", default-features=false, features=["derive"] } log ={ version="0.4.22", default-features=false } -serde ={ version="1.0.214", default-features=false } +serde ={ version="1.0.215", default-features=false } rand_chacha={ version="0.3", default-features=false } frame-benchmarking={ version="29.0.0", default-features=false, optional=true } @@ -33,8 +33,8 @@ spki ="0.7.3" p256 ={ version="0.13.2", default-features=false, features=["ecdsa"] } rand ={ version="0.8.5", default-features=false, features=["alloc"] } -pallet-parameters={ version="0.3.0-rc.1", path="../parameters", default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../../crates/shared", features=[ +pallet-parameters={ version="0.3.0", path="../parameters", default-features=false } +entropy-shared={ version="0.3.0", path="../../crates/shared", features=[ "wasm-no-std", ], default-features=false } diff --git a/pallets/staking/src/benchmarking.rs b/pallets/staking/src/benchmarking.rs index 7969acbd3..112a9c978 100644 --- a/pallets/staking/src/benchmarking.rs +++ b/pallets/staking/src/benchmarking.rs @@ -19,7 +19,7 @@ use super::*; use crate::pck::{signing_key_from_seed, MOCK_PCK_DERIVED_FROM_NULL_ARRAY}; #[allow(unused_imports)] use crate::Pallet as Staking; -use entropy_shared::{AttestationHandler, MAX_SIGNERS}; +use entropy_shared::{AttestationHandler, QuoteContext, MAX_SIGNERS}; use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; use frame_support::{ assert_ok, ensure, @@ -78,7 +78,6 @@ fn prepare_attestation_for_validate( threshold: T::AccountId, x25519_public_key: [u8; 32], endpoint: Vec, - block_number: u32, ) -> (Vec, JoiningServerInfo) { let nonce = NULL_ARR; let quote = { @@ -91,8 +90,12 @@ fn prepare_attestation_for_validate( let attestation_key = tdx_quote::SigningKey::from_bytes(&ATTESTATION_KEY.into()).unwrap(); - let input_data = - entropy_shared::QuoteInputData::new(&threshold, x25519_public_key, nonce, block_number); + let input_data = entropy_shared::QuoteInputData::new( + &threshold, + x25519_public_key, + nonce, + QuoteContext::Validate, + ); tdx_quote::Quote::mock(attestation_key.clone(), pck, input_data.0).as_bytes().to_vec() }; @@ -132,14 +135,9 @@ fn prep_bond_and_validate( )); if validate_also { - let block_number = 0; - let endpoint = vec![20, 20]; - let (quote, joining_server_info) = prepare_attestation_for_validate::( - threshold, - x25519_public_key, - endpoint, - block_number, - ); + let endpoint = b"http://localhost:3001".to_vec(); + let (quote, joining_server_info) = + prepare_attestation_for_validate::(threshold, x25519_public_key, endpoint); assert_ok!(>::validate( RawOrigin::Signed(bonder.clone()).into(), @@ -172,33 +170,81 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let bonder: T::AccountId = account("bond", 0, SEED); let threshold: T::AccountId = account("threshold", 0, SEED); + + let endpoint = b"http://localhost:3001"; let x25519_public_key = NULL_ARR; - prep_bond_and_validate::(true, caller.clone(), bonder.clone(), threshold, NULL_ARR); + let validate_also = true; + prep_bond_and_validate::( + validate_also, + caller.clone(), + bonder.clone(), + threshold.clone(), + x25519_public_key.clone(), + ); - }: _(RawOrigin::Signed(bonder.clone()), vec![30]) + let quote = prepare_attestation_for_validate::( + threshold, + x25519_public_key, + endpoint.clone().to_vec(), + ) + .0; + }: _(RawOrigin::Signed(bonder.clone()), endpoint.to_vec(), quote) verify { - assert_last_event::(Event::::EndpointChanged(bonder, vec![30]).into()); + assert_last_event::(Event::::EndpointChanged(bonder, endpoint.to_vec()).into()); } change_threshold_accounts { let s in 0 .. MAX_SIGNERS as u32; + let caller: T::AccountId = whitelisted_caller(); let _bonder: T::AccountId = account("bond", 0, SEED); - let validator_id_res = ::ValidatorId::try_from(_bonder.clone()).or(Err(Error::::InvalidValidatorId)); - let validator_id_signers = ::ValidatorId::try_from(caller.clone()).or(Err(Error::::InvalidValidatorId)).unwrap(); - let bonder: T::ValidatorId = validator_id_res.expect("Issue converting account id into validator id"); + + let validator_id_res = ::ValidatorId::try_from(_bonder.clone()) + .or(Err(Error::::InvalidValidatorId)); + let validator_id_signers = ::ValidatorId::try_from(caller.clone()) + .or(Err(Error::::InvalidValidatorId)) + .unwrap(); + let bonder: T::ValidatorId = + validator_id_res.expect("Issue converting account id into validator id"); + let threshold: T::AccountId = account("threshold", 0, SEED); + let new_threshold: T::AccountId = account("new_threshold", 0, SEED); + let x25519_public_key: [u8; 32] = NULL_ARR; - prep_bond_and_validate::(true, caller.clone(), _bonder.clone(), threshold, NULL_ARR); + let endpoint = b"http://localhost:3001".to_vec(); + + let validate_also = true; + prep_bond_and_validate::( + validate_also, + caller.clone(), + _bonder.clone(), + threshold.clone(), + x25519_public_key.clone(), + ); + + // For quote verification this needs to be the _next_ block, and right now we're at block `0`. + let (quote , joining_server_info) = prepare_attestation_for_validate::( + new_threshold.clone(), + x25519_public_key, + endpoint.clone().to_vec(), + ); + + let pck_certificate_chain = joining_server_info.pck_certificate_chain; + let signers = vec![validator_id_signers.clone(); s as usize]; Signers::::put(signers.clone()); - - }: _(RawOrigin::Signed(_bonder.clone()), _bonder.clone(), NULL_ARR) + }: _( + RawOrigin::Signed(_bonder.clone()), + new_threshold.clone(), + x25519_public_key.clone(), + pck_certificate_chain, + quote + ) verify { let server_info = ServerInfo { - endpoint: vec![20, 20], - tss_account: _bonder.clone(), + endpoint: b"http://localhost:3001".to_vec(), + tss_account: new_threshold.clone(), x25519_public_key: NULL_ARR, provisioning_certification_key: MOCK_PCK_DERIVED_FROM_NULL_ARRAY.to_vec().try_into().unwrap(), }; @@ -330,9 +376,8 @@ benchmarks! { x25519_public_key.clone() ); - let block_number = 1; let (quote, joining_server_info) = - prepare_attestation_for_validate::(threshold_account.clone(), x25519_public_key, endpoint.clone(), block_number); + prepare_attestation_for_validate::(threshold_account.clone(), x25519_public_key, endpoint.clone()); }: _(RawOrigin::Signed(bonder.clone()), ValidatorPrefs::default(), joining_server_info, quote) verify { assert_last_event::( diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index 4f7f854de..b88cc7da7 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -60,8 +60,8 @@ use sp_staking::SessionIndex; #[frame_support::pallet] pub mod pallet { use entropy_shared::{ - ValidatorInfo, X25519PublicKey, EVE_VERIFYING_KEY, MAX_SIGNERS, TEST_RESHARE_BLOCK_NUMBER, - VERIFICATION_KEY_LENGTH, + QuoteContext, ValidatorInfo, X25519PublicKey, EVE_VERIFYING_KEY, MAX_SIGNERS, + TEST_RESHARE_BLOCK_NUMBER, VERIFICATION_KEY_LENGTH, }; use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, @@ -392,12 +392,26 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Allows a validator to change their endpoint so signers can find them when they are coms - /// manager `endpoint`: nodes's endpoint + /// Allows a validator to change the endpoint used by their Threshold Siganture Scheme + /// (TSS) server. + /// + /// # Expects TDX Quote + /// + /// A valid TDX quote must be passed along in order to ensure that the validator is running + /// TDX hardware. In order for the chain to be aware that a quote is expected from the + /// validator `pallet_attestation::request_attestation()` must be called first. + /// + /// The quote format is specified in: + /// https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/Intel_TDX_DCAP_Quoting_Library_API.pdf #[pallet::call_index(0)] #[pallet::weight(::WeightInfo::change_endpoint())] - pub fn change_endpoint(origin: OriginFor, endpoint: Vec) -> DispatchResult { + pub fn change_endpoint( + origin: OriginFor, + endpoint: Vec, + quote: Vec, + ) -> DispatchResult { let who = ensure_signed(origin)?; + ensure!( endpoint.len() as u32 <= T::MaxEndpointLength::get(), Error::::EndpointTooLong @@ -410,31 +424,61 @@ pub mod pallet { ThresholdServers::::try_mutate(&validator_id, |maybe_server_info| { if let Some(server_info) = maybe_server_info { + // Before we modify the `server_info`, we want to check that the validator is + // still running TDX hardware. + ensure!( + >::verify_quote( + &server_info.tss_account.clone(), + server_info.x25519_public_key, + server_info.provisioning_certification_key.clone(), + quote, + QuoteContext::ChangeEndpoint, + ) + .is_ok(), + Error::::FailedAttestationCheck + ); + server_info.endpoint.clone_from(&endpoint); + Ok(()) } else { Err(Error::::NoBond) } })?; + Self::deposit_event(Event::EndpointChanged(who, endpoint)); Ok(()) } - /// Allows a validator to change their threshold key so can confirm done when coms manager - /// `new_account`: nodes's threshold account + /// Allows a validator to change their associated threshold server AccountID and X25519 + /// public key. + /// + /// # Expects TDX Quote + /// + /// A valid TDX quote must be passed along in order to ensure that the validator is running + /// TDX hardware. In order for the chain to be aware that a quote is expected from the + /// validator `pallet_attestation::request_attestation()` must be called first. + /// + /// The **new** TSS AccountID must be used when requesting this quote. + /// + /// The quote format is specified in: + /// https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/Intel_TDX_DCAP_Quoting_Library_API.pdf #[pallet::call_index(1)] #[pallet::weight(::WeightInfo::change_threshold_accounts(MAX_SIGNERS as u32))] pub fn change_threshold_accounts( origin: OriginFor, tss_account: T::AccountId, x25519_public_key: X25519PublicKey, + pck_certificate_chain: Vec>, + quote: Vec, ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + ensure!( !ThresholdToStash::::contains_key(&tss_account), Error::::TssAccountAlreadyExists ); - let who = ensure_signed(origin)?; let stash = Self::get_stash(&who)?; let validator_id = ::ValidatorId::try_from(stash) .or(Err(Error::::InvalidValidatorId))?; @@ -445,20 +489,49 @@ pub mod pallet { Error::::NoChangingThresholdAccountWhenSigner ); - let new_server_info: ServerInfo = - ThresholdServers::::try_mutate(&validator_id, |maybe_server_info| { + let provisioning_certification_key = + T::PckCertChainVerifier::verify_pck_certificate_chain(pck_certificate_chain) + .map_err(|error| { + let e: Error = error.into(); + e + })?; + + let new_server_info: ServerInfo = ThresholdServers::::try_mutate( + &validator_id, + |maybe_server_info| { if let Some(server_info) = maybe_server_info { - server_info.tss_account = tss_account.clone(); + // Before we modify the `server_info`, we want to check that the validator is + // still running TDX hardware. + ensure!( + >::verify_quote( + &tss_account.clone(), + x25519_public_key, + provisioning_certification_key.clone(), + quote, + QuoteContext::ChangeThresholdAccounts, + ) + .is_ok(), + Error::::FailedAttestationCheck + ); + + server_info.tss_account = tss_account; server_info.x25519_public_key = x25519_public_key; - ThresholdToStash::::insert(&tss_account, &validator_id); + server_info.provisioning_certification_key = provisioning_certification_key; + + ThresholdToStash::::insert(&server_info.tss_account, &validator_id); + Ok(server_info.clone()) } else { Err(Error::::NoBond) } - })?; + }, + )?; + Self::deposit_event(Event::ThresholdAccountChanged(validator_id, new_server_info)); - Ok(Some(::WeightInfo::change_threshold_accounts(signers.len() as u32)) - .into()) + + let actual_weight = + ::WeightInfo::change_threshold_accounts(signers.len() as u32); + Ok(Some(actual_weight).into()) } /// Wraps's Substrate's `unbond` extrinsic but checks to make sure targeted account is not a signer or next signer @@ -535,9 +608,11 @@ pub mod pallet { /// Wrap's Substrate's `staking_pallet::validate()` extrinsic, but enforces that /// information about a validator's threshold server is provided. /// + /// # Expects TDX Quote + /// /// A valid TDX quote must be passed along in order to ensure that the validator candidate /// is running TDX hardware. In order for the chain to be aware that a quote is expected - /// from the candidate, `pallet_attestation::request_attestation()` must be called first. + /// from the candidate `pallet_attestation::request_attestation()` must be called first. /// /// The quote format is specified in: /// https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/Intel_TDX_DCAP_Quoting_Library_API.pdf @@ -586,7 +661,8 @@ pub mod pallet { &server_info.tss_account.clone(), server_info.x25519_public_key, server_info.provisioning_certification_key.clone(), - quote + quote, + QuoteContext::Validate, ) .is_ok(), Error::::FailedAttestationCheck @@ -735,6 +811,11 @@ pub mod pallet { return Ok(weight); } + // Network not jumpstarted + if current_signers_length == 0 { + return Ok(weight); + } + let mut new_signers: Vec> = vec![]; let mut count = 0u32; let mut remove_indicies_len = 0; diff --git a/pallets/staking/src/mock.rs b/pallets/staking/src/mock.rs index 2ff3f8dd1..21a35e06e 100644 --- a/pallets/staking/src/mock.rs +++ b/pallets/staking/src/mock.rs @@ -16,6 +16,7 @@ use core::convert::{TryFrom, TryInto}; use std::cell::RefCell; +use entropy_shared::QuoteContext; use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, onchain, SequentialPhragmen, VoteWeight, @@ -400,6 +401,7 @@ impl entropy_shared::AttestationHandler for MockAttestationHandler { _x25519_public_key: entropy_shared::X25519PublicKey, _provisioning_certification_key: entropy_shared::BoundedVecEncodedVerifyingKey, quote: Vec, + _context: QuoteContext, ) -> Result<(), sp_runtime::DispatchError> { let quote: Result<[u8; 32], _> = quote.try_into(); match quote { diff --git a/pallets/staking/src/tests.rs b/pallets/staking/src/tests.rs index 0340d4cf9..92125b2a9 100644 --- a/pallets/staking/src/tests.rs +++ b/pallets/staking/src/tests.rs @@ -82,7 +82,7 @@ fn it_takes_in_an_endpoint() { let joining_server_info = JoiningServerInfo { tss_account: 3, x25519_public_key: NULL_ARR, - endpoint: vec![20; 26], + endpoint: [20; (crate::tests::MaxEndpointLength::get() + 1) as usize].to_vec(), pck_certificate_chain: vec![[0u8; 32].to_vec()], }; assert_noop!( @@ -156,6 +156,8 @@ fn it_will_not_allow_validator_to_use_existing_tss_account() { #[test] fn it_changes_endpoint() { new_test_ext().execute_with(|| { + let endpoint = b"http://localhost:3001".to_vec(); + assert_ok!(FrameStaking::bond( RuntimeOrigin::signed(1), 100u64, @@ -165,7 +167,7 @@ fn it_changes_endpoint() { let joining_server_info = JoiningServerInfo { tss_account: 3, x25519_public_key: NULL_ARR, - endpoint: vec![20], + endpoint: endpoint.clone(), pck_certificate_chain: vec![[0u8; 32].to_vec()], }; assert_ok!(Staking::validate( @@ -175,16 +177,52 @@ fn it_changes_endpoint() { VALID_QUOTE.to_vec(), )); - assert_ok!(Staking::change_endpoint(RuntimeOrigin::signed(1), vec![30])); - assert_eq!(Staking::threshold_server(1).unwrap().endpoint, vec![30]); + assert_ok!(Staking::change_endpoint( + RuntimeOrigin::signed(1), + endpoint.clone(), + VALID_QUOTE.to_vec() + )); + assert_eq!(Staking::threshold_server(1).unwrap().endpoint, endpoint); assert_noop!( - Staking::change_endpoint(RuntimeOrigin::signed(3), vec![30]), + Staking::change_endpoint(RuntimeOrigin::signed(3), endpoint, VALID_QUOTE.to_vec()), Error::::NoBond ); }); } +#[test] +fn it_doesnt_change_endpoint_with_invalid_quote() { + new_test_ext().execute_with(|| { + let endpoint = b"http://localhost:3001".to_vec(); + + assert_ok!(FrameStaking::bond( + RuntimeOrigin::signed(1), + 100u64, + pallet_staking::RewardDestination::Account(1), + )); + + let joining_server_info = JoiningServerInfo { + tss_account: 3, + x25519_public_key: NULL_ARR, + endpoint: endpoint.clone(), + pck_certificate_chain: vec![[0u8; 32].to_vec()], + }; + + assert_ok!(Staking::validate( + RuntimeOrigin::signed(1), + pallet_staking::ValidatorPrefs::default(), + joining_server_info.clone(), + VALID_QUOTE.to_vec(), + )); + + assert_noop!( + Staking::change_endpoint(RuntimeOrigin::signed(1), endpoint, INVALID_QUOTE.to_vec()), + Error::::FailedAttestationCheck + ); + }) +} + #[test] fn it_changes_threshold_account() { new_test_ext().execute_with(|| { @@ -194,11 +232,12 @@ fn it_changes_threshold_account() { pallet_staking::RewardDestination::Account(1), )); + let pck_certificate_chain = vec![vec![0u8; 32]]; let joining_server_info = JoiningServerInfo { tss_account: 3, x25519_public_key: NULL_ARR, endpoint: vec![20], - pck_certificate_chain: vec![[0u8; 32].to_vec()], + pck_certificate_chain: pck_certificate_chain.clone(), }; assert_ok!(Staking::validate( RuntimeOrigin::signed(1), @@ -207,12 +246,24 @@ fn it_changes_threshold_account() { VALID_QUOTE.to_vec(), )); - assert_ok!(Staking::change_threshold_accounts(RuntimeOrigin::signed(1), 4, NULL_ARR)); + assert_ok!(Staking::change_threshold_accounts( + RuntimeOrigin::signed(1), + 4, + NULL_ARR, + pck_certificate_chain.clone(), + VALID_QUOTE.to_vec() + )); assert_eq!(Staking::threshold_server(1).unwrap().tss_account, 4); assert_eq!(Staking::threshold_to_stash(4).unwrap(), 1); assert_noop!( - Staking::change_threshold_accounts(RuntimeOrigin::signed(4), 5, NULL_ARR), + Staking::change_threshold_accounts( + RuntimeOrigin::signed(4), + 5, + NULL_ARR, + pck_certificate_chain.clone(), + VALID_QUOTE.to_vec() + ), Error::::NotController ); @@ -227,7 +278,7 @@ fn it_changes_threshold_account() { tss_account: 5, x25519_public_key: NULL_ARR, endpoint: vec![20], - pck_certificate_chain: vec![[0u8; 32].to_vec()], + pck_certificate_chain: pck_certificate_chain.clone(), }; assert_ok!(Staking::validate( RuntimeOrigin::signed(2), @@ -237,18 +288,66 @@ fn it_changes_threshold_account() { )); assert_noop!( - Staking::change_threshold_accounts(RuntimeOrigin::signed(1), 5, NULL_ARR), + Staking::change_threshold_accounts( + RuntimeOrigin::signed(1), + 5, + NULL_ARR, + pck_certificate_chain.clone(), + VALID_QUOTE.to_vec() + ), Error::::TssAccountAlreadyExists ); Signers::::put(vec![1]); assert_noop!( - Staking::change_threshold_accounts(RuntimeOrigin::signed(1), 9, NULL_ARR,), + Staking::change_threshold_accounts( + RuntimeOrigin::signed(1), + 9, + NULL_ARR, + pck_certificate_chain.clone(), + VALID_QUOTE.to_vec() + ), Error::::NoChangingThresholdAccountWhenSigner ); }); } +#[test] +fn it_doesnt_allow_changing_threshold_account_with_invalid_quote() { + new_test_ext().execute_with(|| { + assert_ok!(FrameStaking::bond( + RuntimeOrigin::signed(1), + 100u64, + pallet_staking::RewardDestination::Account(1), + )); + + let pck_certificate_chain = vec![[0u8; 32].to_vec()]; + let joining_server_info = JoiningServerInfo { + tss_account: 3, + x25519_public_key: NULL_ARR, + endpoint: vec![20], + pck_certificate_chain: pck_certificate_chain.clone(), + }; + assert_ok!(Staking::validate( + RuntimeOrigin::signed(1), + pallet_staking::ValidatorPrefs::default(), + joining_server_info.clone(), + VALID_QUOTE.to_vec(), + )); + + assert_noop!( + Staking::change_threshold_accounts( + RuntimeOrigin::signed(1), + 4, + NULL_ARR, + pck_certificate_chain.clone(), + INVALID_QUOTE.to_vec() + ), + Error::::FailedAttestationCheck + ); + }) +} + #[test] fn it_will_not_allow_existing_tss_account_when_changing_threshold_account() { new_test_ext().execute_with(|| { @@ -258,11 +357,12 @@ fn it_will_not_allow_existing_tss_account_when_changing_threshold_account() { pallet_staking::RewardDestination::Account(1), )); + let pck_certificate_chain = vec![[0u8; 32].to_vec()]; let joining_server_info = JoiningServerInfo { tss_account: 3, x25519_public_key: NULL_ARR, endpoint: vec![20], - pck_certificate_chain: vec![[0u8; 32].to_vec()], + pck_certificate_chain: pck_certificate_chain.clone(), }; assert_ok!(Staking::validate( RuntimeOrigin::signed(1), @@ -282,7 +382,7 @@ fn it_will_not_allow_existing_tss_account_when_changing_threshold_account() { tss_account: 5, x25519_public_key: NULL_ARR, endpoint: vec![20], - pck_certificate_chain: vec![[0u8; 32].to_vec()], + pck_certificate_chain: pck_certificate_chain.clone(), }; assert_ok!(Staking::validate( RuntimeOrigin::signed(2), @@ -292,7 +392,13 @@ fn it_will_not_allow_existing_tss_account_when_changing_threshold_account() { )); assert_noop!( - Staking::change_threshold_accounts(RuntimeOrigin::signed(1), 5, NULL_ARR), + Staking::change_threshold_accounts( + RuntimeOrigin::signed(1), + 5, + NULL_ARR, + pck_certificate_chain.clone(), + VALID_QUOTE.to_vec() + ), Error::::TssAccountAlreadyExists ); }); @@ -417,6 +523,13 @@ fn it_deletes_when_no_bond_left() { }); } +#[test] +fn it_doesnt_panic_when_no_signers() { + new_test_ext().execute_with(|| { + assert_ok!(Staking::new_session_handler(&[1, 2, 3])); + }); +} + #[test] fn it_tests_new_session_handler() { new_test_ext().execute_with(|| { diff --git a/pallets/transaction-pause/Cargo.toml b/pallets/transaction-pause/Cargo.toml index c9a349a98..247605972 100644 --- a/pallets/transaction-pause/Cargo.toml +++ b/pallets/transaction-pause/Cargo.toml @@ -1,6 +1,6 @@ [package] name ="pallet-transaction-pause" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -25,7 +25,7 @@ pallet-balances={ version="29.0.0" } sp-core ={ version="29.0.0" } sp-io ={ version="31.0.0" } -pallet-programs={ version="0.3.0-rc.1", default-features=false, path="../programs" } +pallet-programs={ version="0.3.0", default-features=false, path="../programs" } [features] default=["std"] diff --git a/pallets/transaction-pause/src/mock.rs b/pallets/transaction-pause/src/mock.rs index 5cc9a2c58..961defb8b 100644 --- a/pallets/transaction-pause/src/mock.rs +++ b/pallets/transaction-pause/src/mock.rs @@ -86,6 +86,7 @@ parameter_types! { pub const MaxBytecodeLength: u32 = 3; pub const ProgramDepositPerByte: u32 = 5; pub const MaxOwnedPrograms: u32 = 5; + pub const MaxOracleLookups: u32 = 5; } impl pallet_programs::Config for Runtime { @@ -93,6 +94,7 @@ impl pallet_programs::Config for Runtime { type MaxBytecodeLength = MaxBytecodeLength; type ProgramDepositPerByte = ProgramDepositPerByte; type MaxOwnedPrograms = MaxOwnedPrograms; + type MaxOracleLookups = MaxOracleLookups; type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } diff --git a/pallets/transaction-pause/src/tests.rs b/pallets/transaction-pause/src/tests.rs index 7ac70ed75..b1c822d75 100644 --- a/pallets/transaction-pause/src/tests.rs +++ b/pallets/transaction-pause/src/tests.rs @@ -152,7 +152,7 @@ fn paused_transaction_filter_work() { new_program: vec![], configuration_schema: vec![], auxiliary_data_schema: vec![], - oracle_data_pointer: vec![], + oracle_data_pointers: BoundedVec::try_from(vec![vec![]].to_vec()).unwrap(), version_number: 0u8, }); assert!(!PausedTransactionFilter::::contains(BALANCE_TRANSFER)); diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index fd90c6247..3cdcdb26b 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -1,7 +1,7 @@ [package] name ='entropy-runtime' description="The substrate runtime for the Entropy chain node" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -95,17 +95,17 @@ pallet-utility ={ version="29.0.0", default-featur pallet-vesting ={ version="29.0.0", default-features=false } # Entropy Pallets -pallet-programs ={ version='0.3.0-rc.1', path='../pallets/programs', default-features=false } -pallet-propagation ={ version='0.3.0-rc.1', path='../pallets/propagation', default-features=false } -pallet-registry ={ version='0.3.0-rc.1', path='../pallets/registry', default-features=false } -pallet-slashing ={ version='0.3.0-rc.1', path='../pallets/slashing', default-features=false } -pallet-staking-extension={ version='0.3.0-rc.1', path='../pallets/staking', default-features=false } -pallet-transaction-pause={ version='0.3.0-rc.1', path='../pallets/transaction-pause', default-features=false } -pallet-parameters ={ version='0.3.0-rc.1', path='../pallets/parameters', default-features=false } -pallet-attestation ={ version='0.3.0-rc.1', path='../pallets/attestation', default-features=false } -pallet-oracle ={ version='0.3.0-rc.1', path='../pallets/oracle', default-features=false } +pallet-programs ={ version='0.3.0', path='../pallets/programs', default-features=false } +pallet-propagation ={ version='0.3.0', path='../pallets/propagation', default-features=false } +pallet-registry ={ version='0.3.0', path='../pallets/registry', default-features=false } +pallet-slashing ={ version='0.3.0', path='../pallets/slashing', default-features=false } +pallet-staking-extension={ version='0.3.0', path='../pallets/staking', default-features=false } +pallet-transaction-pause={ version='0.3.0', path='../pallets/transaction-pause', default-features=false } +pallet-parameters ={ version='0.3.0', path='../pallets/parameters', default-features=false } +pallet-attestation ={ version='0.3.0', path='../pallets/attestation', default-features=false } +pallet-oracle ={ version='0.3.0', path='../pallets/oracle', default-features=false } -entropy-shared={ version="0.3.0-rc.1", path="../crates/shared", default-features=false, features=[ +entropy-shared={ version="0.3.0", path="../crates/shared", default-features=false, features=[ "wasm-no-std", ] } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f801c6a94..461a4d49d 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1467,6 +1467,7 @@ parameter_types! { pub const MaxBytecodeLength: u32 = 1_000_000; pub const ProgramDepositPerByte: Balance = MILLICENTS; pub const MaxOwnedPrograms: u32 = 250; + pub const MaxOracleLookups: u32 = 10; } impl pallet_programs::Config for Runtime { @@ -1474,6 +1475,7 @@ impl pallet_programs::Config for Runtime { type MaxBytecodeLength = MaxBytecodeLength; type ProgramDepositPerByte = ProgramDepositPerByte; type MaxOwnedPrograms = MaxOwnedPrograms; + type MaxOracleLookups = MaxOracleLookups; type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_programs::WeightInfo; } diff --git a/runtime/src/weights/pallet_programs.rs b/runtime/src/weights/pallet_programs.rs index dc006272f..f9519b473 100644 --- a/runtime/src/weights/pallet_programs.rs +++ b/runtime/src/weights/pallet_programs.rs @@ -16,9 +16,9 @@ //! Autogenerated weights for `pallet_programs` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 33.0.0 -//! DATE: 2024-10-03, STEPS: `25`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-08, STEPS: `5`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `ip-172-31-28-93`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! HOSTNAME: `Jesses-MacBook-Pro.local`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 // Executed Command: @@ -27,14 +27,11 @@ // pallet // --chain // dev -// --wasm-execution=compiled // --pallet=pallet_programs // --extrinsic=* -// --steps=25 -// --repeat=10 +// --steps=5 +// --repeat=2 // --header=.maintain/AGPL-3.0-header.txt -// --template -// .maintain/frame-weight-template.hbs // --output=./runtime/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] @@ -52,12 +49,13 @@ impl pallet_programs::WeightInfo for WeightInfo { /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Programs::OwnedPrograms` (r:1 w:1) /// Proof: `Programs::OwnedPrograms` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn set_program() -> Weight { + /// The range of component `o` is `[0, 10]`. + fn set_program(_o: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `214` // Estimated: `3679` - // Minimum execution time: 39_231_000 picoseconds. - Weight::from_parts(39_935_000, 0) + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(26_554_140, 0) .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -67,17 +65,19 @@ impl pallet_programs::WeightInfo for WeightInfo { /// Storage: `Programs::OwnedPrograms` (r:1 w:1) /// Proof: `Programs::OwnedPrograms` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[0, 250]`. - fn remove_program(p: u32, ) -> Weight { + /// The range of component `o` is `[0, 10]`. + fn remove_program(p: u32, o: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `354 + p * (32 ±0)` - // Estimated: `3823 + p * (32 ±0)` - // Minimum execution time: 38_105_000 picoseconds. - Weight::from_parts(40_094_638, 0) - .saturating_add(Weight::from_parts(0, 3823)) - // Standard Error: 1_384 - .saturating_add(Weight::from_parts(149_685, 0).saturating_mul(p.into())) + // Measured: `353 + o * (1 ±0) + p * (32 ±0)` + // Estimated: `3842 + o * (1 ±0) + p * (32 ±0)` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(28_023_735, 0) + .saturating_add(Weight::from_parts(0, 3842)) + // Standard Error: 11_641 + .saturating_add(Weight::from_parts(103_353, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into())) .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) } -} \ No newline at end of file +} diff --git a/scripts/create-test-keyshares/Cargo.toml b/scripts/create-test-keyshares/Cargo.toml index 7b08991ea..4cfbdb541 100644 --- a/scripts/create-test-keyshares/Cargo.toml +++ b/scripts/create-test-keyshares/Cargo.toml @@ -1,7 +1,7 @@ [package] name ="entropy-create-test-keyshares" description="Makes a set of keyshares for testing entropy-tss" -version ='0.3.0-rc.1' +version ='0.3.0' authors =['Entropy Cryptography '] homepage ='https://entropy.xyz/' license ='AGPL-3.0-or-later' @@ -10,14 +10,14 @@ edition ='2021' publish =false [dependencies] -entropy-testing-utils={ version="0.3.0-rc.1", path="../../crates/testing-utils" } +entropy-testing-utils={ version="0.3.0", path="../../crates/testing-utils" } tokio ={ version="1.41", features=["macros", "fs", "rt-multi-thread", "io-util", "process"] } -entropy-shared ={ version="0.3.0-rc.1", path="../../crates/shared" } -entropy-kvdb ={ version="0.3.0-rc.1", path="../../crates/kvdb", default-features=false } +entropy-shared ={ version="0.3.0", path="../../crates/shared" } +entropy-kvdb ={ version="0.3.0", path="../../crates/kvdb", default-features=false } sp-core ="31.0.0" # Unreleased version of Synedrion with support for child key derivations. synedrion={ version="0.2.0-beta.0" } -entropy-tss={ version="0.3.0-rc.1", path="../../crates/threshold-signature-server", features=[ +entropy-tss={ version="0.3.0", path="../../crates/threshold-signature-server", features=[ "test_helpers", ] }