diff --git a/Cargo.lock b/Cargo.lock index 318a67ec8..2360fd812 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,7 +252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ff94ee630eb0bf55c59821a979f486bbaa976324786efcfc9d1f93bd254426" dependencies = [ "aead 0.4.3", - "arrayvec 0.7.2", + "arrayvec 0.7.4", ] [[package]] @@ -379,14 +379,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom 0.2.12", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -853,9 +854,9 @@ checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] name = "array-bytes" -version = "6.1.0" +version = "6.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" +checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "array-init" @@ -877,9 +878,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "ascii-canvas" @@ -1533,7 +1534,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "constant_time_eq 0.2.5", ] @@ -1544,22 +1545,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "constant_time_eq 0.1.5", ] [[package]] name = "blake3" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "cc", "cfg-if", - "constant_time_eq 0.1.5", - "digest 0.10.7", + "constant_time_eq 0.3.0", ] [[package]] @@ -2266,7 +2266,7 @@ dependencies = [ [[package]] name = "common" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#626c9598be949aa3dbdd72e8a40531f68b01d6c2" dependencies = [ "ark-ec", "ark-ff", @@ -2368,6 +2368,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "constcat" version = "0.3.1" @@ -2491,7 +2497,7 @@ version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bumpalo", "cranelift-bforest 0.91.1", "cranelift-codegen-meta 0.91.1", @@ -3265,6 +3271,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-syn-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "derive_builder" version = "0.11.2" @@ -3497,7 +3514,7 @@ dependencies = [ "ark-serialize", "ark-std", "ark-transcript", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "zeroize", ] @@ -3518,21 +3535,21 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "docify" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc4fd38aaa9fb98ac70794c82a00360d1e165a87fbf96a8a91f9dfc602aaee2" +checksum = "43a2f138ad521dc4a2ced1a4576148a6a610b4c5923933b062a263130a6802ce" dependencies = [ "docify_macros", ] [[package]] name = "docify_macros" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63fa215f3a0d40fb2a221b3aa90d8e1fbb8379785a990cb60d62ac71ebdc6460" +checksum = "1a081e51fb188742f5a7a1164ad752121abcb22874b21e2c3b0dd040c515fdad" dependencies = [ "common-path", - "derive-syn-parse", + "derive-syn-parse 0.2.0", "once_cell", "proc-macro2", "quote", @@ -4107,7 +4124,7 @@ version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60ca2514feb98918a0a31de7e1983c29f2267ebf61b2dc5d4294f91e5b866623" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bytes", "cargo_metadata 0.15.4", "chrono", @@ -4608,7 +4625,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ "Inflector", - "array-bytes 6.1.0", + "array-bytes 6.2.3", "chrono", "clap 4.4.12", "comfy-table", @@ -4747,7 +4764,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" dependencies = [ "aquamarine", - "array-bytes 6.1.0", + "array-bytes 6.2.3", "bitflags 1.3.2", "docify", "environmental", @@ -4789,7 +4806,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "Inflector", "cfg-expr", - "derive-syn-parse", + "derive-syn-parse 0.1.5", "expander", "frame-support-procedural-tools", "itertools", @@ -5415,7 +5432,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", ] [[package]] @@ -5424,7 +5441,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "allocator-api2", ] @@ -6433,7 +6450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" dependencies = [ "anyhow", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "async-lock", "async-trait", "beef", @@ -6887,7 +6904,7 @@ version = "0.43.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "asynchronous-codec", "bytes", "either", @@ -7447,7 +7464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "468155613a44cfd825f1fb0ffa532b018253920d404e6fca1e8d43155198a46d" dependencies = [ "const-random", - "derive-syn-parse", + "derive-syn-parse 0.1.5", "macro_magic_core_macros", "proc-macro2", "quote", @@ -7669,7 +7686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daa3eb39495d8e2e2947a1d862852c90cc6a4a8845f8b41c8829cb9fcc047f4a" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bitflags 1.3.2", "blake2 0.10.6", "c2-chacha", @@ -8225,7 +8242,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "itoa", ] @@ -8397,7 +8414,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "auto_impl", "bytes", "ethereum-types", @@ -9440,11 +9457,11 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bitvec 1.0.1", "byte-slice-cast", "bytes", @@ -9455,11 +9472,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -10150,10 +10167,12 @@ dependencies = [ "serde", "serde_json", "sgx-attestation", + "sp-api", "sp-core 21.0.0", "sp-io", "sp-runtime", "sp-std 8.0.0", + "wapod-types", ] [[package]] @@ -11951,13 +11970,14 @@ dependencies = [ [[package]] name = "ring" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#626c9598be949aa3dbdd72e8a40531f68b01d6c2" dependencies = [ "ark-ec", "ark-ff", "ark-poly", "ark-serialize", "ark-std", + "arrayvec 0.7.4", "blake2 0.10.6", "common", "fflonk", @@ -12280,7 +12300,7 @@ version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34a3bb58e85333f1ab191bf979104b586ebd77475bc6681882825f4532dfe87c" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "num-traits", "serde", ] @@ -12665,7 +12685,7 @@ name = "sc-chain-spec" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "docify", "log", "memmap2", @@ -12701,7 +12721,7 @@ name = "sc-cli" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "bip39", "chrono", "clap 4.4.12", @@ -12890,8 +12910,8 @@ name = "sc-consensus-grandpa" version = "0.10.0-dev" source = "git+https://github.com/Phala-Network/polkadot-sdk.git?branch=phala-patch-polkadot-v1.5.0#559a9126a2aa1de47356fea36aa246eb3e27e38a" dependencies = [ - "ahash 0.8.3", - "array-bytes 6.1.0", + "ahash 0.8.11", + "array-bytes 6.2.3", "async-trait", "dyn-clone", "finality-grandpa", @@ -13044,7 +13064,7 @@ name = "sc-keystore" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "parking_lot 0.12.1", "serde_json", "sp-application-crypto", @@ -13059,7 +13079,7 @@ version = "0.1.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ "array-bytes 4.2.0", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "blake2 0.10.6", "bytes", "futures", @@ -13087,7 +13107,7 @@ name = "sc-network" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "async-channel", "async-trait", "asynchronous-codec", @@ -13167,7 +13187,7 @@ name = "sc-network-gossip" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "futures", "futures-timer", "libp2p", @@ -13186,7 +13206,7 @@ name = "sc-network-light" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "async-channel", "futures", "libp2p-identity", @@ -13207,7 +13227,7 @@ name = "sc-network-sync" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "async-channel", "async-trait", "fork-tree", @@ -13243,7 +13263,7 @@ name = "sc-network-transactions" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "futures", "libp2p", "log", @@ -13262,7 +13282,7 @@ name = "sc-offchain" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "bytes", "fnv", "futures", @@ -13372,7 +13392,7 @@ name = "sc-rpc-spec-v2" version = "0.10.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "futures", "futures-util", "hex", @@ -13464,7 +13484,7 @@ name = "sc-service-test" version = "2.0.0" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "async-channel", "fdlimit", "futures", @@ -13795,9 +13815,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec 1.0.1", "cfg-if", @@ -13809,11 +13829,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -13855,7 +13875,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "cfg-if", "hashbrown 0.13.2", ] @@ -14107,9 +14127,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -14137,9 +14157,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -14858,9 +14878,9 @@ dependencies = [ [[package]] name = "sp-core" version = "21.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "bandersnatch_vrfs", "bip39", "bitflags 1.3.2", @@ -14907,7 +14927,7 @@ version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9ebb090ead698a6df04347c86a31ba91a387edb8a58534ec70c4f977d1e1e87" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "bitflags 1.3.2", "blake2 0.10.6", "bounded-collections", @@ -14988,7 +15008,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -15017,7 +15037,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "8.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "proc-macro2", "quote", @@ -15038,7 +15058,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "proc-macro2", "quote", @@ -15048,7 +15068,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "environmental", "parity-scale-codec", @@ -15071,7 +15091,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "environmental", "parity-scale-codec", @@ -15253,7 +15273,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -15290,7 +15310,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -15309,7 +15329,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "Inflector", "expander", @@ -15335,7 +15355,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "Inflector", "expander", @@ -15422,7 +15442,7 @@ dependencies = [ [[package]] name = "sp-std" version = "8.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" [[package]] name = "sp-std" @@ -15433,12 +15453,12 @@ checksum = "54c78c5a66682568cc7b153603c5d01a2cc8f5c221c7b1e921517a0eef18ae05" [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" [[package]] name = "sp-storage" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "impl-serde", "parity-scale-codec", @@ -15465,7 +15485,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "impl-serde", "parity-scale-codec", @@ -15490,7 +15510,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "parity-scale-codec", "sp-std 8.0.0", @@ -15515,7 +15535,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "parity-scale-codec", "tracing", @@ -15552,7 +15572,7 @@ name = "sp-trie" version = "22.0.0" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "hash-db", "hashbrown 0.13.2", "lazy_static", @@ -15603,7 +15623,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#8a98fec3e456033fdedf284e3613d5300f817085" +source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#a56caf11845f2118a34d9464b8e929315c12c8e3" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -15630,7 +15650,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#305d311d5c732fcc4629f3295768f1ed44ef434c" +source = "git+https://github.com/paritytech/polkadot-sdk#975e04bbb59b643362f918e8521f0cde5c27fbc8" dependencies = [ "impl-trait-for-tuples", "log", @@ -16195,7 +16215,7 @@ name = "substrate-test-client" version = "2.0.1" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "async-trait", "futures", "parity-scale-codec", @@ -16221,7 +16241,7 @@ name = "substrate-test-runtime" version = "2.0.0" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.3", "frame-executive", "frame-support", "frame-system", @@ -17888,6 +17908,17 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wapod-types" +version = "0.1.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e15d1f0f6fc295d001a38335e013f18d887c968de19d3ed5a4e7e3e5efbdc60" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -19490,6 +19521,26 @@ dependencies = [ "time 0.3.11", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/crates/phactory/src/snapshots/phactory__show_type_changes_that_affect_the_checkpoint.snap b/crates/phactory/src/snapshots/phactory__show_type_changes_that_affect_the_checkpoint.snap index cb169a356..2fbc24b86 100644 --- a/crates/phactory/src/snapshots/phactory__show_type_changes_that_affect_the_checkpoint.snap +++ b/crates/phactory/src/snapshots/phactory__show_type_changes_that_affect_the_checkpoint.snap @@ -1,6 +1,6 @@ --- source: crates/phactory/src/lib.rs -assertion_line: 365 +assertion_line: 382 expression: "type_info_stringify::>()" --- Option = enum { @@ -398,6 +398,9 @@ phala_types::messaging::GatekeeperEvent = enum { [2]_RepairV, [3]_PhalaLaunched, [4]_UnrespFix, + [5]SetStaticV { + enabled: bool, + } } phala_types::messaging::RandomNumberEvent = struct { block_number: u32, @@ -460,6 +463,11 @@ phala_types::messaging::WorkingReportEvent = enum { n_clusters: u32, n_contracts: u32, } + [2]HeartbeatV3 { + session_id: u32, + iterations: u64, + p_instant: u32, + } } BTreeMap = struct { : Vec<(sp_core::sr25519::Public, phactory::system::gk::WorkerInfo)>, @@ -550,4 +558,3 @@ phactory::Phactory = struct { system: Option>, netconfig: Option, } - diff --git a/crates/phactory/src/system/gk.rs b/crates/phactory/src/system/gk.rs index a40a2c5cf..c168f4261 100644 --- a/crates/phactory/src/system/gk.rs +++ b/crates/phactory/src/system/gk.rs @@ -433,6 +433,9 @@ where GatekeeperEvent::_RepairV | GatekeeperEvent::_PhalaLaunched | GatekeeperEvent::_UnrespFix => unreachable!(), + GatekeeperEvent::SetStaticV { .. } => { + // Handled by ComputingEconomics + } } } @@ -960,43 +963,100 @@ impl> ComputingEconomics { + let Some(worker_info) = self.workers.get_mut(&worker_pubkey) else { + error!( + target: "gk_computing", + "Unknown worker {} sent a {:?}", + hex::encode(worker_pubkey), + event + ); + return; + }; + if worker_info.state.working_state.is_none() { trace!( target: "gk_computing", - "[{}] heartbeat handling case5: Unresponsive, successful heartbeat.", + "[{}] Computing already stopped, ignore the heartbeat.", hex::encode(worker_info.state.pubkey) ); - worker_info - .tokenomic - .update_v_recover(block.now_ms, block.block_number); - fp!(0) - } else { + return; + }; + if worker_info.waiting_heartbeats.is_empty() { trace!( target: "gk_computing", - "[{}] heartbeat handling case2: Idle, successful heartbeat, report to pallet", + "[{}] Unexpected heartbeat response received, ignore it.", hex::encode(worker_info.state.pubkey) ); - let (payout, treasury) = worker_info.tokenomic.update_v_heartbeat( - &self.tokenomic_params, - self.eco_cache.sum_share, - block.now_ms, - block.block_number, - ); + return; + } + worker_info.waiting_heartbeats.clear(); + worker_info.heartbeat_flag = true; - // NOTE: keep the reporting order (vs the one while computing stop). - self.eco_cache.report.settle.push(SettleInfo { - pubkey: worker_pubkey, - v: worker_info.tokenomic.v.to_bits(), - payout: payout.to_bits(), - treasury: treasury.to_bits(), - }); - payout - }; - event_listener.emit_event(EconomicEvent::Heartbeat { payout }, worker_info); + let tokenomic = &mut worker_info.tokenomic; + tokenomic.update_p_instant(block.now_ms, iterations, false); + tokenomic.challenge_time_last = block.now_ms; + tokenomic.iteration_last = iterations; + + Self::update_v_and_payout( + &self.tokenomic_params, + block, + &mut self.eco_cache, + worker_info, + event_listener, + ); } } } + fn update_v_and_payout( + tokenomic_params: &tokenomic::Params, + block: &BlockInfo<'_>, + eco_cache: &mut EconomicCalcCache, + worker_info: &mut WorkerInfo, + event_listener: &mut impl EconomicEventListener, + ) { + let payout = if worker_info.unresponsive { + trace!( + target: "gk_computing", + "[{}] heartbeat handling case5: Unresponsive, successful heartbeat.", + hex::encode(worker_info.state.pubkey) + ); + worker_info + .tokenomic + .update_v_recover(block.now_ms, block.block_number); + fp!(0) + } else { + trace!( + target: "gk_computing", + "[{}] heartbeat handling case2: Idle, successful heartbeat, report to pallet", + hex::encode(worker_info.state.pubkey) + ); + let (payout, treasury) = worker_info.tokenomic.update_v_heartbeat( + tokenomic_params, + eco_cache.sum_share, + block.now_ms, + block.block_number, + ); + + eco_cache.report.settle.push(SettleInfo { + pubkey: worker_info.state.pubkey, + v: worker_info.tokenomic.v.to_bits(), + payout: payout.to_bits(), + treasury: treasury.to_bits(), + }); + payout + }; + event_listener.emit_event(EconomicEvent::Heartbeat { payout }, worker_info); + } + fn process_system_event( &mut self, origin: MessageOrigin, @@ -1121,6 +1181,11 @@ impl> ComputingEconomics unreachable!(), + GatekeeperEvent::SetStaticV { enabled } => { + if origin.is_pallet() { + self.tokenomic_params.set_static_v(enabled); + } + } } } @@ -1128,7 +1193,7 @@ impl> ComputingEconomics for Params { - fn from(params: TokenomicParameters) -> Self { + impl Params { + pub fn update(&mut self, params: TokenomicParameters) { let treasury_ration = FixedPoint::from_bits(params.treasury_ratio); let payout_ration = fp!(1) - treasury_ration; - Params { + *self = Params { rho: FixedPoint::from_bits(params.rho), slash_rate: FixedPoint::from_bits(params.slash_rate), budget_per_block: FixedPoint::from_bits(params.budget_per_block), @@ -1307,7 +1375,12 @@ mod tokenomic { treasury_ration, payout_ration, heartbeat_window: params.heartbeat_window, - } + static_v: self.static_v, + }; + } + + pub fn set_static_v(&mut self, enabled: bool) { + self.static_v = enabled; } } @@ -1322,6 +1395,7 @@ mod tokenomic { treasury_ration: fp!(0.2), payout_ration: fp!(0.8), heartbeat_window: 10, + static_v: false, } } @@ -1336,6 +1410,9 @@ mod tokenomic { /// case1: Idle, no event pub fn update_v_idle(&mut self, params: &Params) { + if params.static_v { + return; + } let cost_idle = params.cost_k * self.p_bench + params.cost_b; let perf_multiplier = if self.p_bench == fp!(0) { fp!(1) @@ -1361,7 +1438,7 @@ mod tokenomic { if sum_share == fp!(0) { return NO_UPDATE; } - if self.v_deductible == fp!(0) { + if !params.static_v && self.v_deductible == fp!(0) { return NO_UPDATE; } if block_number <= self.v_update_block { @@ -1377,10 +1454,11 @@ mod tokenomic { let actual_payout = budget * params.payout_ration; let actual_treasury = budget * params.treasury_ration; - let actual_v_deduct = self.v_deductible.clamp(fp!(0), actual_payout); - self.v -= actual_v_deduct; - - self.v_deductible = fp!(0); + if !params.static_v { + let actual_v_deduct = self.v_deductible.clamp(fp!(0), actual_payout); + self.v -= actual_v_deduct; + self.v_deductible = fp!(0); + } self.v_update_at = now_ms; self.v_update_block = block_number; @@ -1614,6 +1692,15 @@ pub mod tests { }; self.say(message) } + + fn heartbeat_v3(&mut self, session_id: u32, iterations: u64) { + let message = msg::WorkingReportEvent::HeartbeatV3 { + session_id, + iterations, + p_instant: 0, + }; + self.say(message) + } } fn with_block(block_number: chain::BlockNumber, call: impl FnOnce(&BlockInfo)) { @@ -1828,6 +1915,92 @@ pub mod tests { ); } + #[test] + fn static_v_works() { + let mut r = Roles::test_roles(); + let mut block_number = 1; + + r.gk.tokenomic_params.set_static_v(true); + + // Register worker + with_block(block_number, |block| { + let mut worker0 = r.for_worker(0); + worker0.pallet_say(msg::WorkerEvent::Registered(msg::WorkerInfo { + confidence_level: 2, + })); + r.gk.test_process_messages(block); + }); + + // Start computing & send heartbeat challenge + block_number += 1; + with_block(block_number, |block| { + let mut worker0 = r.for_worker(0); + worker0.pallet_say(msg::WorkerEvent::Started { + session_id: 1, + init_v: fp!(100).to_bits(), + init_p: 200, + }); + r.gk.test_process_messages(block); + }); + + block_number += 1; + + // Normal Idle state, no event + let v_snap = r.get_worker(0).tokenomic.v; + r.gk.egress.clear(); + with_block(block_number, |block| { + r.gk.test_process_messages(block); + }); + + assert!(!r.get_worker(0).unresponsive, "Worker should be online"); + assert_eq!( + r.gk.egress.drain_working_info_update_event().len(), + 0, + "Should not report any event" + ); + + assert!( + v_snap == r.get_worker(0).tokenomic.v, + "Worker V should not increase" + ); + + // Once again. + let v_snap = r.get_worker(0).tokenomic.v; + r.gk.egress.clear(); + with_block(block_number, |block| { + r.gk.test_process_messages(block); + }); + + assert!(!r.get_worker(0).unresponsive, "Worker should be online"); + assert_eq!( + r.gk.egress.drain_working_info_update_event().len(), + 0, + "Should not report any event" + ); + assert!( + v_snap == r.get_worker(0).tokenomic.v, + "Worker V should not increase" + ); + + block_number += 1; + with_block(block_number, |block| { + let mut worker0 = r.for_worker(0); + worker0.challenge(); + r.gk.test_process_messages(block); + }); + + block_number += 1; + with_block(block_number, |block| { + let mut worker0 = r.for_worker(0); + worker0.heartbeat(1, block_number - 1, 1000000000); + r.gk.test_process_messages(block); + }); + let egress = r.gk.egress.drain_working_info_update_event(); + assert_eq!(egress.len(), 1, "Should payout"); + let payout = FixedPoint::from_bits(egress[0].settle[0].payout); + assert_eq!(payout, fp!(285.4000288551775845473)); + } + #[test] fn gk_should_report_payout_for_normal_heartbeats_case2() { let mut r = Roles::test_roles(); @@ -2106,6 +2279,198 @@ pub mod tests { } } + #[test] + fn heartbeat_v3_can_flush_multiple_unrespond_heartbeat() { + let mut r = Roles::test_roles(); + + with_block(1, |block| { + let mut worker0 = r.for_worker(0); + worker0.pallet_say(msg::WorkerEvent::Registered(msg::WorkerInfo { + confidence_level: 2, + })); + r.gk.test_process_messages(block); + }); + + assert_eq!(r.gk.workers.len(), 1); + + assert!(r.get_worker(0).state.registered); + + with_block(2, |block| { + let mut worker0 = r.for_worker(0); + worker0.pallet_say(msg::WorkerEvent::Started { + session_id: 1, + init_v: 1, + init_p: 100, + }); + worker0.challenge(); + r.gk.test_process_messages(block); + }); + + for i in 3..6 { + with_block(i, |block| { + let mut worker0 = r.for_worker(0); + worker0.challenge(); + r.gk.test_process_messages(block); + }); + } + + // Force enter unresponsive + with_block(100, |block| { + r.gk.test_process_messages(block); + }); + + assert_eq!( + r.get_worker(0).waiting_heartbeats.len(), + 4, + "There should be 4 waiting HBs" + ); + + assert!( + r.get_worker(0).unresponsive, + "The worker should be unresponsive now" + ); + { + let offline = [r.workers[0]].to_vec(); + let expected_message = WorkingInfoUpdateEvent { + block_number: 100, + timestamp_ms: block_ts(100), + offline, + recovered_to_online: Vec::new(), + settle: Vec::new(), + }; + let messages = r.gk.egress.drain_working_info_update_event(); + assert_eq!(messages.len(), 1, "Should report recover event"); + assert_eq!(messages[0], expected_message); + } + + with_block(101, |block| { + let mut worker = r.for_worker(0); + // Response the first challenge. + worker.heartbeat_v3(1, 10000000); + r.gk.test_process_messages(block); + }); + assert_eq!( + r.get_worker(0).waiting_heartbeats.len(), + 0, + "HBs should be cleared" + ); + + assert!( + !r.get_worker(0).unresponsive, + "The worker should be computing idle now" + ); + { + let recovered_to_online = [r.workers[0]].to_vec(); + let expected_message = WorkingInfoUpdateEvent { + block_number: 101, + timestamp_ms: block_ts(101), + offline: Vec::new(), + recovered_to_online, + settle: Vec::new(), + }; + let messages = r.gk.egress.drain_working_info_update_event(); + assert_eq!(messages.len(), 1, "Should report recover event"); + assert_eq!(messages[0], expected_message); + } + + with_block(102, |block| { + let mut worker = r.for_worker(0); + // Response the second challenge. + worker.heartbeat_v3(2, 10000000); + r.gk.test_process_messages(block); + }); + + assert!( + !r.get_worker(0).unresponsive, + "The worker should be computing idle now" + ); + { + let messages = r.gk.egress.drain_working_info_update_event(); + assert_eq!(messages.len(), 0, "Should have no report event"); + } + } + + #[test] + fn heartbeat_v3_should_be_paid_out() { + let mut r = Roles::test_roles(); + + with_block(1, |block| { + let mut worker0 = r.for_worker(0); + worker0.pallet_say(msg::WorkerEvent::Registered(msg::WorkerInfo { + confidence_level: 2, + })); + r.gk.test_process_messages(block); + }); + + assert_eq!(r.gk.workers.len(), 1); + + assert!(r.get_worker(0).state.registered); + + with_block(2, |block| { + let mut worker0 = r.for_worker(0); + worker0.pallet_say(msg::WorkerEvent::Started { + session_id: 1, + init_v: fp!(100).to_bits(), + init_p: 2500, + }); + worker0.challenge(); + r.gk.test_process_messages(block); + }); + + for i in 3..6 { + with_block(i, |block| { + let mut worker0 = r.for_worker(0); + worker0.challenge(); + r.gk.test_process_messages(block); + }); + } + assert_eq!( + r.get_worker(0).waiting_heartbeats.len(), + 4, + "There should have 4 HBs" + ); + assert_eq!(r.get_worker(0).tokenomic.v, fp!(100.00055963912991258423)); + + with_block(6, |block| { + let mut worker = r.for_worker(0); + // Response the first challenge. + worker.heartbeat_v3(1, 24000); + r.gk.test_process_messages(block); + }); + assert_eq!( + r.get_worker(0).waiting_heartbeats.len(), + 0, + "HBs should be cleared" + ); + + assert!( + !r.get_worker(0).unresponsive, + "The worker should be computing idle now" + ); + { + let expected_message = WorkingInfoUpdateEvent { + block_number: 6, + timestamp_ms: block_ts(6), + offline: Vec::new(), + recovered_to_online: Vec::new(), + settle: vec![super::SettleInfo { + pubkey: r.workers[0], + v: fp!(100).to_bits(), + payout: fp!(383.9765417372721003196).to_bits(), + treasury: fp!(95.9941354343180250734).to_bits(), + }], + }; + let messages = r.gk.egress.drain_working_info_update_event(); + assert_eq!(messages.len(), 1, "Should report recover event"); + assert_eq!(messages[0], expected_message); + assert_eq!( + r.get_worker(0).tokenomic.p_instant, + fp!(2999.9999999999999999729) + ); + assert_eq!(r.get_worker(0).tokenomic.v, fp!(100)); + } + } + #[test] fn check_tokenomic_numerics() { let mut r = Roles::test_roles(); diff --git a/crates/phala-types/src/lib.rs b/crates/phala-types/src/lib.rs index 8491c7f9e..0bd43eb5e 100644 --- a/crates/phala-types/src/lib.rs +++ b/crates/phala-types/src/lib.rs @@ -143,6 +143,14 @@ pub mod messaging { /// Number of current deployed contracts. n_contracts: u32, }, + HeartbeatV3 { + /// The computing session id. + session_id: u32, + /// Benchmark iterations since working_start_time. + iterations: u64, + /// Number of current deployed clusters. + p_instant: u32, + }, } bind_topic!(WorkingInfoUpdateEvent, b"^phala/mining/update"); @@ -384,6 +392,7 @@ pub mod messaging { /// Fix the payout duration problem in unresponsive state. /// Dropped in Phala. The index is reserved here for Khala+pruntime-v0 compatibility. _UnrespFix, + SetStaticV { enabled: bool }, } impl GatekeeperEvent { diff --git a/crates/phala-types/src/snapshots/phala_types__tests__dump_type_info.snap b/crates/phala-types/src/snapshots/phala_types__tests__dump_type_info.snap index 75ba3e903..bd5042482 100644 --- a/crates/phala-types/src/snapshots/phala_types__tests__dump_type_info.snap +++ b/crates/phala-types/src/snapshots/phala_types__tests__dump_type_info.snap @@ -1,6 +1,6 @@ --- source: crates/phala-types/src/lib.rs -assertion_line: 929 +assertion_line: 935 expression: "type_info_stringify::()" --- phala_types::messaging::CommandPayload = enum { @@ -57,6 +57,11 @@ phala_types::messaging::WorkingReportEvent = enum { n_clusters: u32, n_contracts: u32, } + [2]HeartbeatV3 { + session_id: u32, + iterations: u64, + p_instant: u32, + } } phala_types::messaging::WorkingInfoUpdateEvent = struct { block_number: u32, @@ -134,6 +139,9 @@ phala_types::messaging::GatekeeperEvent = enum { [2]_RepairV, [3]_PhalaLaunched, [4]_UnrespFix, + [5]SetStaticV { + enabled: bool, + } } phala_types::messaging::RandomNumberEvent = struct { block_number: u32, @@ -318,4 +326,3 @@ phala_types::tests::TestData = struct { payout_reason: phala_types::PayoutReason, slash_info: phala_types::StashInfo, } - diff --git a/pallets/phala/Cargo.toml b/pallets/phala/Cargo.toml index 9609a023a..a9aeeff09 100644 --- a/pallets/phala/Cargo.toml +++ b/pallets/phala/Cargo.toml @@ -30,6 +30,7 @@ sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = sp-std = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0", default-features = false } sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0", default-features = false } sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0", default-features = false } +sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0", default-features = false } log = { version = "0.4.14", default-features = false } pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0", default-features = false } @@ -46,6 +47,8 @@ fixed-sqrt = { version = "0.2", default-features = false } sgx-attestation = { path = "../../crates/sgx-attestation", default-features = false, features = ["verify"] } +wapod-types = { version = "0.1.0-dev.1", default-features = false } + [dev-dependencies] frame-support-test = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0" } assert_matches = "1.4.0" @@ -68,6 +71,7 @@ std = [ "sp-io/std", "sp-std/std", "sp-core/std", + "sp-api/std", "frame-support/std", "frame-system/std", "pallet-balances/std", @@ -81,6 +85,7 @@ std = [ "serde/derive", "serde/alloc", "sgx-attestation/std", + "wapod-types/std", ] runtime-benchmarks = [ ] diff --git a/pallets/phala/src/compute/computation.rs b/pallets/phala/src/compute/computation.rs index 8be7443fe..72acd4e4f 100644 --- a/pallets/phala/src/compute/computation.rs +++ b/pallets/phala/src/compute/computation.rs @@ -42,7 +42,7 @@ pub mod pallet { use fixed_sqrt::FixedSqrt; #[cfg(feature = "std")] - use serde::{Serialize, Deserialize}; + use serde::{Deserialize, Serialize}; const DEFAULT_EXPECTED_HEARTBEAT_COUNT: u32 = 20; const COMPUTING_PALLETID: PalletId = PalletId(*b"phala/pp"); @@ -436,6 +436,15 @@ pub mod pallet { nonce: u64, budget: u128, }, + /// A signal is sent to enable/disable static V in GK. + StaticVChanged { + enabled: bool, + }, + /// A heartbeat challenge is sent to workers. + HeartbeatChallenge { + seed: U256, + online_target: U256, + }, } #[pallet::error] @@ -531,6 +540,10 @@ pub mod pallet { seed: U256::zero(), online_target: U256::MAX, })); + Self::deposit_event(Event::::HeartbeatChallenge { + seed: U256::zero(), + online_target: U256::MAX, + }); Ok(()) } @@ -632,6 +645,18 @@ pub mod pallet { ContractAccount::::put(account_id); Ok(()) } + + /// Enable static V. + /// + /// When enabled, the V of a worker doesn't increase on IDLE. + #[pallet::call_index(9)] + #[pallet::weight(Weight::from_parts(1, 0))] + pub fn set_static_v(origin: OriginFor, enabled: bool) -> DispatchResult { + T::GovernanceOrigin::ensure_origin(origin)?; + Self::push_message(GatekeeperEvent::SetStaticV { enabled }); + Self::deposit_event(Event::::StaticVChanged { enabled }); + Ok(()) + } } #[pallet::hooks] @@ -673,6 +698,10 @@ pub mod pallet { online_target, }; Self::push_message(SystemEvent::HeartbeatChallenge(seed_info)); + Self::deposit_event(Event::::HeartbeatChallenge { + seed, + online_target, + }); } pub fn on_working_message_received( @@ -718,6 +747,23 @@ pub mod pallet { }); Sessions::::insert(&session, session_info); } + WorkingReportEvent::HeartbeatV3 { + p_instant, + iterations, + .. + } => { + let session = Self::ensure_worker_bound(&worker)?; + let mut session_info = + Self::sessions(&session).expect("Bound worker; qed."); + session_info.benchmark.p_instant = p_instant; + session_info.benchmark.challenge_time_last = Self::now_sec(); + session_info.benchmark.iterations = iterations; + Sessions::::insert(&session, session_info); + Self::deposit_event(Event::::BenchmarkUpdated { + session: session.clone(), + p_instant, + }); + } }; } Ok(()) diff --git a/pallets/phala/src/compute/stake_pool_v2.rs b/pallets/phala/src/compute/stake_pool_v2.rs index f0e4fbbae..32c580c51 100644 --- a/pallets/phala/src/compute/stake_pool_v2.rs +++ b/pallets/phala/src/compute/stake_pool_v2.rs @@ -422,8 +422,7 @@ pub mod pallet { let session: T::AccountId = pool_sub_account(pid, &pubkey); // bind worker with worker - computation::pallet::Pallet::::bind(session.clone(), pubkey) - .or(Err(Error::::FailedToBindSessionAndWorker))?; + computation::pallet::Pallet::::bind(session.clone(), pubkey)?; // Save the preimage of the sub-account, // the lifecycle of the preimage should be the same with the worker record, diff --git a/pallets/phala/src/lib.rs b/pallets/phala/src/lib.rs index e3319dc3e..b8bc6475b 100644 --- a/pallets/phala/src/lib.rs +++ b/pallets/phala/src/lib.rs @@ -18,6 +18,8 @@ pub mod phat; pub mod puppets; pub mod registry; pub mod stake_pool; +pub mod phat_tokenomic; +pub mod wapod_workers; use compute::{base_pool, computation, pool_proxy, stake_pool_v2, vault, wrapped_balances}; @@ -48,7 +50,7 @@ pub use phat as pallet_phat; pub use phat_tokenomic as pallet_phat_tokenomic; pub use registry as pallet_registry; pub use stake_pool as pallet_stake_pool; -pub mod phat_tokenomic; +pub use wapod_workers as pallet_wapod_workers; #[cfg(feature = "native")] use sp_core::hashing; diff --git a/pallets/phala/src/mock.rs b/pallets/phala/src/mock.rs index 1df247822..6b3983f6e 100644 --- a/pallets/phala/src/mock.rs +++ b/pallets/phala/src/mock.rs @@ -3,7 +3,7 @@ use crate::{ utils::attestation_legacy::{ Attestation, AttestationValidator, Error as AttestationError, IasFields, }, - vault, wrapped_balances, + vault, wapod_workers, wrapped_balances, }; use frame_support::{ @@ -20,12 +20,29 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; +use wapod_types::crypto::CryptoProvider; pub(crate) type Balance = u128; type Block = frame_system::mocking::MockBlock; pub(crate) type BlockNumber = u64; +pub struct MockCrypto; +impl CryptoProvider for MockCrypto { + fn sr25519_verify(_public_key: &[u8], _message: &[u8], signature: &[u8]) -> bool { + if signature.starts_with(b"valid") { + return true; + } + false + } + fn keccak_256(data: &[u8]) -> [u8; 32] { + sp_io::hashing::keccak_256(data) + } + fn blake2b_256(data: &[u8]) -> [u8; 32] { + sp_io::hashing::blake2_256(data) + } +} + // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( pub struct Test { @@ -46,6 +63,7 @@ frame_support::construct_runtime!( PhalaWrappedBalances: wrapped_balances::{Pallet, Event}, PhalaBasePool: base_pool::{Pallet, Event}, PhalaStakePool: stake_pool::{Event}, + PhalaWapodWorkers: wapod_workers::{Pallet, Call, Storage, Event}, Preimage: pallet_preimage::{Event}, } ); @@ -394,6 +412,11 @@ impl stake_pool::Config for Test { type Currency = Balances; } +impl wapod_workers::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Crypto = MockCrypto; +} + pub struct MockValidator; impl AttestationValidator for MockValidator { fn validate( diff --git a/pallets/phala/src/registry.rs b/pallets/phala/src/registry.rs index 3ee0bcc32..84b9961e8 100644 --- a/pallets/phala/src/registry.rs +++ b/pallets/phala/src/registry.rs @@ -930,6 +930,38 @@ pub mod pallet { Ok(()) } + pub fn worker_exsists(worker_pubkey: &WorkerPublicKey) -> bool { + Workers::::contains_key(worker_pubkey) + } + + pub fn update_worker_init_score(worker_pubkey: &WorkerPublicKey, score: u64) { + let now = T::UnixTime::now().as_millis().saturated_into::(); + + const MAX_SCORE: u32 = 6000; + let score = MAX_SCORE.min(score as u32); + + Workers::::mutate(worker_pubkey, |val| { + if let Some(val) = val { + val.initial_score = Some(score); + val.last_updated = now / 1000; + } + }); + Self::push_message(SystemEvent::new_worker_event( + *worker_pubkey, + WorkerEvent::BenchScore(score), + )); + Self::deposit_event(Event::::InitialScoreSet { + pubkey: *worker_pubkey, + init_score: score, + }); + } + + pub fn worker_init_score(worker_pubkey: &WorkerPublicKey) -> Option { + Workers::::get(worker_pubkey)? + .initial_score + .map(|s| s as u64) + } + pub fn on_message_received(message: DecodedMessage) -> DispatchResult { let worker_pubkey = match &message.sender { MessageOrigin::Worker(key) => key, @@ -947,26 +979,9 @@ pub mod pallet { return Err(Error::::InvalidBenchReport.into()); } - const MAX_SCORE: u32 = 6000; let score = iterations / ((now - start_time) / 1000); let score = score * 6; // iterations per 6s - let score = MAX_SCORE.min(score as u32); - - Workers::::mutate(worker_pubkey, |val| { - if let Some(val) = val { - val.initial_score = Some(score); - val.last_updated = now / 1000; - } - }); - - Self::push_message(SystemEvent::new_worker_event( - *worker_pubkey, - WorkerEvent::BenchScore(score), - )); - Self::deposit_event(Event::::InitialScoreSet { - pubkey: *worker_pubkey, - init_score: score, - }); + Self::update_worker_init_score(worker_pubkey, score); } RegistryEvent::MasterPubkey { master_pubkey } => { let gatekeepers = Gatekeeper::::get(); diff --git a/pallets/phala/src/test.rs b/pallets/phala/src/test.rs index e3af298ff..ea00cca98 100644 --- a/pallets/phala/src/test.rs +++ b/pallets/phala/src/test.rs @@ -889,7 +889,7 @@ fn test_add_worker() { assert_ok!(PhalaStakePoolv2::create(RuntimeOrigin::signed(1))); assert_noop!( PhalaStakePoolv2::add_worker(RuntimeOrigin::signed(1), 1, worker1), - stake_pool_v2::Error::::FailedToBindSessionAndWorker + computation::Error::::DuplicateBoundWorker ); }); } diff --git a/pallets/phala/src/wapod_workers.rs b/pallets/phala/src/wapod_workers.rs new file mode 100644 index 000000000..302d96d60 --- /dev/null +++ b/pallets/phala/src/wapod_workers.rs @@ -0,0 +1,1709 @@ +//! The pallet managing the wapod workers. +//! +//! This pallet is responsible for managing worker descriptions, sessions, and tickets. +//! It also handles worker lists, benchmarking, and settlement of tickets. + +pub use self::pallet::*; + +#[frame_support::pallet] +pub mod pallet { + // MARK: - Imports + use crate::{mq, registry, PhalaConfig}; + use alloc::boxed::Box; + use alloc::collections::BTreeMap; + use alloc::vec::Vec; + use frame_support::{ + dispatch::DispatchResult, + ensure, + pallet_prelude::*, + traits::{Currency, ExistenceRequirement::*, StorageVersion}, + }; + use frame_system::pallet_prelude::*; + use phala_types::{ + messaging::{DecodedMessage, MessageOrigin, SystemEvent, WorkerEvent, WorkingReportEvent}, + WorkerPublicKey, + }; + use scale_info::TypeInfo; + use sp_runtime::{traits::Zero, SaturatedConversion, Saturating}; + use wapod_types::{ + bench_app::{BenchScore, SignedMessage, SigningMessage}, + crypto::{verify::Verifiable, CryptoProvider}, + metrics::{ClaimMap, MetricsToken, SignedAppsMetrics, VersionedAppsMetrics}, + primitives::{BoundedString, BoundedVec}, + session::{SessionUpdate, SignedSessionUpdate}, + ticket::{Balance, Prices, SignedWorkerDescription, WorkerDescription}, + }; + + // MARK: - Types + type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + pub type TicketId = u64; + pub type ListId = u64; + /// Address type used for apps and workers. + pub type Address = [u8; 32]; + + #[derive(Encode, Decode, TypeInfo, Debug, Clone, Copy, PartialEq, Eq, MaxEncodedLen)] + pub struct Fraction { + pub numerator: u32, + pub denominator: u32, + } + + impl Fraction { + /// Performs a saturating multiplication of the fraction with a u64 value. + fn saturating_mul_u64(&self, rhs: u64) -> u64 { + let rhs = rhs as u128; + let numerator = self.numerator as u128; + let denominator = self.denominator as u128; + let result = (numerator * rhs) / u128::max(denominator, 1); + result.saturated_into() + } + } + + /// Information about a benchmark app. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen)] + pub struct BenchAppInfo { + /// The ticket id used to deploy the benchmark app. + ticket: TicketId, + /// The ratio of mapping gas to score. + score_ratio: Fraction, + } + + /// Represents a worker's session information. When a worker restarts, it creates a new session. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen)] + pub struct WorkerSession { + /// The session id of the worker. + pub session_id: [u8; 32], + /// The nonce that last used in metrics report. + pub last_nonce: [u8; 32], + /// The last metrics sequence number. + pub last_metrics_sn: u64, + /// The account id that receives the ticket reward. + pub recipient: AccountId, + } + + /// Cryptographic provider for signature verification. + pub struct SpCrypto; + impl CryptoProvider for SpCrypto { + fn sr25519_verify(public_key: &[u8], message: &[u8], signature: &[u8]) -> bool { + let Ok(public_key) = public_key.try_into() else { + return false; + }; + let Ok(signature) = signature.try_into() else { + return false; + }; + sp_io::crypto::sr25519_verify(&signature, message, &public_key) + } + fn keccak_256(data: &[u8]) -> [u8; 32] { + sp_io::hashing::keccak_256(data) + } + fn blake2b_256(data: &[u8]) -> [u8; 32] { + sp_io::hashing::blake2_256(data) + } + } + + /// Defines the set of workers that a ticket can be deployed to. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen)] + pub enum WorkerSet { + /// The ticket can be deployed to any worker. + Any, + /// The ticket can be deployed to workers in the specified list. + WorkerList(ListId), + } + + /// Information about a ticket. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen)] + pub struct TicketInfo { + /// If true, the ticket is a system (benchmark) ticket. + pub system: bool, + /// The account id of the ticket owner. + /// None if the ticket is a system ticket. + pub owner: Option, + /// The set of workers that the ticket can be deployed to. + pub workers: WorkerSet, + /// The address of the target app. + pub address: Address, + /// The resource prices of the ticket. + pub prices: Prices, + /// The IPFS CID of the target app's manifest. + pub manifest_cid: BoundedString<128>, + } + + /// Information about a worker list. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen)] + pub struct WorkerListInfo { + /// The account id of the list owner. + pub owner: AccountId, + /// The resource prices of the workers in the list. + pub prices: Prices, + /// The description of the list. + pub description: BoundedString<1024>, + } + + /// Settlement information for a ticket and worker pair. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen, Default)] + pub struct SettlementInfo { + /// The current session id of the App. + pub current_session_id: [u8; 32], + /// The total amount paid in the current App session. + /// If the ticket is created after the worker's session, this value will be initialized + /// to the cost calculated from the first metrics report but without actual payment. + pub current_session_paid: Balance, + /// The total amount paid to the worker. + pub total_paid: Balance, + } + + /// Represents the computation state of a worker. V2 compatible. + #[derive(Encode, Decode, TypeInfo, Debug, Clone, PartialEq, Eq, MaxEncodedLen)] + pub struct ComputationState { + /// The id of the current computation session. + session_id: u32, + /// Whether the worker is unresponsive. + unresponsive: bool, + /// The number of iterations in the last heartbeat. + last_iterations: u64, + /// The time of the last heartbeat. + last_update_time: i64, + } + + // MARK: - Pallet config + #[pallet::config] + pub trait Config: frame_system::Config + PhalaConfig { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type Crypto: CryptoProvider; + } + + // MARK: - Pallet storage + + const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + /// The next ticket ID to use. + #[pallet::storage] + pub type NextTicketId = StorageValue<_, TicketId, ValueQuery>; + + /// Active tickets. + /// Each ticket holds payment information for a target app address. + /// Multiple tickets can pay for the same app at the same time. + #[pallet::storage] + pub type Tickets = StorageMap<_, Twox64Concat, TicketId, TicketInfo>; + + /// Settlement information for each (ticket, worker) pair. + #[pallet::storage] + pub type TicketSettlementInfo = StorageDoubleMap< + _, + Twox64Concat, + TicketId, + Twox64Concat, + WorkerPublicKey, + SettlementInfo>, + ValueQuery, + >; + + /// The next worker list ID to use. + #[pallet::storage] + pub type NextWorkerListId = StorageValue<_, ListId, ValueQuery>; + + /// Worker lists. + /// + /// A worker list is a collection of workers that with the same price. + #[pallet::storage] + pub type WorkerLists = + StorageMap<_, Twox64Concat, ListId, WorkerListInfo>; + + /// Workers associated to worker list. + #[pallet::storage] + pub type WorkerListWorkers = + StorageDoubleMap<_, Twox64Concat, ListId, Twox64Concat, WorkerPublicKey, ()>; + + /// Information about workers. + #[pallet::storage] + pub type WorkerDescriptions = + StorageMap<_, Twox64Concat, WorkerPublicKey, WorkerDescription>; + + /// V3 information about workers. + #[pallet::storage] + pub type WorkerSessions = + StorageMap<_, Twox64Concat, WorkerPublicKey, WorkerSession>; + + /// Working state of wapod workers. V2 compatible. + #[pallet::storage] + pub type ComputationWorkers = StorageMap<_, Twox64Concat, WorkerPublicKey, ComputationState>; + + /// Allowed app addresses that used to benchmark workers. + #[pallet::storage] + pub type BenchmarkApps = StorageMap<_, Twox64Concat, Address, BenchAppInfo>; + + /// Current recommended app address used to benchmark workers. + #[pallet::storage] + pub type RecommendedBenchmarkApp = StorageValue<_, Address>; + + // MARK: - Pallet error + + /// Errors that can occur in this pallet. + #[pallet::error] + pub enum Error { + NotAllowed, + WorkerNotFound, + WorkerListNotFound, + TicketNotFound, + SignatureVerificationFailed, + InvalidWorkerPubkey, + InvalidBenchApp, + OutdatedMessage, + InvalidMessageSender, + PriceMismatch, + SessionMismatch, + InvalidRewardReceiver, + InvalidParameter, + } + + // MARK: - Pallet events + + /// Events emitted by this pallet. + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + /// A new ticket was created. + TicketCreated { id: TicketId }, + /// A ticket was closed. + TicketClosed { id: TicketId }, + /// A new worker list was created. + WorkerListCreated { id: ListId }, + /// Some workers were added to a list. + WorkersAddedToList { + list_id: ListId, + workers: Vec, + }, + /// A worker was removed from a list. + WorkerRemovedFromList { + list_id: ListId, + worker: WorkerPublicKey, + }, + /// A worker's description was set. + WorkerDescriptionSet { worker: WorkerPublicKey }, + /// A benchmark app was added. + BenchmarkAppAdded { address: Address }, + /// The recommended benchmark app was changed. + RecommendedBenchmarkAppChanged { address: Address }, + /// A ticket was settled. + Settled { + ticket_id: TicketId, + worker: WorkerPublicKey, + payout: BalanceOf, + recipient: T::AccountId, + session_cost: BalanceOf, + }, + /// A settlement failed. + SettleFailed { + ticket_id: TicketId, + worker: WorkerPublicKey, + payout: BalanceOf, + session_cost: BalanceOf, + }, + /// A worker's session was updated. + WorkerSessionUpdated { + worker: WorkerPublicKey, + session: [u8; 32], + }, + /// A simulated heartbeat was emitted (V3). + HeartbeatV3 { + worker: WorkerPublicKey, + /// The computation session id. + session_id: u32, + /// The v2 iterations converted from gas consumed. + iterations: u64, + /// The p_instant is estimated by the pallet, might not be the same as the GK state. + p_instant: u32, + }, + } + + fn ticket_account_address(ticket_id: TicketId) -> T + where + T: Encode + Decode, + { + wapod_types::ticket::ticket_account_address(ticket_id, crate::hashing::blake2_256) + } + + // MARK: - Pallet calls + #[pallet::call] + impl Pallet + where + T: mq::Config, + T: registry::Config, + BalanceOf: From, + { + // MARK: - Worker management + + /// Sets the description and price for a worker. + /// + /// This function allows setting the description for a worker, which can only be done once. + /// The description must be signed by the worker via its RPC. + /// + /// # Parameters + /// - `signed_description`: A signed description of the worker. + #[pallet::call_index(0)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn worker_description_set( + origin: OriginFor, + signed_description: SignedWorkerDescription, + ) -> DispatchResult { + let _ = ensure_signed(origin)?; + let worker_pubkey = WorkerPublicKey(signed_description.worker_pubkey); + // Worker price can only be set once + ensure!( + !WorkerDescriptions::::contains_key(worker_pubkey), + Error::::NotAllowed + ); + ensure!( + registry::Pallet::::worker_exsists(&worker_pubkey), + Error::::InvalidWorkerPubkey + ); + ensure!( + signed_description.verify::(), + Error::::SignatureVerificationFailed + ); + WorkerDescriptions::::insert(worker_pubkey, signed_description.worker_description); + Self::deposit_event(Event::WorkerDescriptionSet { + worker: worker_pubkey, + }); + Ok(()) + } + + /// Updates the session for a worker. + /// + /// This function should be called when a worker restarts or resets to update its session with a new session ID. + /// The new session must be initiated with the last nonce on-chain to ensure the session is not lanched before the last metrics report. + /// + /// # Parameters + /// - `update`: A signed session update containing the new session information. + #[pallet::call_index(1)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn worker_session_update( + origin: OriginFor, + update: SignedSessionUpdate, + ) -> DispatchResult { + let _ = ensure_signed(origin)?; + ensure!( + update.verify::(), + Error::::SignatureVerificationFailed + ); + let worker_pubkey = WorkerPublicKey(update.public_key); + ensure!( + registry::Pallet::::worker_exsists(&worker_pubkey), + Error::::InvalidWorkerPubkey + ); + let update = update.update; + if let Some(session) = WorkerSessions::::get(worker_pubkey) { + let computed_session = + SessionUpdate::calc_session_id::(update.nonce, &session.last_nonce); + ensure!( + computed_session == update.session, + Error::::OutdatedMessage + ); + }; + let Ok(recipient) = Decode::decode(&mut &update.recipient[..]) else { + return Err(Error::::InvalidRewardReceiver.into()); + }; + WorkerSessions::::insert( + worker_pubkey, + WorkerSession { + session_id: update.session, + last_nonce: update.nonce, + last_metrics_sn: 0, + recipient, + }, + ); + Self::deposit_event(Event::WorkerSessionUpdated { + worker: worker_pubkey, + session: update.session, + }); + return Ok(()); + } + + /// Creates a new worker list. + /// + /// This function creates a new worker list with specified description, prices, and initial workers. + /// + /// # Parameters + /// - `description`: A string describing the worker list. + /// - `prices`: The resource prices for each worker in the list. + /// - `init_workers`: An optional list of initial workers to add to the list. + #[pallet::call_index(2)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn worker_list_create( + origin: OriginFor, + description: BoundedString<1024>, + prices: Prices, + init_workers: BoundedVec, + ) -> DispatchResult { + let owner = ensure_signed(origin.clone())?; + let id = Self::add_worker_list(WorkerListInfo { + owner, + prices, + description, + }); + if !init_workers.is_empty() { + Self::worker_list_add_workers(origin, id, init_workers)?; + } + Ok(()) + } + + /// Adds workers to an existing worker list. + /// + /// # Parameters + /// - `list_id`: The ID of the worker list to add workers to. + /// - `workers`: A vector of worker public keys to add to the list. + #[pallet::call_index(3)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn worker_list_add_workers( + origin: OriginFor, + list_id: ListId, + workers: BoundedVec, + ) -> DispatchResult { + let owner = ensure_signed(origin)?; + let list_info = WorkerLists::::get(list_id).ok_or(Error::::WorkerListNotFound)?; + ensure!(owner == list_info.owner, Error::::NotAllowed); + for worker in workers.iter() { + let Some(worker_info) = WorkerDescriptions::::get(worker) else { + return Err(Error::::WorkerNotFound.into()); + }; + ensure!( + worker_info.prices == Default::default() + || worker_info.prices == list_info.prices, + Error::::PriceMismatch + ); + WorkerListWorkers::::insert(list_id, worker, ()); + } + Self::deposit_event(Event::WorkersAddedToList { + list_id, + workers: workers.into(), + }); + Ok(()) + } + + /// Removes a worker from a worker list. + #[pallet::call_index(4)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn worker_list_remove_worker( + origin: OriginFor, + list_id: ListId, + worker: WorkerPublicKey, + ) -> DispatchResult { + let owner = ensure_signed(origin)?; + let list_info = WorkerLists::::get(list_id).ok_or(Error::::WorkerListNotFound)?; + ensure!(owner == list_info.owner, Error::::NotAllowed); + WorkerListWorkers::::remove(list_id, worker); + Self::deposit_event(Event::WorkerRemovedFromList { list_id, worker }); + Ok(()) + } + + // MARK: - Tickets + + /// Creates a new ticket for an application. + /// + /// The address must match the address of the target application. Otherwise, this call will not fail but the ticket will not be settled, + /// and the worker will likely reject the ticket. + /// + /// # Parameters + /// - `deposit`: The amount to be deposited into the ticket account. + /// - `address`: The address of the target application. + /// - `manifest_cid`: The IPFS CID of the application manifest. + /// - `worker_list`: The ID of the worker list allowed to settle this ticket. + /// - `prices`: + /// The resource prices for the ticket. This will be merged with the prices of the worker list while settling the ticket. + /// Leave None for the field to use the prices of the worker list. + #[pallet::call_index(5)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn ticket_create( + origin: OriginFor, + deposit: BalanceOf, + address: Address, + manifest_cid: BoundedString<128>, + worker_list: ListId, + prices: Box, + ) -> DispatchResult { + let owner = ensure_signed(origin)?; + let Some(list_info) = WorkerLists::::get(worker_list) else { + return Err(Error::::WorkerListNotFound.into()); + }; + let id = Self::add_ticket(TicketInfo { + system: false, + owner: Some(owner.clone()), + workers: WorkerSet::WorkerList(worker_list), + address, + manifest_cid, + prices: prices.merge(&list_info.prices), + }); + let ticket_account = ticket_account_address(id); + ::Currency::transfer(&owner, &ticket_account, deposit, KeepAlive)?; + Ok(()) + } + + /// Closes an ticket. + /// + /// # Parameters + /// - `ticket_id`: The ID of the ticket to be closed. + #[pallet::call_index(6)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn ticket_close(origin: OriginFor, ticket_id: TicketId) -> DispatchResult { + let owner = ensure_signed(origin)?; + let info = Tickets::::get(ticket_id).ok_or(Error::::TicketNotFound)?; + ensure!(Some(&owner) == info.owner.as_ref(), Error::::NotAllowed); + + // Refund the deposit + let ticket_account = ticket_account_address(ticket_id); + let deposit = ::Currency::free_balance(&ticket_account); + if !deposit.is_zero() { + ::Currency::transfer( + &ticket_account, + &owner, + deposit, + AllowDeath, + )?; + } + Tickets::::remove(ticket_id); + // TODO: remove the remaining entries + _ = TicketSettlementInfo::::clear_prefix(ticket_id, 64, None); + Self::deposit_event(Event::TicketClosed { id: ticket_id }); + Ok(()) + } + + /// Submits application metrics for settlement. + /// + /// This function allows workers to submit signed metrics for applications, which are used to settle tickets. + /// + /// # Parameters + /// - `message`: A signed message containing the application metrics. + #[pallet::call_index(7)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn ticket_settle( + origin: OriginFor, + message: SignedAppsMetrics, + claim_map: ClaimMap, + ) -> DispatchResult { + let _ = ensure_signed(origin)?; + let worker_pubkey = { + // signature verification + ensure!( + message.verify::(), + Error::::SignatureVerificationFailed + ); + let worker_pubkey = WorkerPublicKey(message.worker_pubkey); + ensure!( + registry::Pallet::::worker_exsists(&worker_pubkey), + Error::::InvalidWorkerPubkey + ); + worker_pubkey + }; + + let VersionedAppsMetrics::V0(all_metrics) = message.metrics; + + let worker_info = { + // ensure the session matches + let MetricsToken { session, sn, nonce } = all_metrics.token; + let Some(mut session_info) = WorkerSessions::::get(worker_pubkey) else { + return Err(Error::::WorkerNotFound.into()); + }; + ensure!( + session_info.session_id == session, + Error::::SessionMismatch + ); + ensure!( + session_info.last_metrics_sn < sn, + Error::::OutdatedMessage + ); + session_info.last_nonce = nonce; + session_info.last_metrics_sn = sn; + WorkerSessions::::insert(worker_pubkey, &session_info); + session_info + }; + + { + // update metrics for each ticket + + // Up to 64 entries + let claim_map: BTreeMap<_, _> = claim_map.into_iter().collect(); + + // Up to 64 entries + for metrics in all_metrics.apps { + let Some(ticket_ids) = claim_map.get(&metrics.address) else { + continue; + }; + // Up to 5 entries + for ticket_id in ticket_ids.iter() { + let ticket = + Tickets::::get(ticket_id).ok_or(Error::::TicketNotFound)?; + + if ticket.prices.is_empty() { + continue; + } + + ensure!(ticket.address == metrics.address, Error::::NotAllowed); + match ticket.workers { + WorkerSet::Any => (), + WorkerSet::WorkerList(list_id) => { + ensure!( + WorkerListWorkers::::contains_key(list_id, worker_pubkey), + Error::::NotAllowed + ); + } + } + + let mut settlement = + TicketSettlementInfo::::get(ticket_id, worker_pubkey); + + // Pay out and update the settlement infomation + let cost = ticket.prices.cost_of(&metrics).into(); + if settlement.current_session_id != metrics.session { + settlement.current_session_id = metrics.session; + settlement.current_session_paid = cost; + } + let payout = cost.saturating_sub(settlement.current_session_paid); + if !payout.is_zero() { + let ticket_account = ticket_account_address(*ticket_id); + let transfer_result = ::Currency::transfer( + &ticket_account, + &worker_info.recipient, + payout, + KeepAlive, + ); + match transfer_result { + Ok(_) => { + settlement.current_session_paid = cost; + settlement.total_paid = + settlement.total_paid.saturating_add(payout); + Self::deposit_event(Event::Settled { + ticket_id: *ticket_id, + worker: worker_pubkey, + payout, + session_cost: cost, + recipient: worker_info.recipient.clone(), + }); + } + Err(_) => { + Self::deposit_event(Event::SettleFailed { + ticket_id: *ticket_id, + worker: worker_pubkey, + payout, + session_cost: cost, + }); + } + } + } + TicketSettlementInfo::::insert(ticket_id, worker_pubkey, settlement); + } + } + } + Ok(()) + } + + // MARK: - Benchmark + + /// Submits a benchmark score for a worker. + /// + /// This function allows submitting a benchmark score for a worker, which can be used to update the worker's initial score or simulate a V2 heartbeat. + /// + /// # Parameters + /// - `as_init_score`: If true, the score will update the worker's initial score; otherwise, it will simulate a V2 heartbeat. + /// - `message`: A signed message containing the benchmark score. + #[pallet::call_index(8)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn benchmark_score_submit( + origin: OriginFor, + as_init_score: bool, + message: SignedMessage, + ) -> DispatchResult { + let _ = ensure_signed(origin)?; + ensure!( + message.verify::(), + Error::::SignatureVerificationFailed + ); + let worker_pubkey = WorkerPublicKey(message.worker_pubkey); + ensure!( + registry::Pallet::::worker_exsists(&worker_pubkey), + Error::::InvalidWorkerPubkey + ); + let bench_app_info = + BenchmarkApps::::get(message.app_address).ok_or(Error::::InvalidBenchApp)?; + match message.message { + SigningMessage::BenchScore(BenchScore { + gas_per_second, + gas_consumed, + timestamp_secs, + metrics_token, + }) => { + use frame_support::traits::UnixTime; + + let now = T::UnixTime::now().as_secs() as i64; + let diff = (now - timestamp_secs as i64).abs(); + ensure!(diff < 600, Error::::OutdatedMessage); + + Self::update_metrics_token(&worker_pubkey, &metrics_token)?; + + // Update the worker init score + if as_init_score { + let iterations_per_sec = bench_app_info + .score_ratio + .saturating_mul_u64(gas_per_second); + let score = iterations_per_sec.saturating_mul(6); + registry::Pallet::::update_worker_init_score(&worker_pubkey, score); + } else if let Some(mut computation_state) = + ComputationWorkers::::get(worker_pubkey) + { + // If the worker is scheduled computing by the chain, simulate a heartbeat message. + let p_init = + registry::Pallet::::worker_init_score(&worker_pubkey).unwrap_or(0); + let iterations = + bench_app_info.score_ratio.saturating_mul_u64(gas_consumed); + let delta_time = now - computation_state.last_update_time; + if delta_time <= 0 { + computation_state.last_iterations = iterations; + ComputationWorkers::::insert(worker_pubkey, computation_state); + return Ok(()); + } + let delta_iterations = iterations - computation_state.last_iterations; + let p_instant = delta_iterations / delta_time as u64 * 6; + let p_max = p_init * 120 / 100; + let p_instant = p_instant.min(p_max) as u32; + let worker = MessageOrigin::Worker(worker_pubkey); + + // Minic the worker heartbeat message + let worker_report = WorkingReportEvent::HeartbeatV3 { + iterations, + session_id: computation_state.session_id, + p_instant, + }; + mq::Pallet::::push_bound_message(worker, worker_report); + Self::deposit_event(Event::HeartbeatV3 { + worker: worker_pubkey, + session_id: computation_state.session_id, + iterations, + p_instant, + }); + + computation_state.last_iterations = iterations; + computation_state.last_update_time = now; + ComputationWorkers::::insert(worker_pubkey, computation_state); + } + } + }; + Ok(()) + } + + /// Adds a new benchmark application (governance only). + /// + /// This function allows the governance to add a new benchmark application to the whitelist. + /// + /// # Parameters + /// - `address`: The address of the benchmark application. + /// - `manifest_cid`: The IPFS CID of the application manifest. + /// - `score_ratio`: The ratio for mapping gas to score. + #[pallet::call_index(9)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn benchmark_app_add( + origin: OriginFor, + address: Address, + manifest_cid: BoundedString<128>, + score_ratio: Fraction, + ) -> DispatchResult { + T::GovernanceOrigin::ensure_origin(origin)?; + + ensure!(score_ratio.denominator > 0, Error::::InvalidParameter); + + let ticket = Self::add_ticket(TicketInfo { + system: true, + owner: None, + workers: WorkerSet::Any, + address, + manifest_cid, + prices: Default::default(), + }); + BenchmarkApps::::insert( + address, + BenchAppInfo { + ticket, + score_ratio, + }, + ); + Self::deposit_event(Event::BenchmarkAppAdded { address }); + Ok(()) + } + + /// Sets the recommended benchmark application (governance only). + /// + /// # Parameters + /// - `address`: The address of the recommended benchmark application. + #[pallet::call_index(10)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn benchmark_app_set_recommended( + origin: OriginFor, + address: Address, + ) -> DispatchResult { + T::GovernanceOrigin::ensure_origin(origin)?; + RecommendedBenchmarkApp::::set(Some(address)); + Self::deposit_event(Event::RecommendedBenchmarkAppChanged { address }); + Ok(()) + } + + /// Combine benchmark_app_add and benchmark_app_set_recommended + #[pallet::call_index(11)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn benchmark_app_set( + origin: OriginFor, + address: Address, + manifest_cid: BoundedString<128>, + score_ratio: Fraction, + ) -> DispatchResult { + Self::benchmark_app_add(origin.clone(), address, manifest_cid, score_ratio)?; + Self::benchmark_app_set_recommended(origin, address) + } + + /// Remove a benchmark application from the whitelist (governance only). + #[pallet::call_index(12)] + #[pallet::weight(Weight::from_parts(10_000u64, 0) + T::DbWeight::get().writes(1u64))] + pub fn benchmark_app_remove(origin: OriginFor, address: Address) -> DispatchResult { + T::GovernanceOrigin::ensure_origin(origin)?; + BenchmarkApps::::remove(address); + Ok(()) + } + } + + // MARK: Support functions + + impl Pallet + where + T: mq::Config, + { + fn add_ticket(info: TicketInfo) -> TicketId { + let id = { + let id = NextTicketId::::get(); + NextTicketId::::put(id.wrapping_add(1)); + id + }; + Tickets::::insert(id, info); + Self::deposit_event(Event::TicketCreated { id }); + id + } + + fn add_worker_list(info: WorkerListInfo) -> ListId { + let id = { + let id = NextWorkerListId::::get(); + NextWorkerListId::::put(id.wrapping_add(1)); + id + }; + WorkerLists::::insert(id, info); + Self::deposit_event(Event::WorkerListCreated { id }); + id + } + + fn update_metrics_token( + worker_pubkey: &WorkerPublicKey, + metrics_token: &MetricsToken, + ) -> DispatchResult { + let Some(mut worker_session) = WorkerSessions::::get(worker_pubkey) else { + return Err(Error::::WorkerNotFound.into()); + }; + ensure!( + worker_session.last_metrics_sn < metrics_token.sn, + Error::::OutdatedMessage + ); + ensure!( + worker_session.session_id == metrics_token.session, + Error::::SessionMismatch + ); + worker_session.last_metrics_sn = metrics_token.sn; + worker_session.last_nonce = metrics_token.nonce; + WorkerSessions::::insert(worker_pubkey, worker_session); + Ok(()) + } + + pub fn on_worker_event_received(message: DecodedMessage) -> DispatchResult { + ensure!(message.sender.is_pallet(), Error::::InvalidMessageSender); + let SystemEvent::WorkerEvent(event) = message.payload else { + return Ok(()); + }; + let worker_pubkey = event.pubkey; + match event.event { + WorkerEvent::Registered(_) => (), + WorkerEvent::BenchStart { duration: _ } => (), + WorkerEvent::BenchScore(_) => (), + WorkerEvent::Started { session_id, .. } => { + ComputationWorkers::::insert( + worker_pubkey, + ComputationState { + session_id, + unresponsive: false, + last_iterations: 0, + last_update_time: 0, + }, + ); + } + WorkerEvent::Stopped => { + ComputationWorkers::::remove(worker_pubkey); + } + WorkerEvent::EnterUnresponsive => { + ComputationWorkers::::mutate(worker_pubkey, |state| { + if let Some(state) = state { + state.unresponsive = true; + } + }); + } + WorkerEvent::ExitUnresponsive => { + ComputationWorkers::::mutate(worker_pubkey, |state| { + if let Some(state) = state { + state.unresponsive = false; + } + }); + } + } + Ok(()) + } + } + + // MARK: Runtime api + impl Pallet + where + T: mq::Config, + { + pub fn balance_of_ticket(ticket_id: TicketId) -> BalanceOf { + let account = ticket_account_address(ticket_id); + ::Currency::free_balance(&account) + } + } + + sp_api::decl_runtime_apis! { + /// The API of the wapod workers pallet. + pub trait WapodWorkersApi where Balance: codec::Codec { + /// Get balance of given ticket. + fn balance_of_ticket(ticket_id: TicketId) -> Balance; + } + } + + // MARK: - Tests + + #[cfg(test)] + mod tests { + use super::*; + use crate::mock::{ + ecdh_pubkey, elapse_seconds, new_test_ext, set_block_1, take_events, worker_pubkey, + MockCrypto, PhalaRegistry, PhalaWapodWorkers, RuntimeEvent as TestEvent, + RuntimeOrigin as Origin, Test, + }; + // Pallets + use frame_support::{assert_err, assert_ok}; + use phala_types::messaging::WorkerEventWithKey; + use wapod_types::{ + bench_app::{BenchScore, SignedMessage, SigningMessage}, + metrics::{ + AppMetrics, AppsMetrics, MetricsToken, SignedAppsMetrics, VersionedAppsMetrics, + }, + primitives::BoundedVec, + session::{SessionUpdate, SignedSessionUpdate}, + ticket::{Balance, Prices, SignedWorkerDescription, WorkerDescription}, + }; + + fn setup_workers(n: u8) { + for i in 1..=n { + let worker = worker_pubkey(i); + assert_ok!(PhalaRegistry::force_register_worker( + Origin::root(), + worker, + ecdh_pubkey(1), + Some(1) + )); + } + } + + struct Events(Vec); + + impl Events { + fn take() -> Self { + Self(take_events()) + } + fn has(&self, event: impl Into) -> bool { + let event = event.into(); + self.0.iter().any(|x| x == &event) + } + fn find_settlement_for( + &self, + ticket: TicketId, + worker: WorkerPublicKey, + ) -> Option { + for event in self.0.iter() { + if let TestEvent::PhalaWapodWorkers(Event::::Settled { + ticket_id, + worker: worker_id, + payout, + .. + }) = event + { + if ticket_id == &ticket && worker_id == &worker { + return Some(*payout); + } + } + } + None + } + fn find_heartbeat_v3(&self, worker: WorkerPublicKey) -> Option<(u64, u32)> { + for event in self.0.iter() { + if let TestEvent::PhalaWapodWorkers(Event::::HeartbeatV3 { + worker: worker_id, + session_id: _, + iterations, + p_instant, + }) = event + { + if worker_id == &worker { + return Some((*iterations, *p_instant)); + } + } + } + None + } + } + + fn create_worker_list() -> ListId { + create_worker_list_with_price(Prices::default()) + } + + fn create_worker_list_with_price(prices: Prices) -> ListId { + let result = PhalaWapodWorkers::worker_list_create( + Origin::signed(1), + "my list".to_string().into(), + prices, + vec![].into(), + ); + assert_ok!(result); + + let mut list_id = None; + for event in take_events() { + if let TestEvent::PhalaWapodWorkers(Event::::WorkerListCreated { id }) = event + { + list_id = Some(id); + } + } + list_id.expect("No WorkerListCreated event emitted") + } + + fn setup_worker_list(n: u8, prices: Prices) -> ListId { + for id in 1..=n { + let result = PhalaWapodWorkers::worker_description_set( + Origin::signed(1), + SignedWorkerDescription { + worker_pubkey: worker_pubkey(id).0, + worker_description: WorkerDescription { + prices: prices.clone(), + description: "my worker".to_string().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + assert_ok!(result); + } + + let list_id = create_worker_list_with_price(prices); + let result = PhalaWapodWorkers::worker_list_add_workers( + Origin::signed(1), + list_id, + (1..=n).map(worker_pubkey).collect::>().into(), + ); + assert_ok!(result); + for id in 1..=n { + assert!(WorkerListWorkers::::contains_key( + list_id, + worker_pubkey(id) + )) + } + list_id + } + + #[test] + fn can_not_set_worker_description_without_register() { + new_test_ext().execute_with(|| { + set_block_1(); + + let result = PhalaWapodWorkers::worker_description_set( + Origin::signed(1), + SignedWorkerDescription { + worker_pubkey: worker_pubkey(0).0, + worker_description: WorkerDescription { + prices: Prices::default(), + description: "my worker".to_string().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + + assert_err!(result, Error::::InvalidWorkerPubkey); + }); + } + + #[test] + fn can_set_worker_description() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let result = PhalaWapodWorkers::worker_description_set( + Origin::signed(1), + SignedWorkerDescription { + worker_pubkey: worker_pubkey(1).0, + worker_description: WorkerDescription { + prices: Prices::default(), + description: "my worker".to_string().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + + assert_ok!(result); + + let events = Events::take(); + assert!(events.has(Event::WorkerDescriptionSet { + worker: worker_pubkey(1) + })); + }); + } + + #[test] + fn can_not_update_session_without_register() { + new_test_ext().execute_with(|| { + set_block_1(); + + let result = PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(0).0, + update: SessionUpdate { + session: [1; 32], + nonce: [1; 32], + recipient: [1; 32].to_vec().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + + assert_err!(result, Error::::InvalidWorkerPubkey); + }); + } + + #[test] + fn can_update_session_first_time() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let result = PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(1).0, + update: SessionUpdate { + session: [1; 32], + nonce: [1; 32], + recipient: [1; 32].to_vec().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + + assert_ok!(result); + + let events = Events::take(); + assert!(events.has(Event::WorkerSessionUpdated { + worker: worker_pubkey(1), + session: [1; 32], + })); + }); + } + + #[test] + fn can_not_update_session_second_time_with_incorrect_nonce() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let result = PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(1).0, + update: SessionUpdate { + session: [1; 32], + nonce: [1; 32], + recipient: [1; 32].to_vec().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + + assert_ok!(result); + + let result = PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(1).0, + update: SessionUpdate { + session: [1; 32], + nonce: [2; 32], + recipient: [1; 32].to_vec().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + + assert_err!(result, Error::::OutdatedMessage); + + let last_nonce = WorkerSessions::::get(worker_pubkey(1)) + .unwrap() + .last_nonce; + let nonce = [2; 32]; + + // Can update session with correct nonce. + let result = PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(1).0, + update: SessionUpdate { + session: SessionUpdate::calc_session_id::( + nonce, + &last_nonce, + ), + nonce, + recipient: [1; 32].to_vec().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + assert_ok!(result); + }); + } + + #[test] + fn can_not_add_worker_without_price_to_list() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let list_id = create_worker_list(); + + let result = PhalaWapodWorkers::worker_list_add_workers( + Origin::signed(1), + list_id, + vec![worker_pubkey(1)].into(), + ); + + assert_err!(result, Error::::WorkerNotFound); + }); + } + + #[test] + fn can_not_add_worker_to_list_when_price_mismatch() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let result = PhalaWapodWorkers::worker_description_set( + Origin::signed(1), + SignedWorkerDescription { + worker_pubkey: worker_pubkey(1).0, + worker_description: WorkerDescription { + prices: Prices { + tip_price: Some(1), + ..Default::default() + }, + description: "my worker".to_string().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + assert_ok!(result); + + let list_id = create_worker_list(); + + let result = PhalaWapodWorkers::worker_list_add_workers( + Origin::signed(1), + list_id, + vec![worker_pubkey(1)].into(), + ); + + assert_err!(result, Error::::PriceMismatch); + }); + } + + #[test] + fn can_add_worker_to_list() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let result = PhalaWapodWorkers::worker_description_set( + Origin::signed(1), + SignedWorkerDescription { + worker_pubkey: worker_pubkey(1).0, + worker_description: WorkerDescription { + prices: Prices::default(), + description: "my worker".to_string().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + assert_ok!(result); + + let list_id = create_worker_list(); + + let result = PhalaWapodWorkers::worker_list_add_workers( + Origin::signed(1), + list_id, + vec![worker_pubkey(1)].into(), + ); + + assert_ok!(result); + + let events = Events::take(); + assert!(events.has(Event::WorkersAddedToList { + list_id, + workers: vec![worker_pubkey(1)], + })); + }); + } + + #[test] + fn can_remove_worker_from_list() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let result = PhalaWapodWorkers::worker_description_set( + Origin::signed(1), + SignedWorkerDescription { + worker_pubkey: worker_pubkey(1).0, + worker_description: WorkerDescription { + prices: Prices::default(), + description: "my worker".to_string().into(), + }, + signature: b"valid".to_vec().into(), + }, + ); + assert_ok!(result); + + let list_id = create_worker_list(); + + let result = PhalaWapodWorkers::worker_list_add_workers( + Origin::signed(1), + list_id, + vec![worker_pubkey(1)].into(), + ); + assert_ok!(result); + + let result = PhalaWapodWorkers::worker_list_remove_worker( + Origin::signed(1), + list_id, + worker_pubkey(1), + ); + assert_ok!(result); + + let events = Events::take(); + assert!(events.has(Event::WorkerRemovedFromList { + list_id, + worker: worker_pubkey(1) + })); + }); + } + + #[test] + fn can_create_ticket() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let list_id = create_worker_list(); + + let result = PhalaWapodWorkers::ticket_create( + Origin::signed(1), + 0, + [1; 32], + "manifest".to_string().into(), + list_id, + Default::default(), + ); + assert_ok!(result); + + let events = Events::take(); + assert!(events.has(Event::TicketCreated { id: 0 })); + }); + } + + #[test] + fn can_close_ticket() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let list_id = create_worker_list(); + + let result = PhalaWapodWorkers::ticket_create( + Origin::signed(1), + 0, + [1; 32], + "manifest".to_string().into(), + list_id, + Default::default(), + ); + assert_ok!(result); + + let result = PhalaWapodWorkers::ticket_close(Origin::signed(1), 0); + assert_ok!(result); + + let events = Events::take(); + assert!(events.has(Event::TicketClosed { id: 0 })); + }); + } + + #[test] + fn can_settle_ticket() { + new_test_ext().execute_with(|| { + set_block_1(); + + setup_workers(1); + + let gas_price = 1; + let tip_price = 2; + let gas_consumed = 20; + let tip = 10; + let prices = Prices { + gas_price: Some(gas_price), + tip_price: Some(tip_price), + ..Default::default() + }; + let reward = tip as u128 * tip_price + gas_consumed as u128 * gas_price; + let recipient = 42_u64; + let app_address = [2; 32]; + let list_id = setup_worker_list(1, prices); + let claim_map = BoundedVec::from(vec![(app_address, vec![list_id].into())]); + + assert_ok!(PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(1).0, + update: SessionUpdate { + session: [1; 32], + nonce: [1; 32], + recipient: recipient.encode().into(), + }, + signature: b"valid".to_vec().into(), + }, + )); + + assert_ok!(PhalaWapodWorkers::ticket_create( + Origin::signed(1), + 100, + app_address, + "manifest".to_string().into(), + list_id, + Default::default(), + )); + + assert!(WorkerListWorkers::::contains_key( + list_id, + worker_pubkey(1) + )); + + let result = PhalaWapodWorkers::ticket_settle( + Origin::signed(1), + SignedAppsMetrics { + worker_pubkey: worker_pubkey(1).0, + metrics: VersionedAppsMetrics::V0(AppsMetrics { + token: MetricsToken { + session: [1; 32], + sn: 1, + nonce: [1; 32], + }, + apps: vec![AppMetrics { + address: app_address, + session: [1; 32], + tip, + gas_consumed, + ..Default::default() + }] + .into(), + }), + signature: b"valid".to_vec().into(), + }, + claim_map.clone(), + ); + assert_ok!(result); + + // No payment for the first commit + let events = Events::take(); + let payout = events.find_settlement_for(0, worker_pubkey(1)); + assert_eq!(payout, None); + + let result = PhalaWapodWorkers::ticket_settle( + Origin::signed(1), + SignedAppsMetrics { + worker_pubkey: worker_pubkey(1).0, + metrics: VersionedAppsMetrics::V0(AppsMetrics { + token: MetricsToken { + session: [1; 32], + sn: 2, + nonce: [1; 32], + }, + apps: vec![AppMetrics { + address: app_address, + session: [1; 32], + tip: tip * 2, + gas_consumed: gas_consumed * 2, + ..Default::default() + }] + .into(), + }), + signature: b"valid".to_vec().into(), + }, + claim_map, + ); + assert_ok!(result); + // Should pay for the second commit + let events = Events::take(); + let payout = events.find_settlement_for(0, worker_pubkey(1)); + assert_eq!(payout, Some(reward)); + }); + } + + #[test] + fn can_submit_benchmark_score() { + new_test_ext().execute_with(|| { + set_block_1(); + setup_workers(1); + + let gas_per_second = 500; + let timestamp_secs = 10; + let gas_consumed = gas_per_second * timestamp_secs; + let app_address = [2; 32]; + let receiver = 42u64; + + let metrics_token = MetricsToken { + session: [1; 32], + sn: 1, + nonce: [1; 32], + }; + + // set up the benchmark app + assert_ok!(PhalaWapodWorkers::benchmark_app_set( + Origin::root(), + app_address, + "manifest".to_string().into(), + Fraction { + numerator: 1, + denominator: 10, + }, + )); + + // set up worker session + assert_ok!(PhalaWapodWorkers::worker_session_update( + Origin::signed(1), + SignedSessionUpdate { + public_key: worker_pubkey(1).0, + update: SessionUpdate { + session: [1; 32], + nonce: [1; 32], + recipient: receiver.encode().into(), + }, + signature: b"valid".to_vec().into(), + }, + )); + + let message = SignedMessage { + worker_pubkey: worker_pubkey(1).0, + app_address, + signature: b"valid".to_vec().into(), + message: SigningMessage::BenchScore(BenchScore { + gas_per_second, + gas_consumed, + timestamp_secs, + metrics_token, + }), + }; + + let result = PhalaWapodWorkers::benchmark_score_submit( + Origin::signed(1), + true, + message.clone(), + ); + assert_ok!(result); + let init_score = PhalaRegistry::worker_init_score(&worker_pubkey(1)); + assert_eq!(init_score, Some(300)); + + take_events(); + + // simulate a V2 heartbeat + PhalaWapodWorkers::on_worker_event_received(DecodedMessage { + sender: MessageOrigin::Pallet(vec![]), + destination: vec![].into(), + payload: SystemEvent::WorkerEvent(WorkerEventWithKey { + pubkey: worker_pubkey(1), + event: WorkerEvent::Started { + init_p: 1000, + init_v: 2000, + session_id: 1, + }, + }), + }) + .expect("Failed to send mq message"); + + let message = SignedMessage { + worker_pubkey: worker_pubkey(1).0, + app_address, + signature: b"valid".to_vec().into(), + message: SigningMessage::BenchScore(BenchScore { + gas_per_second, + gas_consumed: gas_consumed * 2, + timestamp_secs: timestamp_secs * 2, + metrics_token: MetricsToken { + session: [1; 32], + sn: 2, + nonce: [1; 32], + }, + }), + }; + + assert_ok!(PhalaWapodWorkers::benchmark_score_submit( + Origin::signed(1), + false, + message + )); + // No heartbeat the first time + let events = Events::take(); + assert!(events.find_heartbeat_v3(worker_pubkey(1)).is_none()); + + elapse_seconds(timestamp_secs); + + let message = SignedMessage { + worker_pubkey: worker_pubkey(1).0, + app_address, + signature: b"valid".to_vec().into(), + message: SigningMessage::BenchScore(BenchScore { + gas_per_second, + gas_consumed: gas_consumed * 3, + timestamp_secs: timestamp_secs * 3, + metrics_token: MetricsToken { + session: [1; 32], + sn: 3, + nonce: [1; 32], + }, + }), + }; + assert_ok!(PhalaWapodWorkers::benchmark_score_submit( + Origin::signed(1), + false, + message + )); + let events = Events::take(); + let (iterations, p_instant) = events.find_heartbeat_v3(worker_pubkey(1)).unwrap(); + assert_eq!((iterations, p_instant), (1500, 300)); + }); + } + } +} diff --git a/standalone/prouter/Cargo.lock b/standalone/prouter/Cargo.lock index 8150d6f27..61c84be63 100644 --- a/standalone/prouter/Cargo.lock +++ b/standalone/prouter/Cargo.lock @@ -510,7 +510,7 @@ checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -676,7 +676,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.43", + "syn 2.0.71", "which", ] @@ -1400,7 +1400,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -1448,7 +1448,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -1470,7 +1470,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core 0.20.1", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -1499,7 +1499,7 @@ checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -1643,7 +1643,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.43", + "syn 2.0.71", "termcolor", "toml 0.8.2", "walkdir", @@ -1802,7 +1802,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -1822,7 +1822,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2019,7 +2019,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.43", + "syn 2.0.71", "toml 0.7.6", "walkdir", ] @@ -2037,7 +2037,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2063,7 +2063,7 @@ dependencies = [ "serde", "serde_json", "strum 0.25.0", - "syn 2.0.43", + "syn 2.0.71", "tempfile", "thiserror", "tiny-keccak", @@ -2214,7 +2214,7 @@ dependencies = [ "fs-err", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2442,10 +2442,10 @@ name = "frame-election-provider-solution-type" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2564,7 +2564,7 @@ dependencies = [ "proc-macro2", "quote", "sp-core-hashing", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2573,10 +2573,10 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2586,7 +2586,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -2740,7 +2740,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -3202,7 +3202,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -3784,7 +3784,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -3798,7 +3798,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -3809,7 +3809,7 @@ checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -3820,7 +3820,7 @@ checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -4110,7 +4110,7 @@ dependencies = [ "proc-macro-crate 1.2.1", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -4869,10 +4869,10 @@ name = "pallet-staking-reward-curve" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -5025,9 +5025,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -5040,11 +5040,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 1.2.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -5233,7 +5233,6 @@ dependencies = [ "log", "parity-scale-codec", "phala-crypto", - "phala-git-revision", "phala-node-runtime", "phala-trie-storage", "phala-types", @@ -5262,10 +5261,6 @@ dependencies = [ "sp-core", ] -[[package]] -name = "phala-git-revision" -version = "0.1.0" - [[package]] name = "phala-mq" version = "0.1.0" @@ -5405,10 +5400,12 @@ dependencies = [ "serde", "serde_json", "sgx-attestation", + "sp-api", "sp-core", "sp-io", "sp-runtime", "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0)", + "wapod-types", ] [[package]] @@ -5534,7 +5531,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -5573,7 +5570,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -5657,7 +5654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282" dependencies = [ "proc-macro2", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -5687,14 +5684,21 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +version = "2.0.2" +source = "git+https://github.com/kvinwang/proc-macro-crate?branch=update-toml#758987cc8f582405f07364dd536142abd5f4da55" dependencies = [ - "toml_datetime", "toml_edit 0.20.2", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -5733,14 +5737,14 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -5924,9 +5928,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -6631,9 +6635,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec 1.0.1", "cfg-if", @@ -6645,11 +6649,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.2.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -6844,22 +6848,22 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7173,10 +7177,10 @@ dependencies = [ "Inflector", "blake2", "expander", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7363,7 +7367,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "quote", "sp-core-hashing", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7394,7 +7398,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7404,7 +7408,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk#b4c816665bd094b6ad703f1 dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7613,10 +7617,10 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "Inflector", "expander", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7626,10 +7630,10 @@ source = "git+https://github.com/paritytech/polkadot-sdk#b4c816665bd094b6ad703f1 dependencies = [ "Inflector", "expander", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7814,7 +7818,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -7997,7 +8001,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -8064,7 +8068,7 @@ dependencies = [ "quote", "scale-info", "subxt-metadata", - "syn 2.0.43", + "syn 2.0.71", "thiserror", "tokio", ] @@ -8076,7 +8080,7 @@ dependencies = [ "darling 0.20.1", "proc-macro-error", "subxt-codegen", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -8123,9 +8127,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.43" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -8275,7 +8279,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -8365,7 +8369,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -8477,9 +8481,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -8510,6 +8514,17 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -8536,7 +8551,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.71", ] [[package]] @@ -8912,6 +8927,17 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wapod-types" +version = "0.1.0-dev.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1af243243426435872a873bb893bbbbc4865caa88d6d4c8856d717a3fcd7094" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/standalone/prouter/Cargo.toml b/standalone/prouter/Cargo.toml index 1d593882c..94af15cbd 100644 --- a/standalone/prouter/Cargo.toml +++ b/standalone/prouter/Cargo.toml @@ -34,3 +34,4 @@ bindgen = "0.66" [patch.crates-io] # TODO.kevin: Move back to crates.io once it released 1.0 derive_more = { version = "0.99.17", git = "https://github.com/JelteF/derive_more" } +proc-macro-crate = { git = "https://github.com/kvinwang/proc-macro-crate", branch = "update-toml" } diff --git a/standalone/pruntime/Cargo.lock b/standalone/pruntime/Cargo.lock index 6775ea875..6501084e3 100644 --- a/standalone/pruntime/Cargo.lock +++ b/standalone/pruntime/Cargo.lock @@ -611,7 +611,7 @@ checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -1183,7 +1183,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -1666,7 +1666,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -1786,7 +1786,7 @@ checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -1860,7 +1860,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics 0.10.0", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -1963,7 +1963,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.43", + "syn 2.0.70", "termcolor", "toml 0.8.2", "walkdir", @@ -2154,7 +2154,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2194,7 +2194,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2412,7 +2412,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.43", + "syn 2.0.70", "toml 0.7.6", "walkdir", ] @@ -2430,7 +2430,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2456,7 +2456,7 @@ dependencies = [ "serde", "serde_json", "strum 0.25.0", - "syn 2.0.43", + "syn 2.0.70", "tempfile", "thiserror", "tiny-keccak", @@ -2601,7 +2601,7 @@ dependencies = [ "fs-err", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2831,10 +2831,10 @@ name = "frame-election-provider-solution-type" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2941,7 +2941,7 @@ dependencies = [ "proc-macro2", "quote", "sp-core-hashing", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2950,10 +2950,10 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -2963,7 +2963,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -3117,7 +3117,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -3836,7 +3836,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -3893,7 +3893,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -3908,7 +3908,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", "synstructure", ] @@ -4339,7 +4339,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -4353,7 +4353,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -4364,7 +4364,7 @@ checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -4375,7 +4375,7 @@ checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -4748,7 +4748,7 @@ dependencies = [ "proc-macro-crate 1.2.1", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -5030,7 +5030,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -5559,10 +5559,10 @@ name = "pallet-staking-reward-curve" version = "4.0.0-dev" source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0#789ffb66dcfcf3b54a1e6786e928ac91c4fdb465" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -5715,9 +5715,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -5730,11 +5730,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 1.2.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -6217,15 +6217,17 @@ dependencies = [ "serde", "serde_json", "sgx-attestation", + "sp-api", "sp-core", "sp-io", "sp-runtime", "sp-std 8.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polkadot-v1.5.0)", + "wapod-types", ] [[package]] name = "phala-rocket-middleware" -version = "0.1.0" +version = "0.1.1" dependencies = [ "log", "rocket", @@ -6419,7 +6421,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -6516,7 +6518,7 @@ dependencies = [ "proc-macro-crate 1.2.1", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", "unzip3", ] @@ -6650,7 +6652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282" dependencies = [ "proc-macro2", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -6680,14 +6682,21 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +version = "2.0.2" +source = "git+https://github.com/kvinwang/proc-macro-crate?branch=update-toml#758987cc8f582405f07364dd536142abd5f4da55" dependencies = [ - "toml_datetime", "toml_edit 0.20.2", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -6726,14 +6735,14 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -6759,7 +6768,7 @@ checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", "version_check", "yansi 0.5.1", ] @@ -7011,9 +7020,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -7563,7 +7572,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.43", + "syn 2.0.70", "unicode-xid", "version_check", ] @@ -7887,9 +7896,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec 1.0.1", "cfg-if", @@ -7901,11 +7910,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.2.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -8077,9 +8086,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -8107,13 +8116,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -8497,10 +8506,10 @@ dependencies = [ "Inflector", "blake2", "expander", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -8687,7 +8696,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "quote", "sp-core-hashing", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -8718,7 +8727,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -8728,7 +8737,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk#b4c816665bd094b6ad703f1 dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -8937,10 +8946,10 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?branch=release-polk dependencies = [ "Inflector", "expander", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -8950,10 +8959,10 @@ source = "git+https://github.com/paritytech/polkadot-sdk#b4c816665bd094b6ad703f1 dependencies = [ "Inflector", "expander", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -9138,7 +9147,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -9427,7 +9436,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -9482,9 +9491,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.43" +version = "2.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" dependencies = [ "proc-macro2", "quote", @@ -9505,7 +9514,7 @@ checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", "unicode-xid", ] @@ -9660,7 +9669,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -9789,7 +9798,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -9911,9 +9920,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -9944,6 +9953,17 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -9970,7 +9990,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -10549,6 +10569,17 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wapod-types" +version = "0.1.0-dev.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e15d1f0f6fc295d001a38335e013f18d887c968de19d3ed5a4e7e3e5efbdc60" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -10582,7 +10613,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", "wasm-bindgen-shared", ] @@ -10639,7 +10670,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11511,7 +11542,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] @@ -11552,7 +11583,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.70", ] [[package]] diff --git a/standalone/pruntime/Cargo.toml b/standalone/pruntime/Cargo.toml index 4f74d9c8b..9d06842d4 100644 --- a/standalone/pruntime/Cargo.toml +++ b/standalone/pruntime/Cargo.toml @@ -55,3 +55,5 @@ derive_more = { version = "0.99.17", git = "https://github.com/JelteF/derive_mor # For pink-chain-extension, it will introduce Substrate from crates-io which usually different with polkadot-branch sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0" } sp-runtime-interface = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.5.0" } + +proc-macro-crate = { git = "https://github.com/kvinwang/proc-macro-crate", branch = "update-toml" } diff --git a/standalone/runtime/src/lib.rs b/standalone/runtime/src/lib.rs index 1c2d16167..85c6ec8ca 100644 --- a/standalone/runtime/src/lib.rs +++ b/standalone/runtime/src/lib.rs @@ -39,8 +39,8 @@ use frame_support::{ fungible::HoldConsideration, tokens::{PayFromAccount, UnityAssetBalanceConversion}, AsEnsureOriginWithArg, ConstU128, ConstU32, Currency, EitherOfDiverse, EqualPrivilegeOnly, - Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, OnUnbalanced, - SortedMembers, WithdrawReasons, LinearStoragePrice, + Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, + LockIdentifier, OnUnbalanced, SortedMembers, WithdrawReasons, }, weights::{ constants::{ @@ -110,7 +110,7 @@ mod voter_bags; pub use phala_pallets::{ pallet_base_pool, pallet_computation, pallet_mq, pallet_phat, pallet_phat_tokenomic, - pallet_registry, pallet_stake_pool, pallet_stake_pool_v2, pallet_vault, + pallet_registry, pallet_stake_pool, pallet_stake_pool_v2, pallet_vault, pallet_wapod_workers, pallet_wrapped_balances, puppets, }; use phat_offchain_rollup::{anchor as pallet_anchor, oracle as pallet_oracle}; @@ -337,8 +337,9 @@ impl InstanceFilter for ProxyType { | RuntimeCall::Elections(..) | RuntimeCall::Treasury(..) ), - ProxyType::Staking => - matches!(c, RuntimeCall::Staking(..) | RuntimeCall::FastUnstake(..)), + ProxyType::Staking => { + matches!(c, RuntimeCall::Staking(..) | RuntimeCall::FastUnstake(..)) + } ProxyType::StakePoolManager => matches!( c, RuntimeCall::Utility { .. } @@ -450,7 +451,7 @@ impl pallet_babe::Config for Runtime { type KeyOwnerProof = >::Proof; type EquivocationReportSystem = - pallet_babe::EquivocationReportSystem; + pallet_babe::EquivocationReportSystem; } parameter_types! { @@ -713,13 +714,16 @@ impl Get> for OffchainRandomBalancing { max => { let seed = sp_io::offchain::random_seed(); let random = ::decode(&mut TrailingZeroInput::new(&seed)) - .expect("input is padded with zeroes; qed") % - max.saturating_add(1); + .expect("input is padded with zeroes; qed") + % max.saturating_add(1); random as usize - }, + } }; - let config = BalancingConfig { iterations, tolerance: 0 }; + let config = BalancingConfig { + iterations, + tolerance: 0, + }; Some(config) } } @@ -1212,7 +1216,7 @@ impl pallet_grandpa::Config for Runtime { type MaxSetIdSessionEntries = MaxSetIdSessionEntries; type KeyOwnerProof = >::Proof; type EquivocationReportSystem = - pallet_grandpa::EquivocationReportSystem; + pallet_grandpa::EquivocationReportSystem; } parameter_types! { @@ -1280,7 +1284,7 @@ impl pallet_society::Config for Runtime { type ClaimPeriod = ClaimPeriod; type MaxLockDuration = MaxLockDuration; type FounderSetOrigin = - pallet_collective::EnsureProportionMoreThan; + pallet_collective::EnsureProportionMoreThan; type ChallengePeriod = ChallengePeriod; type MaxPayouts = MaxPayouts; type MaxBids = MaxBids; @@ -1526,6 +1530,11 @@ impl pallet_phat_tokenomic::Config for Runtime { type Currency = Balances; } +impl pallet_wapod_workers::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Crypto = pallet_wapod_workers::SpCrypto; +} + parameter_types! { pub const QueuePrefix: &'static [u8] = b"_queue/"; pub const QueueCapacity: u32 = 128; @@ -1626,6 +1635,7 @@ construct_runtime!( PhalaBasePool: pallet_base_pool, PhalaPhatContracts: pallet_phat, PhalaPhatTokenomic: pallet_phat_tokenomic, + PhalaWapodWorkers: pallet_wapod_workers, // Rollup and Oracles PhatRollupAnchor: pallet_anchor = 100, @@ -1915,6 +1925,12 @@ impl_runtime_apis! { } } + impl pallet_wapod_workers::WapodWorkersApi for Runtime { + fn balance_of_ticket(ticket_id: pallet_wapod_workers::TicketId) -> Balance { + PhalaWapodWorkers::balance_of_ticket(ticket_id) + } + } + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) diff --git a/standalone/runtime/src/msg_routing.rs b/standalone/runtime/src/msg_routing.rs index 2c351665d..27e13bbf7 100644 --- a/standalone/runtime/src/msg_routing.rs +++ b/standalone/runtime/src/msg_routing.rs @@ -38,6 +38,7 @@ impl pallet_mq::QueueNotifyConfig for MessageRouteConfig { PhalaPhatContracts::on_worker_cluster_message_received, PhalaPhatContracts::on_cluster_message_received, PhalaPhatContracts::on_contract_message_received, + PhalaWapodWorkers::on_worker_event_received, // BridgeTransfer::on_message_received, }; Ok(())