diff --git a/Cargo.lock b/Cargo.lock index 1dd55b44..26899249 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +checksum = "136d4d23bcc79e27423727b36823d86233aad06dfea531837b038394d11e9928" dependencies = [ "concurrent-queue", "event-listener 5.3.0", @@ -667,11 +667,10 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f98c37cf288e302c16ef6c8472aad1e034c6c84ce5ea7b8101c98eb4a802fee" +checksum = "b10202063978b3351199d68f8b22c4e47e4b1b822f8d43fd862d5ea8c006b29a" dependencies = [ - "async-lock 3.3.0", "async-task", "concurrent-queue", "fastrand 2.0.2", @@ -810,7 +809,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -962,13 +961,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.17", + "prettyplease 0.2.19", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -1126,7 +1125,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.2.0", + "async-channel 2.2.1", "async-lock 3.3.0", "async-task", "fastrand 2.0.2", @@ -1294,9 +1293,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.92" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" dependencies = [ "jobserver", "libc", @@ -1368,9 +1367,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1465,7 +1464,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2159,7 +2158,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2501,7 +2500,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2541,7 +2540,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2558,7 +2557,7 @@ checksum = "ad08a837629ad949b73d032c637653d069e909cffe4ee7870b02301939ce39cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2650,7 +2649,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2752,7 +2751,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2798,7 +2797,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.58", + "syn 2.0.59", "termcolor", "toml 0.8.12", "walkdir", @@ -2919,9 +2918,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" @@ -2977,7 +2976,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -2988,7 +2987,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -3117,7 +3116,7 @@ dependencies = [ "prettier-please", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -3175,8 +3174,9 @@ dependencies = [ [[package]] name = "fc-pallet-referenda-tracks" version = "1.0.0" -source = "git+https://github.com/virto-network/frame-contrib?branch=main#3d0e4269cb6b0d20dda1604436691fe71bce475d" +source = "git+https://github.com/virto-network/frame-contrib?branch=feature/trait-tracks#31bbf0bde77ca3179e8b7ebf1fbe4d2365184450" dependencies = [ + "fc-traits-tracks", "frame-benchmarking", "frame-support", "frame-system", @@ -3193,13 +3193,24 @@ dependencies = [ [[package]] name = "fc-traits-memberships" version = "0.1.0" -source = "git+https://github.com/virto-network/frame-contrib?branch=main#3d0e4269cb6b0d20dda1604436691fe71bce475d" +source = "git+https://github.com/virto-network/frame-contrib?branch=main#2daaaeb863411600661fe15ad7ef555c0bf4b7d1" dependencies = [ "frame-support", "parity-scale-codec", "scale-info", ] +[[package]] +name = "fc-traits-tracks" +version = "0.1.0" +source = "git+https://github.com/virto-network/frame-contrib?branch=feature/trait-tracks#31bbf0bde77ca3179e8b7ebf1fbe4d2365184450" +dependencies = [ + "frame-support", + "pallet-referenda", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "fdlimit" version = "0.3.0" @@ -3425,7 +3436,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -3553,7 +3564,7 @@ dependencies = [ "proc-macro2", "quote", "sp-core-hashing", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -3565,7 +3576,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -3575,7 +3586,7 @@ source = "git+https://github.com/virto-network/polkadot-sdk?branch=release-virto dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -3754,7 +3765,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -4678,7 +4689,7 @@ checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" [[package]] name = "kreivo-runtime" -version = "0.10.2" +version = "0.11.0" dependencies = [ "assets-common", "cumulus-pallet-aura-ext", @@ -4708,6 +4719,7 @@ dependencies = [ "pallet-balances", "pallet-collator-selection", "pallet-communities", + "pallet-communities-manager", "pallet-message-queue", "pallet-multisig", "pallet-nfts", @@ -5465,7 +5477,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -5479,7 +5491,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -5490,7 +5502,7 @@ checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -5501,7 +5513,7 @@ checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -6573,6 +6585,32 @@ dependencies = [ "virto-common", ] +[[package]] +name = "pallet-communities-manager" +version = "0.1.0" +dependencies = [ + "fc-pallet-referenda-tracks", + "fc-traits-tracks", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-assets", + "pallet-balances", + "pallet-communities", + "pallet-nfts", + "pallet-ranked-collective", + "pallet-referenda", + "pallet-scheduler", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 8.0.0", + "virto-common", +] + [[package]] name = "pallet-conviction-voting" version = "4.0.0-dev" @@ -7182,7 +7220,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -7658,7 +7696,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -7699,7 +7737,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -8837,7 +8875,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -8847,7 +8885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ "polkavm-derive-impl", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -8970,7 +9008,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" dependencies = [ "proc-macro2", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -8985,12 +9023,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ "proc-macro2", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -9098,14 +9136,14 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" dependencies = [ "unicode-ident", ] @@ -9144,7 +9182,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -9469,7 +9507,7 @@ checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -10113,7 +10151,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -11082,7 +11120,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -11375,14 +11413,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -11767,7 +11805,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -12023,13 +12061,13 @@ source = "git+https://github.com/virto-network/polkadot-sdk?branch=release-virto dependencies = [ "quote", "sp-core-hashing", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -12062,17 +12100,17 @@ source = "git+https://github.com/virto-network/polkadot-sdk?branch=release-virto dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -12089,7 +12127,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "environmental", "parity-scale-codec", @@ -12307,7 +12345,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -12333,20 +12371,20 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "Inflector", "expander 2.1.0", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -12431,7 +12469,7 @@ source = "git+https://github.com/virto-network/polkadot-sdk?branch=release-virto [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" [[package]] name = "sp-storage" @@ -12449,7 +12487,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12486,7 +12524,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "parity-scale-codec", "tracing", @@ -12568,7 +12606,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -12587,7 +12625,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c963dc283af77824ceeeecc20e205f3a17968746" +source = "git+https://github.com/paritytech/polkadot-sdk#753bf2d860e083b5da25fe4171c0e540ddad4888" dependencies = [ "impl-trait-for-tuples", "log", @@ -12828,7 +12866,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -12959,9 +12997,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" dependencies = [ "proc-macro2", "quote", @@ -13076,7 +13114,7 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -13087,7 +13125,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -13231,7 +13269,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -13433,7 +13471,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -13476,7 +13514,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -13824,7 +13862,7 @@ dependencies = [ [[package]] name = "virto-node" -version = "0.10.2" +version = "0.11.0" dependencies = [ "assert_cmd", "async-trait", @@ -14005,7 +14043,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", "wasm-bindgen-shared", ] @@ -14039,7 +14077,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -14529,9 +14567,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.15" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" +checksum = "81a1851a719f11d1d2fea40e15c72f6c00de8c142d7ac47c1441cc7e4d0d5bc6" dependencies = [ "bytemuck", "safe_arch", @@ -14893,7 +14931,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -14936,7 +14974,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] @@ -14956,7 +14994,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.59", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 63a5d3d8..5bb6f192 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ pallet-asset-registry = { default-features = false, path = "pallets/asset-regist pallet-burner = { default-features = false, path = "pallets/burner" } pallet-payments = { default-features = false, path = "pallets/payments" } pallet-communities = { default-features = false, path = "pallets/communities" } +pallet-communities-manager = { default-features = false, path = "pallets/communities-manager" } virto-common = { default-features = false, path = "common" } runtime-common = { default-features = false, path = "runtime/common" } @@ -58,7 +59,8 @@ kusama-runtime-constants = { default-features = false, path = "runtime/kusama-ru # Frame Contrib fc-traits-memberships = { git = "https://github.com/virto-network/frame-contrib", branch = "main", default-features = false } -pallet-referenda-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "main", package="fc-pallet-referenda-tracks", default-features = false } +fc-traits-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "feature/trait-tracks", default-features = false } +pallet-referenda-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "feature/trait-tracks", package="fc-pallet-referenda-tracks", default-features = false } # Substrate std try-runtime-cli = { git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-v1.5.0" } diff --git a/node/Cargo.toml b/node/Cargo.toml index 551439a7..215edbe9 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "virto-node" -version = "0.10.2" +version = "0.11.0" authors = ['Virto Team '] license = "GPL-3.0-only" homepage = 'https://github.com/virto-network/virto-node' diff --git a/pallets/communities-manager/Cargo.toml b/pallets/communities-manager/Cargo.toml new file mode 100644 index 00000000..40c64519 --- /dev/null +++ b/pallets/communities-manager/Cargo.toml @@ -0,0 +1,94 @@ +[package] +name = "pallet-communities-manager" +version = "0.1.0" +authors = ["Virto Team"] +description = "This pallet helps with all the necesary steps to correctly setup a community." +license = "MIT-0" +homepage = 'https://github.com/virto-network/virto-node' +repository = 'https://github.com/virto-network/virto-node' +edition = "2021" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +fc-traits-tracks = { workspace = true } + +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } + +pallet-communities = { workspace = true } +pallet-nfts = { workspace = true } +pallet-referenda = { workspace = true } + +log = { workspace = true } + +parity-scale-codec = { workspace = true, features = ["derive"] } +scale-info = { workspace = true, features = ["derive"] } + +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +[dev-dependencies] +sp-core = { workspace = true } +sp-io = { workspace = true } + +pallet-assets = { workspace = true } +pallet-balances = { workspace = true } +pallet-ranked-collective = { workspace = true } +pallet-referenda-tracks = { workspace = true } +pallet-scheduler = { workspace = true } +virto-common = { workspace = true, default-features = false, features = ["runtime"] } + +[features] +default = ["std", "testnet"] +testnet = [] +std = [ + "fc-traits-tracks/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "pallet-assets/std", + "pallet-balances/std", + "pallet-communities/std", + "pallet-nfts/std", + "pallet-ranked-collective/std", + "pallet-referenda-tracks/std", + "pallet-referenda/std", + "pallet-scheduler/std", + "parity-scale-codec/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "virto-common/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-communities/runtime-benchmarks", + "pallet-nfts/runtime-benchmarks", + "pallet-ranked-collective/runtime-benchmarks", + "pallet-referenda-tracks/runtime-benchmarks", + "pallet-referenda/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-assets/try-runtime", + "pallet-balances/try-runtime", + "pallet-nfts/try-runtime", + "pallet-ranked-collective/try-runtime", + "pallet-referenda-tracks/try-runtime", + "pallet-referenda/try-runtime", + "pallet-scheduler/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/pallets/communities-manager/src/benchmarking.rs b/pallets/communities-manager/src/benchmarking.rs new file mode 100644 index 00000000..39dd1f15 --- /dev/null +++ b/pallets/communities-manager/src/benchmarking.rs @@ -0,0 +1,65 @@ +//! Benchmarking setup for pallet-communities +use super::*; + +use frame_benchmarking::v2::*; + +use frame_support::traits::fungible::Mutate; +use frame_system::RawOrigin; +use sp_runtime::traits::StaticLookup; + +type RuntimeEventFor = ::RuntimeEvent; + +fn assert_has_event(generic_event: RuntimeEventFor) { + frame_system::Pallet::::assert_has_event(generic_event.into()); +} + +fn setup_account(who: &AccountIdOf) -> Result<(), BenchmarkError> +where + NativeBalanceOf: From, +{ + let initial_balance: NativeBalanceOf = 1_000_000_000_000_000u128.into(); + T::Balances::mint_into(who, initial_balance)?; + Ok(()) +} + +#[benchmarks( +where + RuntimeEventFor: From>, + NativeBalanceOf: From, + BlockNumberFor: From, + CommunityIdOf: From, +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn register() -> Result<(), BenchmarkError> { + // setup code + let first_member: AccountIdOf = frame_benchmarking::account("founder", 0, 0); + setup_account::(&first_member)?; + + let community_id: CommunityIdOf = 1.into(); + let admin_origin: RuntimeOriginFor = frame_system::Origin::::Signed(first_member.clone()).into(); + let admin_origin_caller: PalletsOriginOf = admin_origin.into_caller(); + + #[extrinsic_call] + _( + RawOrigin::Root, + community_id, + BoundedVec::truncate_from(b"Test Community".into()), + Some(admin_origin_caller.clone()), + None, + Some(T::Lookup::unlookup(first_member)), + ); + + // verification code + assert_has_event::(Event::::CommunityRegistered { id: community_id }.into()); + Ok(()) + } + + impl_benchmark_test_suite!( + Pallet, + sp_io::TestExternalities::new(Default::default()), + crate::mock::Test + ); +} diff --git a/pallets/communities-manager/src/lib.rs b/pallets/communities-manager/src/lib.rs new file mode 100644 index 00000000..0da41073 --- /dev/null +++ b/pallets/communities-manager/src/lib.rs @@ -0,0 +1,178 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +#[cfg(test)] +pub(crate) mod mock; +#[cfg(test)] +mod tests; + +pub mod weights; +pub use weights::*; + +use fc_traits_tracks::MutateTracks; +use frame_support::{ + pallet_prelude::*, + traits::{nonfungibles_v2::Create, OriginTrait, RankedMembers}, +}; +use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; +use pallet_communities::{ + types::{ + AccountIdLookupOf, AccountIdOf, CommunityIdOf, DecisionMethodFor, NativeBalanceOf, PalletsOriginOf, + RuntimeOriginFor, + }, + Origin as CommunityOrigin, +}; +use pallet_nfts::CollectionConfig; +use pallet_referenda::{TrackInfo, TracksInfo}; + +type TrackInfoOf = TrackInfo, BlockNumberFor>; + +#[frame_support::pallet] +pub mod pallet { + use sp_runtime::str_array; + + use super::*; + + type CommunityName = BoundedVec>; + + /// Configure the pallet by specifying the parameters and types on which it + /// depends. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_communities::Config { + /// Because this pallet emits events, it depends on the runtime's + /// definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + type CreateCollection: Create< + AccountIdOf, + CollectionConfig, BlockNumberFor, CommunityIdOf>, + CollectionId = CommunityIdOf, + >; + + type Tracks: TracksInfo, BlockNumberFor> + + MutateTracks< + NativeBalanceOf, + BlockNumberFor, + Id = CommunityIdOf, + RuntimeOrigin = PalletsOriginOf, + >; + + type RankedCollective: RankedMembers>; + + /// Type representing the weight of this pallet + type WeightInfo: WeightInfo; + + // #[cfg(feature = "runtime-benchmarks")] + // type BenchmarkHelper: BenchmarkHelper; + } + + #[pallet::pallet] + pub struct Pallet(_); + + // Pallets use events to inform users when important changes are made. + // https://docs.substrate.io/main-docs/build/events-errors/ + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// The community with [`CommmunityId`](pallet_communities::CommunityId) + /// has been created. + CommunityRegistered { id: T::CommunityId }, + } + + // Errors inform users that something worked or went wrong. + #[pallet::error] + pub enum Error { + /// Community name didn't contain valid utf8 characters + InvalidCommunityName, + /// It was not possible to register the community + CannotRegister, + } + + // Dispatchable functions allows users to interact with the pallet and invoke + // state changes. These functions materialize as "extrinsics", which are often + // compared to transactions. Dispatchable functions must be annotated with a + // weight and must return a DispatchResult. + #[pallet::call(weight(::WeightInfo))] + impl Pallet { + #[pallet::call_index(0)] + pub fn register( + origin: OriginFor, + community_id: CommunityIdOf, + name: CommunityName, + maybe_admin_origin: Option>, + maybe_decision_method: Option>, + _maybe_first_member: Option>, + ) -> DispatchResult { + let maybe_deposit = T::CreateOrigin::ensure_origin(origin)?; + + let community_name = core::str::from_utf8(&name).map_err(|_| Error::::InvalidCommunityName)?; + let community_origin: RuntimeOriginFor = CommunityOrigin::::new(community_id).into(); + let admin_origin = maybe_admin_origin.unwrap_or(community_origin.clone().into_caller()); + // Register first to check if community exists + pallet_communities::Pallet::::register(&admin_origin, &community_id, maybe_deposit)?; + + if let Some(decision_method) = maybe_decision_method { + pallet_communities::Pallet::::set_decision_method( + admin_origin.clone().into(), + community_id, + decision_method, + )?; + } + + let community_account = pallet_communities::Pallet::::community_account(&community_id); + + // Create memberships collection for community + T::CreateCollection::create_collection_with_id( + community_id, + &community_account, + &community_account, + &CollectionConfig { + settings: Default::default(), + max_supply: None, + mint_settings: Default::default(), + }, + )?; + + // Create governance track for community + T::Tracks::insert( + community_id, + Self::default_tack(community_name), + community_origin.into_caller(), + )?; + // Induct community at Kreivo Governance with rank 1 + T::RankedCollective::induct(&community_account)?; + + Self::deposit_event(Event::::CommunityRegistered { id: community_id }); + Ok(()) + } + } + + impl Pallet { + fn default_tack(name: &str) -> TrackInfoOf { + use sp_runtime::Perbill; + TrackInfo { + name: str_array(name), + max_deciding: 1, + decision_deposit: 0u8.into(), + prepare_period: 1u8.into(), + decision_period: u8::MAX.into(), + confirm_period: 1u8.into(), + min_enactment_period: 1u8.into(), + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + } + } + } +} diff --git a/pallets/communities-manager/src/mock/collective.rs b/pallets/communities-manager/src/mock/collective.rs new file mode 100644 index 00000000..69a70347 --- /dev/null +++ b/pallets/communities-manager/src/mock/collective.rs @@ -0,0 +1,86 @@ +use super::*; + +use pallet_referenda::{impl_tracksinfo_get, Track}; +use sp_runtime::{str_array as s, Perbill}; +use sp_std::borrow::Cow; + +pub type TrackId = u16; + +pub type CollectiveReferendaInstance = pallet_referenda::Instance1; +impl pallet_referenda::Config for Test { + type WeightInfo = pallet_referenda::weights::SubstrateWeight; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + // Communities can submit proposals. + type SubmitOrigin = AsEnsureOriginWithArg>; + type CancelOrigin = EnsureRoot; + type KillOrigin = EnsureRoot; + type Slash = (); + type Votes = pallet_ranked_collective::Votes; + type Tally = pallet_ranked_collective::TallyOf; + type SubmissionDeposit = ConstU128<2>; + type MaxQueued = ConstU32<3>; + type UndecidingTimeout = ConstU64<20>; + type AlarmInterval = AlarmInterval; + type Tracks = TracksInfo; + type Preimages = (); +} + +pub type CollectiveInstance = pallet_ranked_collective::Instance1; +impl pallet_ranked_collective::Config for Test { + type WeightInfo = pallet_ranked_collective::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + + type PromoteOrigin = EnsureRootWithSuccess>; + type DemoteOrigin = EnsureRootWithSuccess>; + type Polls = CollectiveReferenda; + type MinRankOfClass = (); + type VoteWeight = pallet_ranked_collective::Linear; +} + +pub struct TracksInfo; +impl pallet_referenda::TracksInfo> for TracksInfo { + type Id = TrackId; + type RuntimeOrigin = ::PalletsOrigin; + type TracksIter = pallet_referenda::StaticTracksIter>; + + fn tracks() -> Self::TracksIter { + const DATA: [pallet_referenda::Track>; 1] = [Track { + id: 0, + info: pallet_referenda::TrackInfo { + name: s("Root"), + max_deciding: 1, + decision_deposit: 0, + prepare_period: 1, + decision_period: 4, + confirm_period: 1, + min_enactment_period: 1, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(90), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(100), + }, + }, + }]; + DATA.iter().map(Cow::Borrowed) + } + + fn track_for(id: &Self::RuntimeOrigin) -> Result { + if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) { + match system_origin { + frame_system::RawOrigin::Root => Ok(0), + _ => Err(()), + } + } else { + Err(()) + } + } +} +impl_tracksinfo_get!(TracksInfo, Balance, BlockNumberFor); diff --git a/pallets/communities-manager/src/mock/mod.rs b/pallets/communities-manager/src/mock/mod.rs new file mode 100644 index 00000000..3f0de264 --- /dev/null +++ b/pallets/communities-manager/src/mock/mod.rs @@ -0,0 +1,247 @@ +use super::*; + +use frame_support::{ + parameter_types, + traits::{ + AsEnsureOriginWithArg, ConstU128, ConstU16, ConstU32, ConstU64, EitherOf, EqualPrivilegeOnly, Everything, + }, + PalletId, +}; +use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned}; +use pallet_communities::{origin::EnsureCommunity, Tally, VoteWeight}; +use parity_scale_codec::Compact; +use sp_core::H256; +use sp_io::TestExternalities; +use sp_runtime::{ + traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, + MultiSignature, +}; +pub use virto_common::{CommunityId, MembershipId}; + +pub use crate as pallet_communities_manager; + +mod collective; +mod weights; +pub use weights::*; + +#[cfg(feature = "runtime-benchmarks")] +mod runtime_benchmarks; +#[cfg(feature = "runtime-benchmarks")] +use runtime_benchmarks::*; + +type Block = frame_system::mocking::MockBlock; +type WeightInfo = (); + +pub type AccountPublic = ::Signer; +pub type AccountId = ::AccountId; +pub type Balance = u128; +pub type AssetId = u32; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Assets: pallet_assets, + Balances: pallet_balances, + CollectiveReferenda: pallet_referenda::, + Collective: pallet_ranked_collective::, + Scheduler: pallet_scheduler, + Referenda: pallet_referenda, + Tracks: pallet_referenda_tracks, + Memberships: pallet_nfts, + Communities: pallet_communities, + CommunitiesManager: pallet_communities_manager, + } +); + +parameter_types! { + pub const RootAccount: AccountId = AccountId::new([0xff; 32]); +} +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = ConstU16<42>; + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +impl pallet_balances::Config for Test { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; + type WeightInfo = WeightInfo; + type MaxLocks = ConstU32<10>; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = RuntimeFreezeReason; + type FreezeIdentifier = RuntimeHoldReason; + type MaxHolds = ConstU32<10>; + type MaxFreezes = ConstU32<10>; +} + +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = AssetId; + type AssetIdParameter = Compact; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = ConstU128<100>; + type AssetAccountDeposit = ConstU128<1>; + type MetadataDepositBase = ConstU128<10>; + type MetadataDepositPerByte = ConstU128<1>; + type ApprovalDeposit = ConstU128<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type Extra = (); + type CallbackHandle = (); + type WeightInfo = WeightInfo; + type RemoveItemsLimit = ConstU32<1000>; + type RuntimeHoldReason = RuntimeHoldReason; + type MaxHolds = ConstU32<10>; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +impl pallet_scheduler::Config for Test { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type OriginPrivilegeCmp = EqualPrivilegeOnly; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type Preimages = (); +} + +parameter_types! { + pub static AlarmInterval: u64 = 1; + pub const MaxTracks: u32 = u32::MAX; +} + +impl pallet_referenda::Config for Test { + type WeightInfo = (); + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + type SubmitOrigin = EnsureSigned; + type CancelOrigin = EnsureRoot; + type KillOrigin = EnsureRoot; + type Slash = (); + type Votes = VoteWeight; + type Tally = Tally; + type SubmissionDeposit = ConstU128<2>; + type MaxQueued = ConstU32<3>; + type UndecidingTimeout = ConstU64<20>; + type AlarmInterval = AlarmInterval; + type Tracks = Tracks; + type Preimages = (); +} + +impl pallet_referenda_tracks::Config for Test { + type RuntimeEvent = RuntimeEvent; + type TrackId = CommunityId; + type MaxTracks = MaxTracks; + type AdminOrigin = EnsureRoot; + type UpdateOrigin = EnsureRoot; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = TracksBenchmarkHelper; +} + +parameter_types! { + pub const CommunitiesPalletId: PalletId = PalletId(*b"kv/comms"); + pub const MembershipsManagerCollectionId: CommunityId = 0; + pub const MembershipNftAttr: &'static [u8; 10] = b"membership"; + pub const TestCommunity: CommunityId = 1; + pub const NoDepositOnRootRegistration: Option<(Balance, AccountId, AccountId)> = None; +} + +impl pallet_nfts::Config for Test { + type ApprovalsLimit = (); + type AttributeDepositBase = (); + type CollectionDeposit = (); + type CollectionId = CommunityId; + type CreateOrigin = + AsEnsureOriginWithArg, EnsureSigned>>; + type Currency = Balances; + type DepositPerByte = (); + type Features = (); + type ForceOrigin = EnsureRoot; + type ItemAttributesApprovalsLimit = (); + type ItemDeposit = (); + type ItemId = MembershipId; + type KeyLimit = ConstU32<64>; + type Locker = (); + type MaxAttributesPerCall = (); + type MaxDeadlineDuration = (); + type MaxTips = (); + type MetadataDepositBase = (); + type OffchainPublic = AccountPublic; + type OffchainSignature = MultiSignature; + type RuntimeEvent = RuntimeEvent; + type StringLimit = (); + type ValueLimit = ConstU32<10>; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); +} + +impl pallet_communities::Config for Test { + type PalletId = CommunitiesPalletId; + type CommunityId = CommunityId; + type MembershipId = MembershipId; + type Assets = Assets; + type Balances = Balances; + type MemberMgmt = Memberships; + type Polls = Referenda; + type CreateOrigin = EnsureRootWithSuccess; + type AdminOrigin = EnsureCommunity; + type MemberMgmtOrigin = EnsureCommunity; + type RuntimeCall = RuntimeCall; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = CommunityBenchmarkHelper; +} + +impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type CreateCollection = Memberships; + type Tracks = Tracks; + type RankedCollective = Collective; + type WeightInfo = WeightInfo; +} + +#[allow(dead_code)] +fn new_test_ext() -> TestExternalities { + TestExternalities::new(Default::default()) +} diff --git a/pallets/communities-manager/src/mock/runtime_benchmarks.rs b/pallets/communities-manager/src/mock/runtime_benchmarks.rs new file mode 100644 index 00000000..57197b08 --- /dev/null +++ b/pallets/communities-manager/src/mock/runtime_benchmarks.rs @@ -0,0 +1,52 @@ +use super::*; + +use frame_benchmarking::v2::BenchmarkError; +use frame_system::pallet_prelude::{OriginFor, RuntimeCallFor}; +use sp_runtime::SaturatedConversion; + +use pallet_communities::{CommunityIdOf, MembershipIdOf, PollIndexOf}; +use pallet_referenda::PalletsOriginOf; +use pallet_referenda_tracks::TrackIdOf; + +pub struct TracksBenchmarkHelper; + +impl pallet_referenda_tracks::BenchmarkHelper for TracksBenchmarkHelper { + fn track_id(id: u32) -> TrackIdOf { + id.saturated_into() + } +} + +pub struct CommunityBenchmarkHelper; + +impl pallet_communities::BenchmarkHelper for CommunityBenchmarkHelper { + fn community_id() -> CommunityIdOf { + 1 + } + + fn initialize_memberships_collection() -> Result<(), frame_benchmarking::BenchmarkError> { + unimplemented!() + } + + fn issue_membership( + _: CommunityIdOf, + _: MembershipIdOf, + ) -> Result<(), frame_benchmarking::BenchmarkError> { + unimplemented!() + } + + fn prepare_track(_: pallet_communities::PalletsOriginOf) -> Result<(), BenchmarkError> { + unimplemented!() + } + + fn prepare_poll( + _: OriginFor, + _: PalletsOriginOf, + _: RuntimeCallFor, + ) -> Result, BenchmarkError> { + unimplemented!() + } + + fn finish_poll(_: PollIndexOf) -> Result<(), BenchmarkError> { + unimplemented!() + } +} diff --git a/pallets/communities-manager/src/mock/weights.rs b/pallets/communities-manager/src/mock/weights.rs new file mode 100644 index 00000000..a8241a09 --- /dev/null +++ b/pallets/communities-manager/src/mock/weights.rs @@ -0,0 +1,23 @@ +use frame_support::{ + parameter_types, + weights::{ + constants::{WEIGHT_REF_TIME_PER_NANOS, WEIGHT_REF_TIME_PER_SECOND}, + Weight, + }, +}; +use sp_runtime::Perbill; + +pub const MAX_BLOCK_REF_TIME: u64 = WEIGHT_REF_TIME_PER_SECOND.saturating_div(2); // https://github.com/paritytech/cumulus/blob/98e68bd54257b4039a5d5b734816f4a1b7c83a9d/parachain-template/runtime/src/lib.rs#L221 +pub const MAX_BLOCK_POV_SIZE: u64 = 5 * 1024 * 1024; // https://github.com/paritytech/polkadot/blob/ba1f65493d91d4ab1787af2fd6fe880f1da90586/primitives/src/v4/mod.rs#L384 +pub const MAX_BLOCK_WEIGHT: Weight = Weight::from_parts(MAX_BLOCK_REF_TIME, MAX_BLOCK_POV_SIZE); +// max extrinsics: 75% of block +pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); // https://github.com/paritytech/cumulus/blob/d20c4283fe85df0c1ef8cb7c9eb7c09abbcbfa31/parachain-template/runtime/src/lib.rs#L218 + // max extrinsic: max total extrinsics less average on_initialize ratio and less + // base extrinsic weight +pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); // https://github.com/paritytech/cumulus/blob/d20c4283fe85df0c1ef8cb7c9eb7c09abbcbfa31/parachain-template/runtime/src/lib.rs#L214 +pub const BASE_EXTRINSIC: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(125_000), 0); // https://github.com/paritytech/cumulus/blob/d20c4283fe85df0c1ef8cb7c9eb7c09abbcbfa31/parachain-template/runtime/src/weights/extrinsic_weights.rs#L26 + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Weight::from_parts(MAX_BLOCK_REF_TIME, MAX_BLOCK_POV_SIZE); + pub const MaxScheduledPerBlock: u32 = 512; +} diff --git a/pallets/communities-manager/src/tests.rs b/pallets/communities-manager/src/tests.rs new file mode 100644 index 00000000..a731f1cf --- /dev/null +++ b/pallets/communities-manager/src/tests.rs @@ -0,0 +1,44 @@ +use crate::{ + mock::*, + weights::{SubstrateWeight, WeightInfo}, +}; +use frame_support::weights::Weight; + +#[test] +fn weights() { + let max_total_extrinsics = MAX_BLOCK_WEIGHT * NORMAL_DISPATCH_RATIO; + let max_extrinsic_weight = max_total_extrinsics + .saturating_sub(MAX_BLOCK_WEIGHT * AVERAGE_ON_INITIALIZE_RATIO) + .saturating_sub(BASE_EXTRINSIC); + + assert_eq!(max_extrinsic_weight, Weight::from_parts(349_875_000_000, 3_670_016)); + + println!("max block weight: {MAX_BLOCK_WEIGHT}"); + println!("max total extrinsics weight: {max_total_extrinsics}"); + println!("max extrinsic weight: {max_extrinsic_weight}\n"); + + let mut total = Weight::zero(); + + let calls = vec![("register", SubstrateWeight::::register())]; + + for (function, weight) in calls { + println!("{function}: {weight:?}",); + println!( + "\tpercentage of max extrinsic weight: {:.2}% (ref_time), {:.2}% (proof_size)", + (weight.ref_time() as f64 / max_extrinsic_weight.ref_time() as f64) * 100.0, + (weight.proof_size() as f64 / max_extrinsic_weight.proof_size() as f64) * 100.0, + ); + println!( + "\tmax tx per block: {} (ref_time), {} (proof_size)", + max_extrinsic_weight.ref_time() / weight.ref_time(), + max_extrinsic_weight.proof_size() / weight.proof_size().max(1) + ); + + assert!(weight.all_lt(max_extrinsic_weight)); + + total += weight; + } + + // output total weight, useful for evaluating net weight changes when optimising + println!("\ntotal weight: {total:?}"); +} diff --git a/pallets/communities-manager/src/weights.rs b/pallets/communities-manager/src/weights.rs new file mode 100644 index 00000000..8742e860 --- /dev/null +++ b/pallets/communities-manager/src/weights.rs @@ -0,0 +1,29 @@ +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for pallet_communities. +pub trait WeightInfo { + fn register() -> Weight; +} + +/// Weights for pallet_communities using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn register() -> Weight { + Weight::from_parts(18_000_000, 4087) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } +} + +impl WeightInfo for () { + fn register() -> Weight { + Weight::from_parts(18_000_000, 4087) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } +} \ No newline at end of file diff --git a/pallets/communities/README.md b/pallets/communities/README.md index 704ce9a2..2c337c88 100644 --- a/pallets/communities/README.md +++ b/pallets/communities/README.md @@ -76,9 +76,7 @@ Calling these functions requires being a member of the community. These functions can be called either by the community _admin_ or dispatched through an approved proposal. ! -- [`set_metadata`][c01]: Sets some [`CommunityMetadata`][t01] to describe - the -community. + - [`remove_member`][c03]: Removes an account as a community member. While enrolling a member into the community can be an action taken by any member, the decision to remove a member should not be taken arbitrarily by @@ -102,13 +100,9 @@ community. [3]: https://docs.substrate.io/reference/glossary/#existential-deposit [t00]: `Config::CommunityId` -[t01]: `types::CommunityMetadata` [c00]: `crate::Pallet::create` -[c01]: `crate::Pallet::set_metadata` [c02]: `crate::Pallet::add_member` [c03]: `crate::Pallet::remove_member` [g00]: `crate::Pallet::community` [g01]: `crate::Pallet::metadata` -[g02]: `crate::Pallet::membership` -[g03]: `crate::Pallet::members_count` diff --git a/pallets/communities/src/benchmarking.rs b/pallets/communities/src/benchmarking.rs index 6ba6f691..542b0f22 100644 --- a/pallets/communities/src/benchmarking.rs +++ b/pallets/communities/src/benchmarking.rs @@ -5,19 +5,16 @@ use super::*; use self::{ origin::DecisionMethod, types::{ - AccountIdOf, CommunityIdOf, DecisionMethodFor, MembershipIdOf, NativeBalanceOf, PalletsOriginOf, PollIndexOf, - RuntimeCallFor, Vote, + AccountIdOf, AssetIdOf, CommunityIdOf, DecisionMethodFor, MembershipIdOf, NativeBalanceOf, PalletsOriginOf, + PollIndexOf, RuntimeCallFor, Vote, }, CommunityDecisionMethod, Event, HoldReason, Pallet as Communities, }; use fc_traits_memberships::{Inspect, Rank}; use frame_benchmarking::v2::*; -use frame_support::{ - traits::{ - fungible::{InspectFreeze, Mutate}, - OriginTrait, - }, - BoundedVec, +use frame_support::traits::{ + fungible::{InspectFreeze, Mutate}, + OriginTrait, }; use frame_system::{ pallet_prelude::{BlockNumberFor, OriginFor}, @@ -85,7 +82,7 @@ where community_params::(maybe_decision_method); Pallet::::create(origin.clone(), admin_origin_caller, community_id)?; - Pallet::::set_decision_method(origin, community_id, decision_method)?; + Pallet::::set_decision_method(admin_origin.clone(), community_id, decision_method)?; Ok((community_id, admin_origin)) } @@ -139,8 +136,9 @@ where #[benchmarks( where T: frame_system::Config + crate::Config, - OriginFor: From>, + OriginFor: From> + From>, RuntimeEventFor: From>, + AssetIdOf: From, MembershipIdOf: From, BlockNumberFor: From )] @@ -160,20 +158,28 @@ mod benchmarks { } #[benchmark] - fn set_metadata(n: Linear<1, 64>, d: Linear<1, 256>, u: Linear<1, 256>) -> Result<(), BenchmarkError> { + fn set_admin_origin() -> Result<(), BenchmarkError> { // setup code - let (id, _, _, admin_origin) = community_params::(None); - Communities::::create(RawOrigin::Root.into(), admin_origin, id)?; + let (id, _, _, community_origin) = community_params::(None); + + let community_account = Communities::::community_account(&id); + let signed_origin: ::RuntimeOrigin = RawOrigin::Signed(community_account.clone()).into(); + let signed_origin_caller: PalletsOriginOf = signed_origin.into_caller(); - let name = Some(BoundedVec::truncate_from(vec![0u8; n as usize])); - let description = Some(BoundedVec::truncate_from(vec![0u8; d as usize])); - let url = Some(BoundedVec::truncate_from(vec![0u8; u as usize])); + Communities::::create(RawOrigin::Root.into(), signed_origin_caller, id)?; #[extrinsic_call] - _(RawOrigin::Root, id, name.clone(), description.clone(), url.clone()); + _(RawOrigin::Signed(community_account), community_origin.clone()); // verification code - assert_has_event::(Event::MetadataSet { id, name }.into()); + assert_eq!(CommunityIdFor::::get(community_origin.clone()), Some(id)); + assert_has_event::( + Event::AdminOriginSet { + id, + origin: community_origin, + } + .into(), + ); Ok(()) } @@ -182,12 +188,12 @@ mod benchmarks { fn set_decision_method() -> Result<(), BenchmarkError> { // setup code let (id, decision_method, _, admin_origin) = community_params::(None); - Communities::::create(RawOrigin::Root.into(), admin_origin, id)?; + Communities::::create(RawOrigin::Root.into(), admin_origin.clone(), id)?; CommunityDecisionMethod::::set(id, decision_method); #[extrinsic_call] _( - RawOrigin::Root, + admin_origin, id, DecisionMethod::CommunityAsset(T::BenchmarkHelper::community_asset_id()), ); @@ -393,7 +399,7 @@ mod benchmarks { )?; assert_eq!( - T::Balances::balance_frozen(&HoldReason::VoteCasted(0u32).into(), &who), + T::Balances::balance_frozen(&HoldReason::VoteCasted.into(), &who), 1u32.into() ); @@ -404,7 +410,7 @@ mod benchmarks { // verification code assert_eq!( - T::Balances::balance_frozen(&HoldReason::VoteCasted(0u32).into(), &who), + T::Balances::balance_frozen(&HoldReason::VoteCasted.into(), &who), 0u32.into() ); diff --git a/pallets/communities/src/functions.rs b/pallets/communities/src/functions.rs index 3f29bbb5..08aa8355 100644 --- a/pallets/communities/src/functions.rs +++ b/pallets/communities/src/functions.rs @@ -1,25 +1,21 @@ -use crate::{ - origin::DecisionMethod, - types::{ - AccountIdOf, CommunityIdOf, CommunityInfo, CommunityState, ConstSizedField, MembershipIdOf, PalletsOriginOf, - PollIndexOf, RuntimeCallFor, Tally, Vote, VoteOf, VoteWeight, - }, - CommunityDecisionMethod, CommunityIdFor, CommunityVotes, Config, Error, HoldReason, Info, Metadata, Pallet, -}; +use super::{origin::DecisionMethod, *}; use fc_traits_memberships::{GenericRank, Inspect, Rank}; use frame_support::{ dispatch::PostDispatchInfo, fail, pallet_prelude::*, traits::{ - fungible::MutateFreeze as FunMutateFreeze, fungibles::MutateHold as FunsMutateHold, tokens::Precision, Polling, + fungible::{Mutate, MutateFreeze}, + fungibles::{InspectHold, MutateHold}, + tokens::Precision, + Polling, }, }; use sp_runtime::{ traits::{AccountIdConversion, Dispatchable}, DispatchResultWithInfo, TokenError, }; -use sp_std::vec::Vec; +use sp_std::{vec, vec::Vec}; impl Pallet { #[inline] @@ -28,7 +24,7 @@ impl Pallet { } pub fn community_exists(community_id: &T::CommunityId) -> bool { - Self::community(community_id).is_some() + Info::::contains_key(community_id) } pub fn is_member(community_id: &T::CommunityId, who: &AccountIdOf) -> bool { @@ -52,9 +48,23 @@ impl Pallet { /// Stores an initial info about the community /// Sets the caller as the community admin, the initial community state /// to its default value(awaiting) - pub(crate) fn do_register_community(admin: &PalletsOriginOf, community_id: &T::CommunityId) -> DispatchResult { - if Self::community_exists(community_id) { - fail!(Error::::CommunityAlreadyExists); + pub fn register( + admin: &PalletsOriginOf, + community_id: &CommunityIdOf, + maybe_deposit: Option<(NativeBalanceOf, AccountIdOf, AccountIdOf)>, + ) -> DispatchResult { + ensure!( + !Self::community_exists(community_id), + Error::::CommunityAlreadyExists + ); + + if let Some((deposit, depositor, depositee)) = maybe_deposit { + T::Balances::transfer( + &depositor, + &depositee, + deposit, + frame_support::traits::tokens::Preservation::Preserve, + )?; } CommunityIdFor::::insert(admin, community_id); @@ -64,35 +74,14 @@ impl Pallet { Ok(()) } - pub(crate) fn do_set_metadata( - community_id: &CommunityIdOf, - name: &Option>, - description: Option>, - url: Option>, - ) { - Metadata::::mutate(community_id, |metadata| { - if let Some(name) = name { - metadata.name = name.clone(); - } - if let Some(desc) = description { - metadata.description = desc; - } - if let Some(url) = url { - metadata.main_url = url; - } - }) - } - - pub(crate) fn do_vote( + pub(crate) fn try_vote( who: &AccountIdOf, membership_id: MembershipIdOf, poll_index: PollIndexOf, vote: &VoteOf, ) -> DispatchResult { ensure!(VoteWeight::from(vote).gt(&0), TokenError::BelowMinimum); - let Some(community_id) = T::MemberMgmt::check_membership(who, &membership_id) else { - fail!(Error::::NotAMember); - }; + let community_id = T::MemberMgmt::check_membership(who, &membership_id).ok_or(Error::::NotAMember)?; T::Polls::try_access_poll(poll_index, |poll_status| { let (tally, class) = poll_status.ensure_ongoing().ok_or(Error::::NotOngoing)?; @@ -106,11 +95,6 @@ impl Pallet { .into(), _ => 1, }; - if let Some(vote) = Self::community_vote_of(who, poll_index) { - Self::do_unlock_for_vote(who, &poll_index, &vote)?; - let vote_weight = VoteWeight::from(&vote); - tally.remove_vote(vote.say(), vote_multiplier * vote_weight, vote_weight); - } let say = *match (vote, decision_method) { (Vote::AssetBalance(say, asset, ..), DecisionMethod::CommunityAsset(a)) if *asset == a => say, @@ -122,76 +106,94 @@ impl Pallet { let vote_weight = VoteWeight::from(vote); tally.add_vote(say, vote_multiplier * vote_weight, vote_weight); - Self::do_lock_for_vote(who, &poll_index, vote) + CommunityVotes::::insert(poll_index, membership_id, (vote, who)); + Self::update_locks(who, poll_index, vote, LockUpdateType::Add) }) } - pub(crate) fn do_remove_vote( + pub(crate) fn try_remove_vote( who: &AccountIdOf, membership_id: MembershipIdOf, poll_index: PollIndexOf, ) -> DispatchResult { - let Some(community_id) = T::MemberMgmt::check_membership(who, &membership_id) else { - fail!(Error::::NotAMember); - }; + let community_id = T::MemberMgmt::check_membership(who, &membership_id).ok_or(Error::::NotAMember)?; T::Polls::try_access_poll(poll_index, |poll_status| { - let Some((tally, class)) = poll_status.ensure_ongoing() else { - fail!(Error::::NotOngoing); - }; + let (tally, class) = poll_status.ensure_ongoing().ok_or(Error::::NotOngoing)?; ensure!(community_id == class, Error::::InvalidTrack); - let vote = Self::community_vote_of(who, poll_index).ok_or(Error::::NoVoteCasted)?; + let (vote, voter) = CommunityVotes::::get(poll_index, membership_id).ok_or(Error::::NoVoteCasted)?; let vote_multiplier = match CommunityDecisionMethod::::get(community_id) { DecisionMethod::Rank => T::MemberMgmt::rank_of(&community_id, &membership_id) .unwrap_or_default() .into(), _ => 1, }; + let vote_weight = VoteWeight::from(&vote); tally.remove_vote(vote.say(), vote_multiplier * vote_weight, vote_weight); - let reason = HoldReason::VoteCasted(poll_index).into(); - CommunityVotes::::remove(who, poll_index); - - match vote { - Vote::AssetBalance(_, asset_id, amount) => { - T::Assets::release(asset_id.clone(), &reason, who, amount, Precision::BestEffort).map(|_| ()) - } - Vote::NativeBalance(..) => T::Balances::thaw(&reason, who), - _ => Ok(()), - } + CommunityVotes::::remove(poll_index, membership_id); + Self::update_locks(&voter, poll_index, &vote, LockUpdateType::Remove) }) } - fn do_lock_for_vote(who: &AccountIdOf, poll_index: &PollIndexOf, vote: &VoteOf) -> DispatchResult { - let reason = HoldReason::VoteCasted(*poll_index).into(); - CommunityVotes::::insert(who, poll_index, vote.clone()); - - match vote { - Vote::AssetBalance(_, asset_id, amount) => T::Assets::hold(asset_id.clone(), &reason, who, *amount), - Vote::NativeBalance(_, amount) => { - T::Balances::set_frozen(&reason, who, *amount, frame_support::traits::tokens::Fortitude::Polite) - } - _ => Ok(()), - } - } - - pub(crate) fn do_unlock_for_vote( + pub(crate) fn update_locks( who: &AccountIdOf, - poll_index: &PollIndexOf, + poll_index: PollIndexOf, vote: &VoteOf, + update_type: LockUpdateType, ) -> DispatchResult { - let reason = HoldReason::VoteCasted(*poll_index).into(); - CommunityVotes::::remove(who, poll_index); + use sp_runtime::traits::Zero; + let reason = HoldReason::VoteCasted.into(); + + // 1. Define locks + let mut assets_locked_amount: Vec<(AssetIdOf, AssetBalanceOf)> = vec![]; + let mut native_locked_amount: NativeBalanceOf = Zero::zero(); - match vote { - Vote::AssetBalance(_, asset_id, amount) => { - T::Assets::release(asset_id.clone(), &reason, who, *amount, Precision::BestEffort).map(|_| ()) + // 1a. Define possibly asset to void + if let Vote::AssetBalance(_, asset_id, _) = vote { + assets_locked_amount.push((asset_id.clone(), Zero::zero())); + } + + match update_type { + LockUpdateType::Add => CommunityVoteLocks::::insert(who, poll_index, vote), + LockUpdateType::Remove => CommunityVoteLocks::::remove(who, poll_index), + } + + for locked_vote in CommunityVoteLocks::::iter_prefix_values(who) { + match locked_vote { + Vote::AssetBalance(_, asset_id, amount) => { + if let Some((_, locked_amount)) = + assets_locked_amount.iter_mut().find(|(asset, _)| asset == &asset_id) + { + *locked_amount = (*locked_amount).max(amount); + } else { + assets_locked_amount.push((asset_id.clone(), amount)); + } + } + Vote::NativeBalance(_, amount) => native_locked_amount = native_locked_amount.max(amount), + _ => (), } - Vote::NativeBalance(..) => T::Balances::thaw(&reason, who), - _ => Err(Error::::NoLocksInPlace.into()), } + + // 3. Apply locks + for (asset, amount) in assets_locked_amount.iter() { + let held_balance = T::Assets::balance_on_hold(asset.clone(), &reason, who); + if held_balance.gt(&Zero::zero()) { + T::Assets::release(asset.clone(), &reason, who, held_balance, Precision::Exact)?; + } + T::Assets::hold(asset.clone(), &reason, who, *amount)?; + } + + T::Balances::set_frozen( + &reason, + who, + native_locked_amount, + frame_support::traits::tokens::Fortitude::Polite, + )?; + + Ok(()) } pub(crate) fn do_dispatch_as_community_account( diff --git a/pallets/communities/src/lib.rs b/pallets/communities/src/lib.rs index 2e161a12..9524f2ee 100644 --- a/pallets/communities/src/lib.rs +++ b/pallets/communities/src/lib.rs @@ -77,9 +77,6 @@ //! //! These functions can be called either by the community _admin_ or //! dispatched through an approved proposal. ! -//! - [`set_metadata`][c01]: Sets some [`CommunityMetadata`][t01] to describe -//! the -//! community. //! - [`remove_member`][c03]: Removes an account as a community member. While //! enrolling a member into the community can be an action taken by any //! member, the decision to remove a member should not be taken arbitrarily by @@ -130,8 +127,11 @@ mod functions; mod impls; pub mod types; +pub use types::*; + pub mod weights; pub use weights::*; + pub mod origin; #[frame_support::pallet] @@ -145,10 +145,10 @@ pub mod pallet { traits::{fungible, fungibles, EnsureOrigin, IsSubType, OriginTrait, Polling}, Blake2_128Concat, Parameter, }; - use frame_system::pallet_prelude::{OriginFor, *}; + use frame_system::pallet_prelude::{ensure_signed, BlockNumberFor, OriginFor}; use sp_runtime::traits::{Dispatchable, StaticLookup}; use sp_std::prelude::Box; - use types::{PollIndexOf, RuntimeCallFor, RuntimeOriginFor, *}; + const ONE: NonZeroU8 = NonZeroU8::MIN; #[pallet::pallet] @@ -170,8 +170,13 @@ pub mod pallet { + membership::Manager, Membership = MembershipIdOf> + membership::Rank, Membership = MembershipIdOf>; - /// Origin authorized to manage the state of a community - type CommunityMgmtOrigin: EnsureOrigin>; + type CreateOrigin: EnsureOrigin< + OriginFor, + Success = Option<(NativeBalanceOf, AccountIdOf, AccountIdOf)>, + >; + + /// Origin authorized to administer an active community + type AdminOrigin: EnsureOrigin, Success = Self::CommunityId>; /// Origin authorized to manage memeberships of an active community type MemberMgmtOrigin: EnsureOrigin, Success = Self::CommunityId>; @@ -186,6 +191,7 @@ pub mod pallet { /// Type represents interactions between fungibles (i.e. assets) type Assets: fungibles::Inspect + + fungibles::hold::Inspect + fungibles::hold::Mutate; /// Type represents interactions between fungible tokens (native token) @@ -236,26 +242,19 @@ pub mod pallet { #[pallet::composite_enum] pub enum HoldReason { // A vote has been casted on a poll - VoteCasted(u32), + VoteCasted, } /// Stores the basic information of the community. If a value exists for a /// specified [`ComumunityId`][`Config::CommunityId`], this means a /// community exists. #[pallet::storage] - #[pallet::getter(fn community)] pub(super) type Info = StorageMap<_, Blake2_128Concat, CommunityIdOf, CommunityInfo>; /// List of origins and how they map to communities #[pallet::storage] pub(super) type CommunityIdFor = StorageMap<_, Blake2_128Concat, PalletsOriginOf, CommunityIdOf>; - /// Stores the metadata regarding a community. - #[pallet::storage] - #[pallet::getter(fn metadata)] - pub(super) type Metadata = - StorageMap<_, Blake2_128Concat, CommunityIdOf, CommunityMetadata, ValueQuery>; - /// Stores the decision method for a community #[pallet::storage] pub(super) type CommunityDecisionMethod = @@ -263,8 +262,18 @@ pub mod pallet { /// Stores the list of votes for a community. #[pallet::storage] - #[pallet::getter(fn community_vote_of)] - pub(super) type CommunityVotes = + pub(super) type CommunityVotes = StorageDoubleMap< + _, + Blake2_128Concat, + PollIndexOf, + Blake2_128Concat, + MembershipIdOf, + (VoteOf, AccountIdOf), + >; + + /// Stores the list of votes for a community. + #[pallet::storage] + pub(super) type CommunityVoteLocks = StorageDoubleMap<_, Blake2_128Concat, AccountIdOf, Blake2_128Concat, PollIndexOf, VoteOf>; // Pallets use events to inform users when important changes are made. @@ -277,11 +286,9 @@ pub mod pallet { id: T::CommunityId, origin: PalletsOriginOf, }, - /// Some [`CommmuniMetadata`][`types::CommunityMetadata`] has been set - /// for a community. - MetadataSet { + AdminOriginSet { id: T::CommunityId, - name: Option>, + origin: PalletsOriginOf, }, DecisionMethodSet { id: T::CommunityId, @@ -352,38 +359,34 @@ pub mod pallet { admin_origin: PalletsOriginOf, community_id: T::CommunityId, ) -> DispatchResult { - T::CommunityMgmtOrigin::ensure_origin(origin)?; + let maybe_deposit = T::CreateOrigin::ensure_origin(origin)?; + + Self::register(&admin_origin, &community_id, maybe_deposit)?; - Self::do_register_community(&admin_origin, &community_id)?; - Self::deposit_event(Event::CommunityCreated { + Self::deposit_event(crate::Event::CommunityCreated { id: community_id, origin: admin_origin, }); Ok(()) } - /// Sets some [`CommunityMetadata`][11] to describe the - /// community. - /// - /// [11]: `types::CommunityMetadata` + /// Creates a new community managed by the given origin #[pallet::call_index(1)] - #[pallet::weight(::WeightInfo::set_metadata( - name.as_ref().map(|x| x.len() as u32).unwrap_or(0), - description.as_ref().map(|x| x.len() as u32).unwrap_or(0), - url.as_ref().map(|x| x.len() as u32).unwrap_or(0), - ))] - pub fn set_metadata( - origin: OriginFor, - community_id: T::CommunityId, - name: Option>, - description: Option>, - url: Option>, - ) -> DispatchResult { - T::CommunityMgmtOrigin::ensure_origin(origin)?; + pub fn set_admin_origin(origin: OriginFor, admin_origin: PalletsOriginOf) -> DispatchResult { + let community_id = T::AdminOrigin::ensure_origin(origin.clone())?; + + ensure!( + CommunityIdFor::::get(origin.clone().caller()) == Some(community_id), + DispatchError::BadOrigin + ); - Self::do_set_metadata(&community_id, &name, description, url); - Self::deposit_event(Event::MetadataSet { id: community_id, name }); + CommunityIdFor::::remove(origin.caller()); + CommunityIdFor::::insert(admin_origin.clone(), community_id); + Self::deposit_event(Event::AdminOriginSet { + id: community_id, + origin: admin_origin, + }); Ok(()) } @@ -466,9 +469,8 @@ pub mod pallet { community_id: T::CommunityId, decision_method: DecisionMethodFor, ) -> DispatchResult { - T::CommunityMgmtOrigin::ensure_origin(origin)?; + T::AdminOrigin::ensure_origin(origin)?; CommunityDecisionMethod::::set(community_id, decision_method); - Self::deposit_event(Event::DecisionMethodSet { id: community_id }); Ok(()) } @@ -482,7 +484,12 @@ pub mod pallet { vote: VoteOf, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_vote(&who, membership_id, poll_index, &vote)?; + + if CommunityVotes::::get(poll_index, membership_id).is_some() { + Self::try_remove_vote(&who, membership_id, poll_index)?; + } + + Self::try_vote(&who, membership_id, poll_index, &vote)?; Self::deposit_event(Event::::VoteCasted { who: who.clone(), poll_index, @@ -499,7 +506,7 @@ pub mod pallet { #[pallet::compact] poll_index: PollIndexOf, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_remove_vote(&who, membership_id, poll_index)?; + Self::try_remove_vote(&who, membership_id, poll_index)?; Self::deposit_event(Event::::VoteRemoved { who: who.clone(), poll_index, @@ -513,9 +520,8 @@ pub mod pallet { pub fn unlock(origin: OriginFor, #[pallet::compact] poll_index: PollIndexOf) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(T::Polls::as_ongoing(poll_index).is_none(), Error::::AlreadyOngoing); - let vote = Self::community_vote_of(&who, poll_index).ok_or(Error::::NoLocksInPlace)?; - - Self::do_unlock_for_vote(&who, &poll_index, &vote) + let vote = CommunityVoteLocks::::get(&who, poll_index).ok_or(Error::::NoLocksInPlace)?; + Self::update_locks(&who, poll_index, &vote, LockUpdateType::Remove) } /// Dispatch a callable as the community account diff --git a/pallets/communities/src/mock.rs b/pallets/communities/src/mock.rs index 0011cb9b..92c90815 100644 --- a/pallets/communities/src/mock.rs +++ b/pallets/communities/src/mock.rs @@ -3,9 +3,12 @@ use frame_support::{ parameter_types, traits::{ fungible::HoldConsideration, tokens::nonfungible_v2::ItemOf, AsEnsureOriginWithArg, ConstU128, ConstU16, - ConstU32, ConstU64, EitherOf, EnsureOriginWithArg, EqualPrivilegeOnly, Footprint, OriginTrait, + ConstU32, ConstU64, EitherOf, EnsureOriginWithArg, EqualPrivilegeOnly, Footprint, + }, + weights::{ + constants::{WEIGHT_REF_TIME_PER_NANOS, WEIGHT_REF_TIME_PER_SECOND}, + Weight, }, - weights::{constants::WEIGHT_REF_TIME_PER_NANOS, constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, PalletId, }; use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned}; @@ -21,7 +24,7 @@ pub use virto_common::{CommunityId, MembershipId}; use crate::{ self as pallet_communities, - origin::{DecisionMethod, EnsureCommunity}, + origin::{DecisionMethod, EnsureCommunity, EnsureSignedPays}, types::{Tally, VoteWeight}, }; @@ -406,6 +409,12 @@ impl BenchmarkHelper for CommunityBenchmarkHelper { } } +parameter_types! { + pub const NoPay: Option<(Balance, AccountId, AccountId)> = None; +} +type RootCreatesCommunitiesForFree = EnsureRootWithSuccess; +type AnyoneElsePays = EnsureSignedPays, RootAccount>; + impl pallet_communities::Config for Test { type PalletId = CommunitiesPalletId; type CommunityId = CommunityId; @@ -416,7 +425,8 @@ impl pallet_communities::Config for Test { type MemberMgmt = Nfts; type Polls = Referenda; - type CommunityMgmtOrigin = EnsureRoot; + type CreateOrigin = EitherOf; + type AdminOrigin = EnsureCommunity; type MemberMgmtOrigin = EnsureCommunity; type RuntimeCall = RuntimeCall; @@ -542,10 +552,10 @@ impl TestEnvBuilder { .expect("should include decision_method on add_community"); let community_origin: RuntimeOrigin = Self::create_community_origin(community_id); - Communities::create(RuntimeOrigin::root(), community_origin.caller().clone(), *community_id) + Communities::create(RuntimeOrigin::root(), community_origin.caller.clone(), *community_id) .expect("can add community"); - Communities::set_decision_method(RuntimeOrigin::root(), *community_id, decision_method.clone()) + Communities::set_decision_method(community_origin.clone(), *community_id, decision_method.clone()) .expect("can set decision info"); let mut members = self.members.iter().filter(|(cid, _)| cid == community_id); @@ -573,7 +583,7 @@ impl TestEnvBuilder { RuntimeOrigin::root(), *community_id, track_info.clone(), - community_origin.caller().clone(), + community_origin.caller.clone(), ) .expect("can add track"); } diff --git a/pallets/communities/src/origin.rs b/pallets/communities/src/origin.rs index 1c259b17..adf2b0b5 100644 --- a/pallets/communities/src/origin.rs +++ b/pallets/communities/src/origin.rs @@ -1,14 +1,17 @@ use crate::{ types::{CommunityIdOf, CommunityState::Active, MembershipIdOf, RuntimeOriginFor}, - CommunityIdFor, Config, Info, Pallet, + AccountIdOf, CommunityIdFor, Config, Info, Pallet, }; use core::marker::PhantomData; use fc_traits_memberships::Inspect; use frame_support::{ pallet_prelude::*, - traits::{membership::GenericRank, EnsureOriginWithArg, OriginTrait}, + traits::{membership::GenericRank, EnsureOriginWithArg, MapSuccess, OriginTrait}, }; -use sp_runtime::{traits::TryConvert, Permill}; +use frame_system::EnsureSigned; +#[cfg(feature = "xcm")] +use sp_runtime::traits::TryConvert; +use sp_runtime::{morph_types, Permill}; pub struct EnsureCommunity(PhantomData); @@ -43,6 +46,19 @@ where } } +morph_types! { + pub type PaymentForCreate< + AccountId, + GetAmount: TypedGet, + GetReceiver: TypedGet + >: Morph = |sender: AccountId| -> Option<(GetAmount::Type, AccountId, GetReceiver::Type)> { + Some((GetAmount::get(), sender, GetReceiver::get())) + }; +} + +pub type EnsureSignedPays = + MapSuccess>, PaymentForCreate, Amount, Beneficiary>>; + pub struct EnsureMember(PhantomData); impl EnsureOriginWithArg, CommunityIdOf> for EnsureMember diff --git a/pallets/communities/src/tests/governance.rs b/pallets/communities/src/tests/governance.rs index 55608b45..b27c94bb 100644 --- a/pallets/communities/src/tests/governance.rs +++ b/pallets/communities/src/tests/governance.rs @@ -259,6 +259,64 @@ mod vote { ); }); } + + #[test] + fn transferring_memberships_does_not_lead_to_double_voting() { + new_test_ext().execute_with(|| { + assert_ok!(Communities::vote( + RuntimeOrigin::signed(ALICE), + membership(COMMUNITY_A, 1), + 0, + Vote::Standard(true) + )); + + System::assert_last_event( + crate::Event::VoteCasted { + who: ALICE, + poll_index: 0, + vote: Vote::Standard(true), + } + .into(), + ); + + assert_ok!(Nfts::transfer( + RuntimeOrigin::signed(ALICE), + COMMUNITY_A, + membership(COMMUNITY_A, 1), + BOB + )); + + assert_ok!(Communities::vote( + RuntimeOrigin::signed(BOB), + membership(COMMUNITY_A, 1), + 0, + Vote::Standard(true) + )); + + System::assert_last_event( + crate::Event::VoteCasted { + who: BOB, + poll_index: 0, + vote: Vote::Standard(true), + } + .into(), + ); + + use frame_support::traits::Polling; + assert_eq!( + Referenda::as_ongoing(0), + Some(( + Tally { + ayes: 1, + bare_ayes: 1, + nays: 0, + ..Default::default() + }, + COMMUNITY_A + )) + ); + }); + } } mod membership { @@ -373,7 +431,7 @@ mod vote { ext.execute_with(|| { // For now, this community will vote membership-based assert_ok!(Communities::set_decision_method( - RuntimeOrigin::root(), + TestEnvBuilder::create_community_origin(&COMMUNITY_C), COMMUNITY_C, DecisionMethod::Membership )); @@ -909,7 +967,6 @@ mod vote { tick_blocks(2); - dbg!(System::events()); System::assert_has_event(pallet_referenda::Event::::ConfirmStarted { index: 3 }.into()); }); } @@ -1092,25 +1149,6 @@ mod unlock { }); } - #[test] - fn fails_if_no_locks_in_place() { - new_test_ext().execute_with(|| { - tick_blocks(6); - - // Since BOB never casted a vote, a lock wasn't put in place - assert_noop!( - Communities::unlock(RuntimeOrigin::signed(BOB), 1), - Error::NoLocksInPlace - ); - - // Since CHARLIE never casted a vote, a freeze wasn't put in place - assert_noop!( - Communities::unlock(RuntimeOrigin::signed(CHARLIE), 2), - Error::NoLocksInPlace - ); - }); - } - #[test] fn it_works() { new_test_ext().execute_with(|| { diff --git a/pallets/communities/src/tests/registry.rs b/pallets/communities/src/tests/registry.rs index e1ceb6a2..d100b19e 100644 --- a/pallets/communities/src/tests/registry.rs +++ b/pallets/communities/src/tests/registry.rs @@ -1,15 +1,14 @@ use super::*; -use crate::{ - types::{CommunityInfo, CommunityMetadata}, - Event, Info, -}; +use crate::{types::CommunityInfo, Event, Info}; use frame_support::assert_noop; use frame_system::RawOrigin::Root; -use sp_runtime::{BoundedVec, DispatchError}; mod create { use super::*; + const COMMUNITY_B: CommunityId = 2; + const COMMUNITY_B_ORIGIN: OriginCaller = OriginCaller::Communities(crate::Origin::::new(COMMUNITY_B)); + #[test] fn fails_if_community_already_exists() { new_test_ext(&[], &[]).execute_with(|| { @@ -36,69 +35,27 @@ mod create { ); }); } -} - -mod set_metadata { - use super::*; #[test] - fn fails_if_bad_origin() { + fn takes_deposit_if_permissionlessly_creating_community() { new_test_ext(&[], &[]).execute_with(|| { - // Fail if trying to call from unsigned origin - assert_noop!( - Communities::set_metadata(RuntimeOrigin::none(), COMMUNITY, None, None, None), - DispatchError::BadOrigin - ); + const ALICE: AccountId = AccountId::new([1; 32]); + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), ALICE, 15)); - // Fail if trying to call from non-admin - const NON_ADMIN: AccountId = AccountId::new([0; 32]); - assert_noop!( - Communities::set_metadata(RuntimeOrigin::signed(NON_ADMIN), COMMUNITY, None, None, None), - DispatchError::BadOrigin - ); - }); - } - - #[test] - fn works_inserts_default_metadata() { - new_test_ext(&[], &[]).execute_with(|| { - assert_ok!(Communities::set_metadata( - Root.into(), - COMMUNITY, - Some(BoundedVec::truncate_from(b"Virto Network".to_vec())), - None, - None, + assert_ok!(Communities::create( + RuntimeOrigin::signed(ALICE), + COMMUNITY_B_ORIGIN, + COMMUNITY_B )); - let community_metadata = Communities::metadata(COMMUNITY); - - assert_eq!( - community_metadata, - crate::types::CommunityMetadata { - name: BoundedVec::truncate_from(b"Virto Network".to_vec()), - description: BoundedVec::new(), - main_url: BoundedVec::new(), - } - ); - - assert_ok!(Communities::set_metadata( - Root.into(), - COMMUNITY, - None, - Some(BoundedVec::truncate_from(b"A community of awesome builders".to_vec())), - None, - )); - - let community_metadata = Communities::metadata(COMMUNITY); - - assert_eq!( - community_metadata, - CommunityMetadata { - name: BoundedVec::truncate_from(b"Virto Network".to_vec()), - description: BoundedVec::truncate_from(b"A community of awesome builders".to_vec()), - main_url: BoundedVec::new(), + System::assert_has_event( + Event::CommunityCreated { + id: COMMUNITY_B, + origin: COMMUNITY_B_ORIGIN, } + .into(), ); + assert_eq!(Balances::free_balance(ALICE), 5); }); } } diff --git a/pallets/communities/src/tests/weights.rs b/pallets/communities/src/tests/weights.rs index ed35d32f..1c9652a0 100644 --- a/pallets/communities/src/tests/weights.rs +++ b/pallets/communities/src/tests/weights.rs @@ -21,10 +21,7 @@ fn weights() { // Examples: call available weight functions with various parameters (as applicable) to gauge weight usage in // comparison to limits ("create", SubstrateWeight::::create()), - ( - "set_metadata (64, 256, 63)", - SubstrateWeight::::set_metadata(64, 256, 64), - ), + ("set_admin_origin", SubstrateWeight::::set_admin_origin()), ("set_decision_method", SubstrateWeight::::set_decision_method()), ("add_member", SubstrateWeight::::add_member()), ("remove_member", SubstrateWeight::::remove_member()), diff --git a/pallets/communities/src/types.rs b/pallets/communities/src/types.rs index 62e1bdce..14a7f1aa 100644 --- a/pallets/communities/src/types.rs +++ b/pallets/communities/src/types.rs @@ -25,9 +25,6 @@ pub type MembershipIdOf = ::MembershipId; pub type RuntimeCallFor = ::RuntimeCall; pub type RuntimeOriginFor = ::RuntimeOrigin; -pub type SizedField = BoundedVec; -pub type ConstSizedField = SizedField>; - #[cfg(feature = "runtime-benchmarks")] pub type BenchmarkHelperOf = ::BenchmarkHelper; @@ -57,20 +54,7 @@ pub enum CommunityState { Blocked, } -/// The CommunityMetadata struct stores some descriptive information about -/// the community. -#[derive(Clone, Debug, Decode, Default, Encode, Eq, MaxEncodedLen, PartialEq, TypeInfo)] -pub struct CommunityMetadata { - /// The name of the community - pub name: ConstSizedField<64>, - /// A short description of the community - pub description: ConstSizedField<256>, - /// The main URL that can lead to information about the community - pub main_url: ConstSizedField<256>, -} - // Governance - pub type VoteWeight = u32; /// @@ -149,6 +133,11 @@ impl Tally { } } +pub enum LockUpdateType { + Add, + Remove, +} + #[cfg(feature = "runtime-benchmarks")] use {frame_benchmarking::BenchmarkError, frame_system::pallet_prelude::OriginFor}; @@ -158,11 +147,18 @@ pub trait BenchmarkHelper { fn community_id() -> CommunityIdOf; /// Returns the ID of the community to use in benchmarks - fn community_asset_id() -> AssetIdOf; + fn community_asset_id() -> AssetIdOf + where + AssetIdOf: From, + { + 1u32.into() + } /// Returns the desired size of the community for /// effects of benchmark testing - fn community_desired_size() -> u32; + fn community_desired_size() -> u32 { + u8::MAX as u32 + } /// Initializes the membership collection of a community. fn initialize_memberships_collection() -> Result<(), frame_benchmarking::BenchmarkError>; diff --git a/pallets/communities/src/weights.rs b/pallets/communities/src/weights.rs index e764a82e..4532efb0 100644 --- a/pallets/communities/src/weights.rs +++ b/pallets/communities/src/weights.rs @@ -34,12 +34,12 @@ use core::marker::PhantomData; /// Weight functions needed for pallet_communities. pub trait WeightInfo { fn create() -> Weight; - fn set_metadata(n: u32, d: u32, u: u32) -> Weight; fn add_member() -> Weight; + fn set_admin_origin () -> Weight; + fn set_decision_method () -> Weight; fn promote() -> Weight; fn demote() -> Weight; fn remove_member() -> Weight; - fn set_decision_method () -> Weight; fn vote() -> Weight; fn remove_vote() -> Weight; fn unlock() -> Weight; @@ -70,7 +70,7 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[1, 64]`. /// The range of component `d` is `[1, 256]`. /// The range of component `u` is `[1, 256]`. - fn set_metadata(_n: u32, d: u32, u: u32, ) -> Weight { + fn set_admin_origin() -> Weight { // Proof Size summary in bytes: // Measured: `75` // Estimated: `4065` @@ -78,9 +78,6 @@ impl WeightInfo for SubstrateWeight { Weight::from_parts(37_081_339, 0) .saturating_add(Weight::from_parts(0, 4065)) // Standard Error: 1_334 - .saturating_add(Weight::from_parts(4_526, 0).saturating_mul(d.into())) - // Standard Error: 1_334 - .saturating_add(Weight::from_parts(2_575, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -291,7 +288,7 @@ impl WeightInfo for () { /// The range of component `n` is `[1, 64]`. /// The range of component `d` is `[1, 256]`. /// The range of component `u` is `[1, 256]`. - fn set_metadata(_n: u32, d: u32, u: u32, ) -> Weight { + fn set_admin_origin() -> Weight { // Proof Size summary in bytes: // Measured: `75` // Estimated: `4065` @@ -299,9 +296,6 @@ impl WeightInfo for () { Weight::from_parts(37_081_339, 0) .saturating_add(Weight::from_parts(0, 4065)) // Standard Error: 1_334 - .saturating_add(Weight::from_parts(4_526, 0).saturating_mul(d.into())) - // Standard Error: 1_334 - .saturating_add(Weight::from_parts(2_575, 0).saturating_mul(u.into())) .saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().writes(1)) } diff --git a/runtime/kreivo/Cargo.toml b/runtime/kreivo/Cargo.toml index dbc52a94..94cb2d4c 100644 --- a/runtime/kreivo/Cargo.toml +++ b/runtime/kreivo/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kreivo-runtime" description = "Kreivo Runtime" -version = "0.10.2" +version = "0.11.0" authors = ['Virto Team '] license = "GPL-3.0-only" homepage = 'https://github.com/virto-network/virto-node' @@ -24,6 +24,7 @@ smallvec = { workspace = true } # Local pallet-payments = { workspace = true } pallet-communities = { workspace = true, features = ["xcm"] } +pallet-communities-manager = { workspace = true } # Local: Common virto-common = { workspace = true, default-features = false, features = ["runtime"] } @@ -128,6 +129,7 @@ std = [ "pallet-aura/std", "pallet-authorship/std", "pallet-balances/std", + "pallet-communities-manager/std", "pallet-communities/std", "pallet-collator-selection/std", "pallet-message-queue/std", @@ -190,6 +192,7 @@ runtime-benchmarks = [ "pallet-asset-tx-payment/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-communities-manager/runtime-benchmarks", "pallet-communities/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", @@ -230,6 +233,7 @@ try-runtime = [ "pallet-aura/try-runtime", "pallet-authorship/try-runtime", "pallet-balances/try-runtime", + "pallet-communities-manager/try-runtime", "pallet-communities/try-runtime", "pallet-collator-selection/try-runtime", "pallet-message-queue/try-runtime", diff --git a/runtime/kreivo/src/collective/governance.rs b/runtime/kreivo/src/collective/governance.rs index dcfbc7f8..6599fcfa 100644 --- a/runtime/kreivo/src/collective/governance.rs +++ b/runtime/kreivo/src/collective/governance.rs @@ -1,7 +1,7 @@ use super::*; -use pallet_communities::origin::AsSignedByCommunity; -use pallet_ranked_collective::{EnsureMember, TallyOf, Votes}; +use frame_system::EnsureSigned; +use pallet_ranked_collective::{TallyOf, Votes}; use parachains_common::kusama::currency::QUID; use sp_core::ConstU128; @@ -21,14 +21,13 @@ impl pallet_referenda::Config for Runtime { type Scheduler = Scheduler; type Currency = Balances; // Communities can submit proposals. - type SubmitOrigin = - AsEnsureOriginWithArg, AsSignedByCommunity>>; + type SubmitOrigin = EnsureSigned; type CancelOrigin = EnsureRoot; type KillOrigin = EnsureRoot; type Slash = (); type Votes = Votes; type Tally = TallyOf; - type SubmissionDeposit = ConstU128<0>; + type SubmissionDeposit = ConstU128<{ UNITS }>; type MaxQueued = ConstU32<10>; type UndecidingTimeout = ConstU32<{ 2 * DAYS }>; type AlarmInterval = ConstU32<1>; diff --git a/runtime/kreivo/src/collective/tracks.rs b/runtime/kreivo/src/collective/tracks.rs index ea56b264..2645aadc 100644 --- a/runtime/kreivo/src/collective/tracks.rs +++ b/runtime/kreivo/src/collective/tracks.rs @@ -18,7 +18,7 @@ impl pallet_referenda::TracksInfo for TracksInfo { info: pallet_referenda::TrackInfo { name: s("Root"), max_deciding: 1, - decision_deposit: 0, + decision_deposit: UNITS, prepare_period: 15 * MINUTES, decision_period: 4 * DAYS, confirm_period: 15 * MINUTES, diff --git a/runtime/kreivo/src/communities/governance.rs b/runtime/kreivo/src/communities/governance.rs index 745203c4..8a9a128a 100644 --- a/runtime/kreivo/src/communities/governance.rs +++ b/runtime/kreivo/src/communities/governance.rs @@ -1,6 +1,7 @@ use super::*; use frame_system::{pallet_prelude::BlockNumberFor, EnsureRootWithSuccess}; +use pallet_communities::RuntimeOriginFor; use sp_std::marker::PhantomData; use pallet_referenda::{BalanceOf, PalletsOriginOf, TrackIdOf, TracksInfo}; diff --git a/runtime/kreivo/src/communities/memberships.rs b/runtime/kreivo/src/communities/memberships.rs index b5710df6..122aa3df 100644 --- a/runtime/kreivo/src/communities/memberships.rs +++ b/runtime/kreivo/src/communities/memberships.rs @@ -18,8 +18,8 @@ impl pallet_nfts::Config for Runtime { type CreateOrigin = EnsureRootWithSuccess; type Locker = (); - type CollectionDeposit = NftsCollectionDeposit; - type ItemDeposit = NftsItemDeposit; + type CollectionDeposit = (); + type ItemDeposit = (); type MetadataDepositBase = NftsMetadataDepositBase; type AttributeDepositBase = NftsAttributeDepositBase; type DepositPerByte = NftsDepositPerByte; diff --git a/runtime/kreivo/src/communities/mod.rs b/runtime/kreivo/src/communities/mod.rs index ea0e54bd..3cbda3e8 100644 --- a/runtime/kreivo/src/communities/mod.rs +++ b/runtime/kreivo/src/communities/mod.rs @@ -1,11 +1,9 @@ use super::*; -use frame_support::{ - pallet_prelude::{EnsureOrigin, PhantomData}, - traits::OriginTrait, -}; -use pallet_communities::{origin::EnsureCommunity, types::RuntimeOriginFor}; -use sp_runtime::traits::AccountIdConversion; +use frame_support::traits::TryMapSuccess; +use frame_system::{EnsureRootWithSuccess, EnsureSigned}; +use pallet_communities::origin::{EnsureCommunity, EnsureSignedPays}; +use sp_runtime::{morph_types, traits::AccountIdConversion}; use virto_common::{CommunityId, MembershipId}; pub mod governance; @@ -18,13 +16,13 @@ use self::{ }; #[cfg(feature = "runtime-benchmarks")] -use ::{ +use { frame_benchmarking::BenchmarkError, frame_support::traits::{schedule::DispatchTime, tokens::nonfungible_v2::ItemOf, tokens::nonfungible_v2::Mutate}, frame_system::pallet_prelude::{OriginFor, RuntimeCallFor}, pallet_communities::{ types::{CommunityIdOf, MembershipIdOf, PalletsOriginOf, PollIndexOf}, - BenchmarkHelper, Origin, + BenchmarkHelper, }, pallet_nfts::Pallet as Nfts, pallet_referenda::{BoundedCallOf, Curve, Pallet as Referenda, TrackInfo}, @@ -34,42 +32,28 @@ use ::{ }; parameter_types! { - pub const CommunityPalletId: PalletId = PalletId(*b"kv/cmtys"); + pub const CommunityPalletId: PalletId = PalletId(*b"kv/cmtys"); pub const MembershipsCollectionId: CommunityId = 0; pub const MembershipNftAttr: &'static [u8; 10] = b"membership"; + pub const CommunityDepositAmount: Balance = UNITS / 2; + pub const NoPay: Option<(Balance, AccountId, AccountId)> = None; } -pub struct EnsureCommunityAccountId(PhantomData); - -impl EnsureOrigin> for EnsureCommunityAccountId -where - RuntimeOriginFor: - OriginTrait + From> + From>, - T: pallet_communities::Config, -{ - type Success = T::CommunityId; - - fn try_origin(o: RuntimeOriginFor) -> Result> { - match o.clone().into() { - Ok(frame_system::RawOrigin::Signed(account_id)) => { - let (_, community_id) = PalletId::try_from_sub_account(&account_id).ok_or(o.clone())?; - Ok(community_id) - } - _ => Err(o), - } - } - - #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin() -> Result, ()> { - Ok(Origin::new(T::BenchmarkHelper::community_id()).into()) - } +morph_types! { + pub type AccountToCommunityId: TryMorph = |a: AccountId| -> Result { + PalletId::try_from_sub_account(&a).map(|(_, id)| id).ok_or(()) + }; } +type EnsureCommunityAccount = TryMapSuccess, AccountToCommunityId>; + +type RootCreatesCommunitiesForFree = EnsureRootWithSuccess; +type AnyoneElsePays = EnsureSignedPays; impl pallet_communities::Config for Runtime { type CommunityId = CommunityId; - - type CommunityMgmtOrigin = EnsureRoot; - type MemberMgmtOrigin = EitherOf, EnsureCommunityAccountId>; + type CreateOrigin = EitherOf; + type AdminOrigin = EitherOf, EnsureCommunityAccount>; + type MemberMgmtOrigin = EitherOf, EnsureCommunityAccount>; type MemberMgmt = CommunityMemberships; type MembershipId = MembershipId; @@ -90,6 +74,14 @@ impl pallet_communities::Config for Runtime { type BenchmarkHelper = CommunityBenchmarkHelper; } +impl pallet_communities_manager::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CreateCollection = CommunityMemberships; + type Tracks = CommunityTracks; + type RankedCollective = KreivoCollective; + type WeightInfo = crate::weights::pallet_communities_manager::WeightInfo; +} + #[cfg(feature = "runtime-benchmarks")] type MembershipCollection = ItemOf; @@ -124,13 +116,6 @@ impl BenchmarkHelper for CommunityBenchmarkHelper { let community_id = Self::community_id(); let community_account = pallet_communities::Pallet::::community_account(&community_id); - <::Balances as frame_support::traits::fungible::Mutate>::mint_into( - &community_account, - >::AttributeDepositBase::get() + - // Deposit for membership_member_count attribute - >::DepositPerByte::get() * 27 - )?; - Nfts::::do_create_collection( community_id, community_account.clone(), @@ -152,22 +137,6 @@ impl BenchmarkHelper for CommunityBenchmarkHelper { ) -> Result<(), BenchmarkError> { let community_account = pallet_communities::Pallet::::community_account(&community_id); - <::Balances as frame_support::traits::fungible::Mutate>::mint_into( - &TreasuryAccount::get(), - >::ItemDeposit::get() - )?; - - <::Balances as frame_support::traits::fungible::Mutate>::mint_into( - &community_account, - >::ItemDeposit::get() - )?; - <::Balances as frame_support::traits::fungible::Mutate>::mint_into( - &community_account, - >::AttributeDepositBase::get() + - // Deposit for membership_member_rank attribute - >::DepositPerByte::get() * 26 - )?; - MembershipCollection::mint_into(&membership_id, &community_account, &Default::default(), true)?; Ok(()) diff --git a/runtime/kreivo/src/lib.rs b/runtime/kreivo/src/lib.rs index acdb6093..b517da9b 100644 --- a/runtime/kreivo/src/lib.rs +++ b/runtime/kreivo/src/lib.rs @@ -142,10 +142,10 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("kreivo-parachain"), impl_name: create_runtime_str!("kreivo-parachain"), authoring_version: 1, - spec_version: 107, + spec_version: 108, impl_version: 0, apis: RUNTIME_API_VERSIONS, - transaction_version: 5, + transaction_version: 6, state_version: 1, }; @@ -210,6 +210,7 @@ construct_runtime!( CommunityTracks: pallet_referenda_tracks:: = 72, CommunityReferenda: pallet_referenda:: = 73, CommunityMemberships: pallet_nfts:: = 74, + CommunitiesManager: pallet_communities_manager = 75, } ); @@ -728,6 +729,7 @@ mod benches { [pallet_communities, Communities] [pallet_referenda_tracks, CommunityTracks] [pallet_referenda, CommunityReferenda] + [pallet_communities_manager, CommunitiesManager] [pallet_nfts, CommunityMemberships] // XCM // NOTE: Make sure you point to the individual modules below. diff --git a/runtime/kreivo/src/weights/mod.rs b/runtime/kreivo/src/weights/mod.rs index 5c4f6d1a..5f966470 100644 --- a/runtime/kreivo/src/weights/mod.rs +++ b/runtime/kreivo/src/weights/mod.rs @@ -21,6 +21,7 @@ pub mod block_weights; pub mod extrinsic_weights; pub mod pallet_assets; pub mod pallet_communities; +pub mod pallet_communities_manager; pub mod pallet_payments; pub mod pallet_proxy; pub mod paritydb_weights; diff --git a/runtime/kreivo/src/weights/pallet_communities.rs b/runtime/kreivo/src/weights/pallet_communities.rs index 1de048e6..c46f40c9 100644 --- a/runtime/kreivo/src/weights/pallet_communities.rs +++ b/runtime/kreivo/src/weights/pallet_communities.rs @@ -2,7 +2,7 @@ //! Autogenerated weights for `pallet_communities` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-04-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-04-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `virto-builder`, CPU: `Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("kreivo-local")`, DB CACHE: 1024 @@ -45,40 +45,38 @@ impl pallet_communities::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `56` // Estimated: `3593` - // Minimum execution time: 39_126_000 picoseconds. - Weight::from_parts(46_625_000, 0) + // Minimum execution time: 61_614_000 picoseconds. + Weight::from_parts(69_046_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Communities::Metadata` (r:1 w:1) - /// Proof: `Communities::Metadata` (`max_values`: None, `max_size`: Some(600), added: 3075, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 64]`. - /// The range of component `d` is `[1, 256]`. - /// The range of component `u` is `[1, 256]`. - fn set_metadata(_n: u32, d: u32, u: u32, ) -> Weight { + /// Storage: `Communities::CommunityIdFor` (r:1 w:2) + /// Proof: `Communities::CommunityIdFor` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// Storage: `Communities::Info` (r:1 w:0) + /// Proof: `Communities::Info` (`max_values`: None, `max_size`: Some(19), added: 2494, mode: `MaxEncodedLen`) + fn set_admin_origin() -> Weight { // Proof Size summary in bytes: - // Measured: `75` - // Estimated: `4065` - // Minimum execution time: 23_340_000 picoseconds. - Weight::from_parts(37_081_339, 0) - .saturating_add(Weight::from_parts(0, 4065)) - // Standard Error: 1_334 - .saturating_add(Weight::from_parts(4_526, 0).saturating_mul(d.into())) - // Standard Error: 1_334 - .saturating_add(Weight::from_parts(2_575, 0).saturating_mul(u.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `122` + // Estimated: `4087` + // Minimum execution time: 65_300_000 picoseconds. + Weight::from_parts(69_683_000, 0) + .saturating_add(Weight::from_parts(0, 4087)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Communities::Info` (r:1 w:0) + /// Proof: `Communities::Info` (`max_values`: None, `max_size`: Some(19), added: 2494, mode: `MaxEncodedLen`) /// Storage: `Communities::CommunityDecisionMethod` (r:0 w:1) - /// Proof: `Communities::CommunityDecisionMethod` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Proof: `Communities::CommunityDecisionMethod` (`max_values`: None, `max_size`: Some(37), added: 2512, mode: `MaxEncodedLen`) fn set_decision_method() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 17_407_000 picoseconds. - Weight::from_parts(26_505_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `115` + // Estimated: `3484` + // Minimum execution time: 39_560_000 picoseconds. + Weight::from_parts(43_691_000, 0) + .saturating_add(Weight::from_parts(0, 3484)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Communities::Info` (r:1 w:0) @@ -93,8 +91,6 @@ impl pallet_communities::WeightInfo for WeightInfo { /// Proof: `CommunityMemberships::Collection` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Item` (r:2 w:2) /// Proof: `CommunityMemberships::Item` (`max_values`: None, `max_size`: Some(859), added: 3334, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::ItemMetadataOf` (r:1 w:0) /// Proof: `CommunityMemberships::ItemMetadataOf` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::CollectionConfigOf` (r:1 w:0) @@ -107,19 +103,19 @@ impl pallet_communities::WeightInfo for WeightInfo { /// Proof: `CommunityMemberships::PendingSwapOf` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn add_member() -> Weight { // Proof Size summary in bytes: - // Measured: `1123` + // Measured: `880` // Estimated: `9846` - // Minimum execution time: 446_737_000 picoseconds. - Weight::from_parts(472_105_000, 0) + // Minimum execution time: 350_162_000 picoseconds. + Weight::from_parts(380_032_000, 0) .saturating_add(Weight::from_parts(0, 9846)) - .saturating_add(T::DbWeight::get().reads(15)) - .saturating_add(T::DbWeight::get().writes(15)) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(13)) } /// Storage: `Communities::Info` (r:1 w:0) /// Proof: `Communities::Info` (`max_values`: None, `max_size`: Some(19), added: 2494, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Account` (r:1 w:1) /// Proof: `CommunityMemberships::Account` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) - /// Storage: `CommunityMemberships::Attribute` (r:3 w:2) + /// Storage: `CommunityMemberships::Attribute` (r:4 w:3) /// Proof: `CommunityMemberships::Attribute` (`max_values`: None, `max_size`: Some(477), added: 2952, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Collection` (r:1 w:1) /// Proof: `CommunityMemberships::Collection` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) @@ -127,8 +123,6 @@ impl pallet_communities::WeightInfo for WeightInfo { /// Proof: `CommunityMemberships::ItemConfigOf` (`max_values`: None, `max_size`: Some(46), added: 2521, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Item` (r:1 w:1) /// Proof: `CommunityMemberships::Item` (`max_values`: None, `max_size`: Some(859), added: 3334, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::ItemMetadataOf` (r:1 w:0) /// Proof: `CommunityMemberships::ItemMetadataOf` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::ItemPriceOf` (r:0 w:1) @@ -139,11 +133,11 @@ impl pallet_communities::WeightInfo for WeightInfo { /// Proof: `CommunityMemberships::PendingSwapOf` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn remove_member() -> Weight { // Proof Size summary in bytes: - // Measured: `1146` - // Estimated: `9846` - // Minimum execution time: 286_361_000 picoseconds. - Weight::from_parts(479_050_000, 0) - .saturating_add(Weight::from_parts(0, 9846)) + // Measured: `1006` + // Estimated: `12798` + // Minimum execution time: 379_940_000 picoseconds. + Weight::from_parts(408_854_000, 0) + .saturating_add(Weight::from_parts(0, 12798)) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(10)) } @@ -157,8 +151,8 @@ impl pallet_communities::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `717` // Estimated: `6894` - // Minimum execution time: 136_612_000 picoseconds. - Weight::from_parts(161_764_000, 0) + // Minimum execution time: 203_916_000 picoseconds. + Weight::from_parts(208_036_000, 0) .saturating_add(Weight::from_parts(0, 6894)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -171,74 +165,90 @@ impl pallet_communities::WeightInfo for WeightInfo { /// Proof: `CommunityMemberships::Collection` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn demote() -> Weight { // Proof Size summary in bytes: - // Measured: `717` + // Measured: `755` // Estimated: `6894` - // Minimum execution time: 136_647_000 picoseconds. - Weight::from_parts(175_816_000, 0) + // Minimum execution time: 195_421_000 picoseconds. + Weight::from_parts(213_713_000, 0) .saturating_add(Weight::from_parts(0, 6894)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `Communities::CommunityVotes` (r:1 w:1) + /// Proof: `Communities::CommunityVotes` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Account` (r:1 w:0) /// Proof: `CommunityMemberships::Account` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) /// Storage: `CommunityReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `CommunityReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Communities::CommunityDecisionMethod` (r:1 w:0) - /// Proof: `Communities::CommunityDecisionMethod` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Proof: `Communities::CommunityDecisionMethod` (`max_values`: None, `max_size`: Some(37), added: 2512, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Attribute` (r:1 w:0) /// Proof: `CommunityMemberships::Attribute` (`max_values`: None, `max_size`: Some(477), added: 2952, mode: `MaxEncodedLen`) - /// Storage: `Communities::CommunityVotes` (r:1 w:1) - /// Proof: `Communities::CommunityVotes` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Communities::CommunityVoteLocks` (r:2 w:1) + /// Proof: `Communities::CommunityVoteLocks` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:1) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(4658), added: 7133, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:0) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(155814), added: 158289, mode: `MaxEncodedLen`) fn vote() -> Weight { // Proof Size summary in bytes: - // Measured: `2891` + // Measured: `3440` // Estimated: `317568` - // Minimum execution time: 229_153_000 picoseconds. - Weight::from_parts(308_906_000, 0) + // Minimum execution time: 401_943_000 picoseconds. + Weight::from_parts(421_485_000, 0) .saturating_add(Weight::from_parts(0, 317568)) - .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(7)) } /// Storage: `CommunityMemberships::Account` (r:1 w:0) /// Proof: `CommunityMemberships::Account` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`) /// Storage: `CommunityReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `CommunityReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Communities::CommunityVotes` (r:1 w:1) - /// Proof: `Communities::CommunityVotes` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Proof: `Communities::CommunityVotes` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Communities::CommunityDecisionMethod` (r:1 w:0) - /// Proof: `Communities::CommunityDecisionMethod` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Proof: `Communities::CommunityDecisionMethod` (`max_values`: None, `max_size`: Some(37), added: 2512, mode: `MaxEncodedLen`) /// Storage: `CommunityMemberships::Attribute` (r:1 w:0) /// Proof: `CommunityMemberships::Attribute` (`max_values`: None, `max_size`: Some(477), added: 2952, mode: `MaxEncodedLen`) + /// Storage: `Communities::CommunityVoteLocks` (r:2 w:1) + /// Proof: `Communities::CommunityVoteLocks` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:1) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(4658), added: 7133, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:0) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) fn remove_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `2893` - // Estimated: `4365` - // Minimum execution time: 166_028_000 picoseconds. - Weight::from_parts(219_123_000, 0) - .saturating_add(Weight::from_parts(0, 4365)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `3539` + // Estimated: `8123` + // Minimum execution time: 227_921_000 picoseconds. + Weight::from_parts(315_697_000, 0) + .saturating_add(Weight::from_parts(0, 8123)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `CommunityReferenda::ReferendumInfoFor` (r:1 w:0) /// Proof: `CommunityReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) - /// Storage: `Communities::CommunityVotes` (r:1 w:1) - /// Proof: `Communities::CommunityVotes` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:1) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(5682), added: 8157, mode: `MaxEncodedLen`) + /// Storage: `Communities::CommunityVoteLocks` (r:2 w:1) + /// Proof: `Communities::CommunityVoteLocks` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:1) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(4658), added: 7133, mode: `MaxEncodedLen`) /// Storage: `Balances::Locks` (r:1 w:0) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `1046` - // Estimated: `9147` - // Minimum execution time: 122_533_000 picoseconds. - Weight::from_parts(173_769_000, 0) - .saturating_add(Weight::from_parts(0, 9147)) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `1082` + // Estimated: `8123` + // Minimum execution time: 154_383_000 picoseconds. + Weight::from_parts(214_346_000, 0) + .saturating_add(Weight::from_parts(0, 8123)) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Communities::Info` (r:1 w:0) @@ -247,8 +257,8 @@ impl pallet_communities::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115` // Estimated: `3484` - // Minimum execution time: 31_529_000 picoseconds. - Weight::from_parts(33_449_000, 0) + // Minimum execution time: 33_022_000 picoseconds. + Weight::from_parts(55_259_000, 0) .saturating_add(Weight::from_parts(0, 3484)) .saturating_add(T::DbWeight::get().reads(1)) } diff --git a/runtime/kreivo/src/weights/pallet_communities_manager.rs b/runtime/kreivo/src/weights/pallet_communities_manager.rs new file mode 100644 index 00000000..f7a0b93c --- /dev/null +++ b/runtime/kreivo/src/weights/pallet_communities_manager.rs @@ -0,0 +1,76 @@ + +//! Autogenerated weights for `pallet_communities_manager` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-04-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `virto-builder`, CPU: `Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("kreivo-local")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/virto-node +// benchmark +// pallet +// --chain +// kreivo-local +// --pallet +// pallet_communities_manager +// --extrinsic +// * +// --steps +// 50 +// --repeat +// 20 +// --output +// runtime/kreivo/src/weights/pallet_communities_manager.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_communities_manager`. +pub struct WeightInfo(PhantomData); +impl pallet_communities_manager::WeightInfo for WeightInfo { + /// Storage: `Communities::Info` (r:1 w:1) + /// Proof: `Communities::Info` (`max_values`: None, `max_size`: Some(19), added: 2494, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `CommunityMemberships::Collection` (r:1 w:1) + /// Proof: `CommunityMemberships::Collection` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `CommunityTracks::Tracks` (r:1 w:1) + /// Proof: `CommunityTracks::Tracks` (`max_values`: None, `max_size`: Some(129), added: 2604, mode: `MaxEncodedLen`) + /// Storage: `CommunityTracks::TracksIds` (r:1 w:1) + /// Proof: `CommunityTracks::TracksIds` (`max_values`: Some(1), `max_size`: Some(131076), added: 131571, mode: `MaxEncodedLen`) + /// Storage: `KreivoCollective::Members` (r:1 w:1) + /// Proof: `KreivoCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `KreivoCollective::MemberCount` (r:1 w:1) + /// Proof: `KreivoCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Communities::CommunityIdFor` (r:0 w:1) + /// Proof: `Communities::CommunityIdFor` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// Storage: `KreivoCollective::IndexToId` (r:0 w:1) + /// Proof: `KreivoCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `KreivoCollective::IdToIndex` (r:0 w:1) + /// Proof: `KreivoCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CommunityTracks::OriginToTrackId` (r:0 w:1) + /// Proof: `CommunityTracks::OriginToTrackId` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// Storage: `CommunityMemberships::CollectionRoleOf` (r:0 w:1) + /// Proof: `CommunityMemberships::CollectionRoleOf` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `CommunityMemberships::CollectionConfigOf` (r:0 w:1) + /// Proof: `CommunityMemberships::CollectionConfigOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `CommunityMemberships::CollectionAccount` (r:0 w:1) + /// Proof: `CommunityMemberships::CollectionAccount` (`max_values`: None, `max_size`: Some(66), added: 2541, mode: `MaxEncodedLen`) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `278` + // Estimated: `132561` + // Minimum execution time: 117_045_000 picoseconds. + Weight::from_parts(166_053_000, 0) + .saturating_add(Weight::from_parts(0, 132561)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(14)) + } +} diff --git a/runtime/kreivo/src/weights/pallet_payments.rs b/runtime/kreivo/src/weights/pallet_payments.rs index 212745f4..a7bc5fc1 100644 --- a/runtime/kreivo/src/weights/pallet_payments.rs +++ b/runtime/kreivo/src/weights/pallet_payments.rs @@ -2,7 +2,7 @@ //! Autogenerated weights for `pallet_payments` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-04-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-04-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `virto-builder`, CPU: `Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("kreivo-local")`, DB CACHE: 1024 @@ -36,78 +36,78 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_payments::WeightInfo for WeightInfo { /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Assets::Holds` (r:2 w:2) - /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(1182), added: 3657, mode: `MaxEncodedLen`) + /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(983), added: 3458, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:2 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(147), added: 2622, mode: `MaxEncodedLen`) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// Storage: `Payments::PaymentParties` (r:0 w:1) /// Proof: `Payments::PaymentParties` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// The range of component `q` is `[1, 50]`. fn pay(_q: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `510` - // Estimated: `8517` - // Minimum execution time: 161_437_000 picoseconds. - Weight::from_parts(243_625_056, 0) - .saturating_add(Weight::from_parts(0, 8517)) + // Measured: `544` + // Estimated: `8518` + // Minimum execution time: 159_701_000 picoseconds. + Weight::from_parts(253_581_329, 0) + .saturating_add(Weight::from_parts(0, 8518)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:3 w:3) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(147), added: 2622, mode: `MaxEncodedLen`) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// Storage: `Assets::Holds` (r:2 w:2) - /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(1182), added: 3657, mode: `MaxEncodedLen`) + /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(983), added: 3458, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn release() -> Weight { // Proof Size summary in bytes: - // Measured: `1119` - // Estimated: `8856` - // Minimum execution time: 263_269_000 picoseconds. - Weight::from_parts(336_806_000, 0) - .saturating_add(Weight::from_parts(0, 8856)) + // Measured: `1153` + // Estimated: `8859` + // Minimum execution time: 414_864_000 picoseconds. + Weight::from_parts(429_418_000, 0) + .saturating_add(Weight::from_parts(0, 8859)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(8)) } /// Storage: `Payments::PaymentParties` (r:1 w:1) /// Proof: `Payments::PaymentParties` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(147), added: 2622, mode: `MaxEncodedLen`) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// Storage: `Assets::Holds` (r:2 w:2) - /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(1182), added: 3657, mode: `MaxEncodedLen`) + /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(983), added: 3458, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `1086` - // Estimated: `8517` - // Minimum execution time: 204_349_000 picoseconds. - Weight::from_parts(254_506_000, 0) - .saturating_add(Weight::from_parts(0, 8517)) + // Measured: `1120` + // Estimated: `8518` + // Minimum execution time: 309_509_000 picoseconds. + Weight::from_parts(333_648_000, 0) + .saturating_add(Weight::from_parts(0, 8518)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(7)) } /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(155814), added: 158289, mode: `MaxEncodedLen`) fn request_refund() -> Weight { // Proof Size summary in bytes: - // Measured: `343` + // Measured: `377` // Estimated: `159279` - // Minimum execution time: 59_774_000 picoseconds. - Weight::from_parts(68_590_000, 0) + // Minimum execution time: 57_498_000 picoseconds. + Weight::from_parts(71_539_000, 0) .saturating_add(Weight::from_parts(0, 159279)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -115,23 +115,23 @@ impl pallet_payments::WeightInfo for WeightInfo { /// Storage: `Payments::PaymentParties` (r:1 w:0) /// Proof: `Payments::PaymentParties` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Assets::Holds` (r:1 w:1) - /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(1182), added: 3657, mode: `MaxEncodedLen`) + /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(983), added: 3458, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(147), added: 2622, mode: `MaxEncodedLen`) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(155814), added: 158289, mode: `MaxEncodedLen`) fn dispute_refund() -> Weight { // Proof Size summary in bytes: - // Measured: `1187` + // Measured: `1221` // Estimated: `159279` - // Minimum execution time: 144_132_000 picoseconds. - Weight::from_parts(164_914_000, 0) + // Minimum execution time: 216_107_000 picoseconds. + Weight::from_parts(236_476_000, 0) .saturating_add(Weight::from_parts(0, 159279)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(6)) @@ -139,58 +139,58 @@ impl pallet_payments::WeightInfo for WeightInfo { /// Storage: `Payments::PaymentParties` (r:1 w:0) /// Proof: `Payments::PaymentParties` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:3 w:3) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(147), added: 2622, mode: `MaxEncodedLen`) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// Storage: `Assets::Holds` (r:2 w:2) - /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(1182), added: 3657, mode: `MaxEncodedLen`) + /// Proof: `Assets::Holds` (`max_values`: None, `max_size`: Some(983), added: 3458, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn resolve_dispute() -> Weight { // Proof Size summary in bytes: - // Measured: `1189` - // Estimated: `8856` - // Minimum execution time: 371_278_000 picoseconds. - Weight::from_parts(422_852_000, 0) - .saturating_add(Weight::from_parts(0, 8856)) + // Measured: `1223` + // Estimated: `8859` + // Minimum execution time: 573_042_000 picoseconds. + Weight::from_parts(596_747_000, 0) + .saturating_add(Weight::from_parts(0, 8859)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(8)) } /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Payments::PaymentParties` (r:0 w:1) /// Proof: `Payments::PaymentParties` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) fn request_payment() -> Weight { // Proof Size summary in bytes: - // Measured: `357` - // Estimated: `8517` - // Minimum execution time: 41_756_000 picoseconds. - Weight::from_parts(60_208_000, 0) - .saturating_add(Weight::from_parts(0, 8517)) + // Measured: `391` + // Estimated: `8518` + // Minimum execution time: 56_938_000 picoseconds. + Weight::from_parts(58_726_000, 0) + .saturating_add(Weight::from_parts(0, 8518)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Payments::PaymentParties` (r:1 w:0) /// Proof: `Payments::PaymentParties` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// Storage: `Payments::Payment` (r:1 w:1) - /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5052), added: 7527, mode: `MaxEncodedLen`) + /// Proof: `Payments::Payment` (`max_values`: None, `max_size`: Some(5053), added: 7528, mode: `MaxEncodedLen`) /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(223), added: 2698, mode: `MaxEncodedLen`) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(224), added: 2699, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:3 w:3) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(147), added: 2622, mode: `MaxEncodedLen`) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_and_pay() -> Weight { // Proof Size summary in bytes: - // Measured: `980` - // Estimated: `8856` - // Minimum execution time: 333_981_000 picoseconds. - Weight::from_parts(364_695_000, 0) - .saturating_add(Weight::from_parts(0, 8856)) + // Measured: `1014` + // Estimated: `8859` + // Minimum execution time: 356_092_000 picoseconds. + Weight::from_parts(361_268_000, 0) + .saturating_add(Weight::from_parts(0, 8859)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(6)) }