diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..d2c78e25c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## What? + +## Why? + +## How? + +## Testing? + +## Screenshots (optional) + +## Anything Else? diff --git a/.github/workflows/pull_request_template.md b/.github/workflows/pull_request_template.md deleted file mode 100644 index b4e3b3ed0..000000000 --- a/.github/workflows/pull_request_template.md +++ /dev/null @@ -1,10 +0,0 @@ -## Describe your changes - -## Changes Made - -## Additional Notes - -## Checklist before requesting a review -- [ ] I have performed a self-review of my code -- [ ] If it is a core feature, I have added thorough tests. -- [ ] If it is a core feature, I have added thorough benchmarks. diff --git a/Cargo.lock b/Cargo.lock index 6ec06b6bb..6c654822c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,12 +125,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "ansi_term" version = "0.12.1" @@ -278,93 +272,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15832d94c458da98cac0ffa6eca52cc19c2a3c6c951058500a5ae8f01f0fdf56" -[[package]] -name = "asset-hub-polkadot-runtime" -version = "0.9.420" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "assets-common", - "cumulus-pallet-aura-ext", - "cumulus-pallet-dmp-queue", - "cumulus-pallet-parachain-system", - "cumulus-pallet-session-benchmarking", - "cumulus-pallet-xcm", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-core", - "cumulus-primitives-timestamp", - "cumulus-primitives-utility", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-rpc-runtime-api", - "log", - "pallet-asset-tx-payment", - "pallet-assets", - "pallet-aura", - "pallet-authorship", - "pallet-balances", - "pallet-collator-selection", - "pallet-multisig", - "pallet-nfts", - "pallet-nfts-runtime-api", - "pallet-proxy", - "pallet-session", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-uniques", - "pallet-utility", - "pallet-xcm", - "parachain-info", - "parachains-common", - "parity-scale-codec", - "polkadot-core-primitives", - "polkadot-parachain", - "polkadot-runtime-common", - "polkadot-runtime-constants", - "scale-info", - "smallvec", - "sp-api", - "sp-block-builder", - "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "sp-weights", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", -] - -[[package]] -name = "assets-common" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "cumulus-primitives-core", - "frame-support", - "log", - "pallet-asset-conversion", - "pallet-asset-tx-payment", - "pallet-xcm", - "parachains-common", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-runtime", - "sp-std", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", -] - [[package]] name = "async-channel" version = "1.9.0" @@ -812,21 +719,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "casey" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614586263949597dcc18675da12ef9b429135e13628d92eb8b8c6fa50ca5656b" -dependencies = [ - "syn 1.0.109", -] - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" version = "1.0.83" @@ -905,33 +797,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "ciborium" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" - -[[package]] -name = "ciborium-ll" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "cid" version = "0.9.0" @@ -1302,44 +1167,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "criterion" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "futures", - "is-terminal", - "itertools 0.10.5", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "tokio", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools 0.10.5", -] - [[package]] name = "critical-section" version = "1.1.2" @@ -1571,29 +1398,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cumulus-client-consensus-relay-chain" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "async-trait", - "cumulus-client-consensus-common", - "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "futures", - "parking_lot 0.12.1", - "sc-consensus", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-inherents", - "sp-runtime", - "substrate-prometheus-endpoint", - "tracing", -] - [[package]] name = "cumulus-client-network" version = "0.1.0" @@ -2003,122 +1807,9 @@ dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "polkadot-primitives", - "sp-runtime", - "sp-state-machine", - "sp-std", -] - -[[package]] -name = "cumulus-test-relay-validation-worker-provider" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "polkadot-node-core-pvf", - "toml 0.7.8", -] - -[[package]] -name = "cumulus-test-runtime" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "cumulus-pallet-parachain-system", - "cumulus-primitives-core", - "cumulus-primitives-timestamp", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-rpc-runtime-api", - "pallet-balances", - "pallet-glutton", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-block-builder", - "sp-core", - "sp-inherents", - "sp-io", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", -] - -[[package]] -name = "cumulus-test-service" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "async-trait", - "clap", - "criterion", - "cumulus-client-cli", - "cumulus-client-consensus-common", - "cumulus-client-consensus-relay-chain", - "cumulus-client-pov-recovery", - "cumulus-client-service", - "cumulus-pallet-parachain-system", - "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", - "cumulus-relay-chain-inprocess-interface", - "cumulus-relay-chain-interface", - "cumulus-relay-chain-minimal-node", - "cumulus-test-relay-sproof-builder", - "cumulus-test-relay-validation-worker-provider", - "cumulus-test-runtime", - "frame-system", - "frame-system-rpc-runtime-api", - "jsonrpsee", - "pallet-timestamp", - "pallet-transaction-payment", - "parachains-common", - "parity-scale-codec", - "polkadot-cli", - "polkadot-node-subsystem", - "polkadot-overseer", - "polkadot-primitives", - "polkadot-service", - "polkadot-test-service", - "rand 0.8.5", - "sc-basic-authorship", - "sc-block-builder", - "sc-chain-spec", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-executor", - "sc-executor-common", - "sc-executor-wasmtime", - "sc-network", - "sc-service", - "sc-telemetry", - "sc-tracing", - "sc-transaction-pool", - "sc-transaction-pool-api", - "serde", - "sp-api", - "sp-arithmetic", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-io", - "sp-keyring", - "sp-runtime", - "sp-state-machine", - "sp-timestamp", - "sp-tracing", - "sp-trie", - "substrate-test-client", - "tempfile", - "tokio", - "tracing", - "url", + "sp-runtime", + "sp-state-machine", + "sp-std", ] [[package]] @@ -3477,12 +3168,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "handlebars" version = "4.5.0" @@ -3914,66 +3599,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "integration-tests" -version = "0.4.0" -dependencies = [ - "asset-hub-polkadot-runtime", - "cumulus-pallet-xcm", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-core", - "frame-support", - "frame-system", - "itertools 0.11.0", - "macros", - "orml-oracle", - "pallet-assets", - "pallet-balances", - "pallet-collective", - "pallet-democracy 4.0.0-dev", - "pallet-elections-phragmen 5.0.0-dev", - "pallet-funding", - "pallet-im-online", - "pallet-linear-release", - "pallet-membership", - "pallet-message-queue", - "pallet-parachain-staking", - "pallet-scheduler", - "pallet-staking", - "pallet-treasury", - "pallet-vesting", - "pallet-xcm", - "parachain-info", - "parachains-common", - "parity-scale-codec", - "penpal-runtime", - "polimec-base-runtime", - "polimec-common", - "polimec-parachain-runtime", - "polimec-receiver", - "polkadot-core-primitives", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime", - "polkadot-runtime-constants", - "polkadot-runtime-parachains", - "polkadot-service", - "sc-consensus-grandpa", - "scale-info", - "sp-arithmetic", - "sp-authority-discovery", - "sp-consensus-babe", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-emulator", - "xcm-executor", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -5608,12 +5233,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "opaque-debug" version = "0.2.3" @@ -5726,24 +5345,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-asset-conversion" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-asset-tx-payment" version = "4.0.0-dev" @@ -6159,6 +5760,7 @@ dependencies = [ "futures", "itertools 0.11.0", "log", + "macros", "pallet-assets", "pallet-balances", "pallet-insecure-randomness-collective-flip", @@ -6186,24 +5788,6 @@ dependencies = [ "xcm-executor", ] -[[package]] -name = "pallet-glutton" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" -dependencies = [ - "blake2", - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-grandpa" version = "4.0.0-dev" @@ -6383,35 +5967,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-nfts" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" -dependencies = [ - "enumflags2", - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - -[[package]] -name = "pallet-nfts-runtime-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" -dependencies = [ - "frame-support", - "pallet-nfts", - "parity-scale-codec", - "sp-api", -] - [[package]] name = "pallet-nis" version = "4.0.0-dev" @@ -6929,21 +6484,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-uniques" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-utility" version = "4.0.0-dev" @@ -7174,124 +6714,61 @@ dependencies = [ ] [[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.4.1", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "partial_sort" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "pbkdf2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" -dependencies = [ - "crypto-mac 0.11.1", -] - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] - -[[package]] -name = "penpal-runtime" -version = "0.9.27" -dependencies = [ - "cumulus-pallet-aura-ext", - "cumulus-pallet-dmp-queue", - "cumulus-pallet-parachain-system", - "cumulus-pallet-session-benchmarking", - "cumulus-pallet-xcm", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-core", - "cumulus-primitives-timestamp", - "cumulus-primitives-utility", - "frame-benchmarking", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "frame-try-runtime", - "hex-literal 0.4.1", - "log", - "pallet-asset-tx-payment", - "pallet-assets", - "pallet-aura", - "pallet-authorship", - "pallet-balances", - "pallet-collator-selection", - "pallet-session", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-vesting", - "pallet-xcm", - "parachain-info", - "parachains-common", - "parity-scale-codec", - "polimec-common", - "polimec-receiver", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "scale-info", - "smallvec", - "sp-api", - "sp-block-builder", - "sp-consensus-aura", - "sp-core", - "sp-inherents", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", - "xcm", - "xcm-builder", - "xcm-executor", +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "partial_sort" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.1", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", ] [[package]] @@ -7415,34 +6892,6 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" -[[package]] -name = "plotters" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" - -[[package]] -name = "plotters-svg" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" -dependencies = [ - "plotters-backend", -] - [[package]] name = "polimec-base-runtime" version = "0.4.0" @@ -8907,118 +8356,6 @@ dependencies = [ "sp-core", ] -[[package]] -name = "polkadot-test-runtime" -version = "1.0.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v1.0.0#c9ec8c5a15959ce711bb60aa79add58f560d61e9" -dependencies = [ - "bitvec", - "frame-election-provider-support", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-rpc-runtime-api", - "log", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-balances", - "pallet-grandpa", - "pallet-indices", - "pallet-offences", - "pallet-session", - "pallet-staking", - "pallet-staking-reward-curve", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-vesting", - "pallet-xcm", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "rustc-hex", - "scale-info", - "serde", - "serde_derive", - "smallvec", - "sp-api", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-consensus-beefy", - "sp-core", - "sp-inherents", - "sp-io", - "sp-mmr-primitives", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", - "test-runtime-constants", - "xcm", - "xcm-builder", - "xcm-executor", -] - -[[package]] -name = "polkadot-test-service" -version = "1.0.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v1.0.0#c9ec8c5a15959ce711bb60aa79add58f560d61e9" -dependencies = [ - "frame-system", - "futures", - "hex", - "pallet-balances", - "pallet-staking", - "pallet-transaction-payment", - "polkadot-node-primitives", - "polkadot-node-subsystem", - "polkadot-overseer", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-rpc", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "polkadot-service", - "polkadot-test-runtime", - "rand 0.8.5", - "sc-authority-discovery", - "sc-chain-spec", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-consensus-babe", - "sc-consensus-grandpa", - "sc-network", - "sc-service", - "sc-tracing", - "sc-transaction-pool", - "sp-arithmetic", - "sp-authority-discovery", - "sp-blockchain", - "sp-consensus", - "sp-consensus-babe", - "sp-consensus-grandpa", - "sp-core", - "sp-inherents", - "sp-keyring", - "sp-runtime", - "sp-state-machine", - "substrate-test-client", - "tempfile", - "test-runtime-constants", - "tokio", - "tracing-gum", -] - [[package]] name = "polling" version = "3.3.1" @@ -12517,32 +11854,6 @@ dependencies = [ "trie-db", ] -[[package]] -name = "substrate-test-client" -version = "2.0.1" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" -dependencies = [ - "array-bytes", - "async-trait", - "futures", - "parity-scale-codec", - "sc-client-api", - "sc-client-db", - "sc-consensus", - "sc-executor", - "sc-offchain", - "sc-service", - "serde", - "serde_json", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-keyring", - "sp-keystore", - "sp-runtime", - "sp-state-machine", -] - [[package]] name = "substrate-test-utils" version = "4.0.0-dev" @@ -12693,20 +12004,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" -[[package]] -name = "test-runtime-constants" -version = "1.0.0" -source = "git+https://github.com/paritytech/polkadot?branch=release-v1.0.0#c9ec8c5a15959ce711bb60aa79add58f560d61e9" -dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-core", - "sp-runtime", - "sp-weights", -] - [[package]] name = "thiserror" version = "1.0.50" @@ -12843,16 +12140,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -14296,39 +13583,6 @@ dependencies = [ "xcm-executor", ] -[[package]] -name = "xcm-emulator" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus?branch=release-v1.0.0#7935c251f42a41a3e3f61db101af623027676b49" -dependencies = [ - "casey", - "cumulus-pallet-dmp-queue", - "cumulus-pallet-parachain-system", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", - "cumulus-test-relay-sproof-builder", - "cumulus-test-service", - "frame-support", - "frame-system", - "log", - "pallet-balances", - "pallet-message-queue", - "parachain-info", - "parachains-common", - "parity-scale-codec", - "paste", - "polkadot-primitives", - "polkadot-runtime-parachains", - "quote", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-std", - "sp-trie", - "xcm", -] - [[package]] name = "xcm-executor" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index cc14a3de1..9cc0e6e0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ members = [ "nodes/*", "runtimes/*", "pallets/*", - "integration-tests", - "integration-tests/penpal", +# "integration-tests", +# "integration-tests/penpal", "macros", "macros/tests", "polimec-common", diff --git a/nodes/parachain/src/chain_spec/testnet.rs b/nodes/parachain/src/chain_spec/testnet.rs index 658b34a3b..3cf3949df 100644 --- a/nodes/parachain/src/chain_spec/testnet.rs +++ b/nodes/parachain/src/chain_spec/testnet.rs @@ -279,11 +279,10 @@ fn testnet_genesis( mod testing_helpers { use super::*; use macros::generate_accounts; - pub use pallet_funding::{instantiator::UserToUSDBalance, *}; + use pallet_funding::{instantiator::UserToUSDBalance, *}; use polimec_parachain_runtime::AccountId; use sp_core::H256; pub use sp_runtime::{traits::ConstU32, BoundedVec, FixedU128}; - pub const METADATA: &str = r#"METADATA { "whitepaper":"ipfs_url", diff --git a/pallets/funding/Cargo.toml b/pallets/funding/Cargo.toml index 9feba58c9..9d70ac855 100644 --- a/pallets/funding/Cargo.toml +++ b/pallets/funding/Cargo.toml @@ -60,6 +60,7 @@ pallet-assets.workspace = true pallet-linear-release.workspace = true assert_matches2.workspace = true xcm-executor.workspace = true +macros.workspace = true [features] default = [ "std" ] diff --git a/pallets/funding/src/benchmarking.rs b/pallets/funding/src/benchmarking.rs index 74c70c5d0..ec2690852 100644 --- a/pallets/funding/src/benchmarking.rs +++ b/pallets/funding/src/benchmarking.rs @@ -18,20 +18,31 @@ //! Benchmarking setup for Funding pallet -#![cfg(feature = "runtime-benchmarks")] +use sp_runtime::traits::TrailingZeroInput; use super::*; -use crate::{instantiator::*, traits::SetPrices}; +use crate::instantiator::*; use frame_benchmarking::v2::*; -use frame_support::{dispatch::RawOrigin, traits::OriginTrait, Parameter}; +#[cfg(test)] +use frame_support::assert_ok; +use frame_support::{ + dispatch::RawOrigin, + traits::{ + fungible::{InspectHold, MutateHold}, + OriginTrait, + }, + Parameter, +}; #[allow(unused_imports)] use pallet::Pallet as PalletFunding; +use parity_scale_codec::{Decode, Encode}; use polimec_common::ReleaseSchedule; use scale_info::prelude::format; use sp_arithmetic::Percent; use sp_core::H256; +use sp_io::hashing::blake2_256; use sp_runtime::traits::{BlakeTwo256, Get, Member}; -use sp_std::marker::PhantomData; + const METADATA: &str = r#" { "whitepaper":"ipfs_url", @@ -54,6 +65,7 @@ const EDITED_METADATA: &str = r#" const ASSET_DECIMALS: u8 = 10; const US_DOLLAR: u128 = 1_0_000_000_000u128; const ASSET_UNIT: u128 = 1_0_000_000_000u128; +type BenchInstantiator = Instantiator::AllPalletsWithoutSystem, ::RuntimeEvent>; pub fn usdt_id() -> u32 { AcceptedFundingAsset::USDT.to_statemint_id() @@ -126,6 +138,24 @@ where ] } +pub fn full_bids() -> Vec> +where + ::Price: From, + ::Balance: From, + T::Hash: From, +{ + let default_project = default_project::(0, account::>("issuer", 0, 0)); + let total_ct_for_bids = default_project.total_allocation_size.0; + let total_usd_for_bids = default_project.minimum_price.checked_mul_int(total_ct_for_bids).unwrap(); + BenchInstantiator::::generate_bids_from_total_usd( + total_usd_for_bids, + default_project.minimum_price, + default_weights(), + default_bidders::(), + default_bidder_multipliers(), + ) +} + pub fn default_community_contributions() -> Vec> where ::Price: From, @@ -153,6 +183,33 @@ where ] } +pub fn default_remainder_contributions() -> Vec> +where + ::Price: From, + ::Balance: From, +{ + vec![ + ContributionParams::new( + account::>("contributor_1", 0, 0), + (10 * ASSET_UNIT).into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + ContributionParams::new( + account::>("bidder_1", 0, 0), + (60 * ASSET_UNIT).into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + ContributionParams::new( + account::>("evaluator_1", 0, 0), + (30 * ASSET_UNIT).into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + ] +} + pub fn default_weights() -> Vec { vec![20u8, 15u8, 10u8, 25u8, 30u8] } @@ -187,6 +244,112 @@ pub fn default_remainder_contributor_multipliers() -> Vec { vec![1u8, 10u8, 3u8, 2u8, 4u8] } +/// Grab an account, seeded by a name and index. +pub fn string_account( + name: scale_info::prelude::string::String, + index: u32, + seed: u32, +) -> AccountId { + let entropy = (name, index, seed).using_encoded(blake2_256); + Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .expect("infinite length input; no invalid inputs for type; qed") +} + +#[cfg(feature = "std")] +pub fn populate_with_projects(amount: u32, inst: BenchInstantiator) -> BenchInstantiator +where + T: Config + + frame_system::Config::RuntimeEvent> + + pallet_balances::Config>, + ::RuntimeEvent: TryInto> + Parameter + Member, + ::Price: From, + ::Balance: From, + T::Hash: From, + ::AccountId: + Into<<::RuntimeOrigin as OriginTrait>::AccountId> + sp_std::fmt::Debug, + ::Balance: Into>, +{ + let states = vec![ + ProjectStatus::Application, + ProjectStatus::EvaluationRound, + ProjectStatus::AuctionRound(AuctionPhase::English), + ProjectStatus::CommunityRound, + ProjectStatus::RemainderRound, + ProjectStatus::FundingSuccessful, + ] + .into_iter() + .cycle() + .take(amount as usize); + + let instantiation_details = states + .map(|state| { + let nonce = inst.get_new_nonce(); + let issuer_name: String = format!("issuer_{}", nonce); + + let issuer = string_account::>(issuer_name, 0, 0); + TestProjectParams:: { + expected_state: state, + metadata: default_project::(inst.get_new_nonce(), issuer.clone()), + issuer: issuer.clone(), + evaluations: default_evaluations::(), + bids: default_bids::(), + community_contributions: default_community_contributions::(), + remainder_contributions: default_remainder_contributions::(), + } + }) + .collect::>>(); + + async_features::create_multiple_projects_at(inst, instantiation_details).1 +} + +// IMPORTANT: make sure your project starts at (block 1 + `total_vecs_in_storage` - `fully_filled_vecs_from_insertion`) to always have room to insert new vecs +pub fn fill_projects_to_update( + fully_filled_vecs_from_insertion: u32, + mut expected_insertion_block: BlockNumberFor, + maybe_total_vecs_in_storage: Option, +) { + // fill the `ProjectsToUpdate` vectors from @ expected_insertion_block to @ expected_insertion_block+x, to benchmark all the failed insertion attempts + for _ in 0..fully_filled_vecs_from_insertion { + while ProjectsToUpdate::::try_append(expected_insertion_block, (&69u32, UpdateType::EvaluationEnd)).is_ok() { + continue; + } + expected_insertion_block += 1u32.into(); + } + + // sometimes we don't expect to remove anything from storage + if let Some(total_vecs_in_storage) = maybe_total_vecs_in_storage { + // fill `ProjectsToUpdate` with `y` different BlockNumber->Vec items to benchmark deletion of our project from the map + // We keep in mind that we already filled `x` amount of vecs to max capacity + let remaining_vecs = total_vecs_in_storage.saturating_sub(fully_filled_vecs_from_insertion); + if remaining_vecs > 0 { + // we benchmarked this with different values, and it had no impact on the weight, so we use a low value to speed up the benchmark + let items_per_vec = 5u32; + let mut block_number: BlockNumberFor = Zero::zero(); + for _ in 0..remaining_vecs { + // To iterate over all expected items when looking to remove, we need to insert everything _before_ our already stored project's block_number + let mut vec: Vec<(ProjectId, UpdateType)> = ProjectsToUpdate::::get(block_number).to_vec(); + let items_to_fill = items_per_vec - vec.len() as u32; + for _ in 0..items_to_fill { + vec.push((69u32, UpdateType::EvaluationEnd)); + } + let bounded_vec: BoundedVec<(ProjectId, UpdateType), T::MaxProjectsToUpdatePerBlock> = + vec.try_into().unwrap(); + ProjectsToUpdate::::insert(block_number, bounded_vec); + block_number += 1u32.into(); + } + } + } +} + +// returns how much PLMC was minted and held to the user +pub fn make_ct_deposit_for(user: AccountIdOf, project_id: ProjectId) { + let ct_deposit = T::ContributionTokenCurrency::deposit_required(project_id); + // Reserve plmc deposit to create a contribution token account for this project + if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), &user) < ct_deposit { + T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), &user, ct_deposit).unwrap(); + } +} + #[benchmarks( where T: Config + frame_system::Config::RuntimeEvent> + pallet_balances::Config>, @@ -203,13 +366,13 @@ mod benchmarks { impl_benchmark_test_suite!(PalletFunding, crate::mock::new_test_ext(), crate::mock::TestRuntime); - type BenchInstantiator = Instantiator::AllPalletsWithoutSystem, ::RuntimeEvent>; #[benchmark] fn create() { // * setup * let mut inst = BenchInstantiator::::new(None); // real benchmark starts at block 0, and we can't call `events()` at block 0 inst.advance_time(1u32.into()).unwrap(); + let ed = BenchInstantiator::::get_ed(); let issuer = account::>("issuer", 0, 0); @@ -266,7 +429,10 @@ mod benchmarks { } #[benchmark] - fn start_evaluation() { + fn start_evaluation( + // insertion attempts in add_to_update_store. + x: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + ) { // * setup * let mut inst = BenchInstantiator::::new(None); @@ -279,6 +445,16 @@ mod benchmarks { let project_metadata = default_project::(inst.get_new_nonce(), issuer.clone()); let project_id = inst.create_new_project(project_metadata, issuer.clone()); + // start_evaluation fn will try to add an automatic transition 1 block after the last evaluation block + let mut block_number: BlockNumberFor = inst.current_block() + T::EvaluationDuration::get() + One::one(); + // fill the `ProjectsToUpdate` vectors from @ block_number to @ block_number+x, to benchmark all the failed insertion attempts + for _ in 0..x { + while ProjectsToUpdate::::try_append(block_number, (&69u32, UpdateType::EvaluationEnd)).is_ok() { + continue; + } + block_number += 1u32.into(); + } + #[extrinsic_call] start_evaluation(RawOrigin::Signed(issuer), project_id); @@ -303,79 +479,67 @@ mod benchmarks { } #[benchmark] - fn bond_evaluation() { - // setup + fn start_auction_manually( + // Insertion attempts in add_to_update_store. Total amount of storage items iterated through in `ProjectsToUpdate`. Leave one free to make the extrinsic pass + x: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + // Total amount of storage items iterated through in `ProjectsToUpdate` when trying to remove our project in `remove_from_update_store`. + // Upper bound is assumed to be enough + y: Linear<1, 10_000>, + ) { + // * setup * let mut inst = BenchInstantiator::::new(None); - // real benchmark starts at block 0, and we can't call `events()` at block 0 - inst.advance_time(1u32.into()).unwrap(); + // We need to leave enough block numbers to fill `ProjectsToUpdate` before our project insertion + let u32_remaining_vecs: u32 = y.saturating_sub(x); + let time_advance: u32 = 1 + u32_remaining_vecs + 1; + inst.advance_time(time_advance.into()).unwrap(); let issuer = account::>("issuer", 0, 0); - let test_evaluator = account::>("evaluator", 0, 0); - whitelist_account!(test_evaluator); + whitelist_account!(issuer); let project_metadata = default_project::(inst.get_new_nonce(), issuer.clone()); - let test_project_id = inst.create_evaluating_project(project_metadata, issuer); - - let evaluation = UserToUSDBalance::new(test_evaluator.clone(), (50_000 * US_DOLLAR).into()); + let project_id = inst.create_evaluating_project(project_metadata, issuer.clone()); - let plmc_for_evaluating = BenchInstantiator::::calculate_evaluation_plmc_spent(vec![evaluation.clone()]); + let evaluations = default_evaluations(); + let plmc_for_evaluating = BenchInstantiator::::calculate_evaluation_plmc_spent(evaluations.clone()); let existential_plmc: Vec> = plmc_for_evaluating.accounts().existential_deposits(); let ct_account_deposits: Vec> = plmc_for_evaluating.accounts().ct_account_deposits(); inst.mint_plmc_to(existential_plmc); inst.mint_plmc_to(ct_account_deposits); - inst.mint_plmc_to(plmc_for_evaluating.clone()); + inst.mint_plmc_to(plmc_for_evaluating); inst.advance_time(One::one()).unwrap(); + inst.bond_for_users(project_id, evaluations).expect("All evaluations are accepted"); + + inst.advance_time(::EvaluationDuration::get() + One::one()).unwrap(); + + let current_block = inst.current_block(); + // `do_english_auction` fn will try to add an automatic transition 1 block after the last english round block + let insertion_block_number: BlockNumberFor = current_block + T::EnglishAuctionDuration::get() + One::one(); + + fill_projects_to_update::(x, insertion_block_number, Some(y)); #[extrinsic_call] - bond_evaluation(RawOrigin::Signed(test_evaluator.clone()), test_project_id, evaluation.usd_amount); + start_auction(RawOrigin::Signed(issuer), project_id); // * validity checks * // Storage - let stored_evaluation = Evaluations::::iter_prefix_values((test_project_id, test_evaluator.clone())) - .sorted_by(|a, b| a.id.cmp(&b.id)) - .last() - .unwrap(); - - match stored_evaluation { - EvaluationInfo { - project_id, - evaluator, - original_plmc_bond, - current_plmc_bond, - rewarded_or_slashed, - .. - } if project_id == project_id && - evaluator == test_evaluator.clone() && - original_plmc_bond == plmc_for_evaluating[0].plmc_amount && - current_plmc_bond == plmc_for_evaluating[0].plmc_amount && - rewarded_or_slashed.is_none() => {}, - _ => assert!(false, "Evaluation is not stored correctly"), - } - - // Balances - let bonded_plmc = inst.get_reserved_plmc_balances_for( - vec![test_evaluator.clone()], - HoldReason::Evaluation(test_project_id).into(), - )[0] - .plmc_amount; - assert_eq!(bonded_plmc, plmc_for_evaluating[0].plmc_amount); + let stored_details = ProjectsDetails::::get(project_id).unwrap(); + assert_eq!(stored_details.status, ProjectStatus::AuctionRound(AuctionPhase::English)); // Events frame_system::Pallet::::assert_last_event( - Event::::FundsBonded { - project_id: test_project_id, - amount: plmc_for_evaluating[0].plmc_amount, - bonder: test_evaluator.clone(), - } - .into(), + Event::::EnglishAuctionStarted { project_id, when: current_block }.into(), ); } #[benchmark] - fn start_auction() { + fn start_auction_automatically( + // Insertion attempts in add_to_update_store. Total amount of storage items iterated through in `ProjectsToUpdate`. Leave one free to make the extrinsic pass + x: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + // No `y` param because we don't need to remove the automatic transition from storage + ) { // * setup * let mut inst = BenchInstantiator::::new(None); @@ -401,7 +565,23 @@ mod benchmarks { inst.bond_for_users(project_id, evaluations).expect("All evaluations are accepted"); inst.advance_time(::EvaluationDuration::get() + One::one()).unwrap(); - let block_number = frame_system::Pallet::::block_number(); + + let current_block = inst.current_block(); + let automatic_transition_block = + current_block + ::AuctionInitializePeriodDuration::get() + One::one(); + let insertion_block_number: BlockNumberFor = + automatic_transition_block + T::EnglishAuctionDuration::get() + One::one(); + let block_number = insertion_block_number; + + fill_projects_to_update::(x, block_number, None); + + let now = inst.current_block(); + inst.advance_time(automatic_transition_block - now - One::one()).unwrap(); + let now = inst.current_block(); + // we don't use advance time to avoid triggering on_initialize. This benchmark should only measure the extrinsic + // weight and not the whole on_initialize call weight + frame_system::Pallet::::set_block_number(now + One::one()); + #[extrinsic_call] start_auction(RawOrigin::Signed(issuer), project_id); @@ -411,13 +591,216 @@ mod benchmarks { assert_eq!(stored_details.status, ProjectStatus::AuctionRound(AuctionPhase::English)); // Events + let current_block = inst.current_block(); frame_system::Pallet::::assert_last_event( - Event::::EnglishAuctionStarted { project_id, when: block_number.into() }.into(), + Event::::EnglishAuctionStarted { project_id, when: current_block }.into(), ); } + // possible branches: + // - pays ct account deposit + // - we know this happens only if param x = 0, but we cannot fit it in the linear regression + // - is over max evals per user, and needs to unbond the lowest evaluation + // - this case, we know they paid already for ct account deposit + + fn evaluation_setup( + x: u32, + ) -> (BenchInstantiator, ProjectId, UserToUSDBalance, BalanceOf, BalanceOf) + where + ::Balance: From, + ::Price: From, + T::Hash: From, + ::RuntimeEvent: From>, + { + // setup + let mut inst = BenchInstantiator::::new(None); + + // real benchmark starts at block 0, and we can't call `events()` at block 0 + inst.advance_time(1u32.into()).unwrap(); + + let issuer = account::>("issuer", 0, 0); + let test_evaluator = account::>("evaluator", 0, 0); + whitelist_account!(test_evaluator); + + let project_metadata = default_project::(inst.get_new_nonce(), issuer.clone()); + let test_project_id = inst.create_evaluating_project(project_metadata, issuer); + + let existing_evaluation = UserToUSDBalance::new(test_evaluator.clone(), (100 * US_DOLLAR).into()); + let extrinsic_evaluation = UserToUSDBalance::new(test_evaluator.clone(), (1_000 * US_DOLLAR).into()); + let existing_evaluations = vec![existing_evaluation; x as usize]; + + let plmc_for_existing_evaluations = + BenchInstantiator::::calculate_evaluation_plmc_spent(existing_evaluations.clone()); + let plmc_for_extrinsic_evaluation = + BenchInstantiator::::calculate_evaluation_plmc_spent(vec![extrinsic_evaluation.clone()]); + let existential_plmc: Vec> = + plmc_for_extrinsic_evaluation.accounts().existential_deposits(); + let ct_account_deposits: Vec> = + plmc_for_extrinsic_evaluation.accounts().ct_account_deposits(); + + inst.mint_plmc_to(existential_plmc); + inst.mint_plmc_to(ct_account_deposits); + inst.mint_plmc_to(plmc_for_existing_evaluations.clone()); + inst.mint_plmc_to(plmc_for_extrinsic_evaluation.clone()); + + inst.advance_time(One::one()).unwrap(); + + // do "x" evaluations for this user + inst.bond_for_users(test_project_id, existing_evaluations).expect("All evaluations are accepted"); + + let extrinsic_plmc_bonded = plmc_for_extrinsic_evaluation[0].plmc_amount; + let mut total_expected_plmc_bonded = BenchInstantiator::::sum_balance_mappings(vec![ + plmc_for_existing_evaluations.clone(), + plmc_for_extrinsic_evaluation.clone(), + ]); + + // if we are going to unbond evaluations due to being over the limit per user, then deduct them from the total expected plmc bond + if x >= ::MaxEvaluationsPerUser::get() { + total_expected_plmc_bonded -= plmc_for_existing_evaluations[0].plmc_amount + * (x as u128 - ::MaxEvaluationsPerUser::get() as u128 + 1u128).into(); + } + + (inst, test_project_id, extrinsic_evaluation, extrinsic_plmc_bonded, total_expected_plmc_bonded) + } + fn evaluation_verification( + mut inst: BenchInstantiator, + project_id: ProjectId, + evaluation: UserToUSDBalance, + extrinsic_plmc_bonded: BalanceOf, + total_expected_plmc_bonded: BalanceOf, + ) where + ::Balance: From, + ::Price: From, + T::Hash: From, + ::RuntimeEvent: From>, + { + // * validity checks * + // Storage + let stored_evaluation = Evaluations::::iter_prefix_values((project_id, evaluation.account.clone())) + .sorted_by(|a, b| a.id.cmp(&b.id)) + .last() + .unwrap(); + + match stored_evaluation { + EvaluationInfo { + project_id, + evaluator, + original_plmc_bond, + current_plmc_bond, + rewarded_or_slashed, + .. + } if project_id == project_id + && evaluator == evaluation.account.clone() + && original_plmc_bond == extrinsic_plmc_bonded + && current_plmc_bond == extrinsic_plmc_bonded + && rewarded_or_slashed.is_none() => {}, + _ => assert!(false, "Evaluation is not stored correctly"), + } + + // Balances + let bonded_plmc = inst.get_reserved_plmc_balances_for( + vec![evaluation.account.clone()], + HoldReason::Evaluation(project_id).into(), + )[0] + .plmc_amount; + assert_eq!(bonded_plmc, total_expected_plmc_bonded); + + // Events + frame_system::Pallet::::assert_last_event( + Event::::FundsBonded { project_id, amount: extrinsic_plmc_bonded, bonder: evaluation.account.clone() } + .into(), + ); + } + + // - We know how many iterations it does in storage + // - We know that it requires a ct deposit + // - We know that it does not require to unbond the lowest evaluation #[benchmark] - fn bid() { + pub fn first_evaluation() { + // How many other evaluations the user did for that same project + let x = 0; + let (inst, project_id, extrinsic_evaluation, extrinsic_plmc_bonded, total_expected_plmc_bonded) = + evaluation_setup::(x); + + #[extrinsic_call] + evaluate(RawOrigin::Signed(extrinsic_evaluation.account.clone()), project_id, extrinsic_evaluation.usd_amount); + + evaluation_verification::( + inst, + project_id, + extrinsic_evaluation, + extrinsic_plmc_bonded, + total_expected_plmc_bonded, + ); + } + + // - We know that it does not require a ct deposit + // - We know that it does not require to unbond the lowest evaluation. + // - We don't know how many iterations it does in storage (i.e "x") + #[benchmark] + fn second_to_limit_evaluation( + // How many other evaluations the user did for that same project + x: Linear<1, { T::MaxEvaluationsPerUser::get() - 1 }>, + ) { + let (inst, project_id, extrinsic_evaluation, extrinsic_plmc_bonded, total_expected_plmc_bonded) = + evaluation_setup::(x); + + #[extrinsic_call] + evaluate(RawOrigin::Signed(extrinsic_evaluation.account.clone()), project_id, extrinsic_evaluation.usd_amount); + + evaluation_verification::( + inst, + project_id, + extrinsic_evaluation, + extrinsic_plmc_bonded, + total_expected_plmc_bonded, + ); + } + + // - We know how many iterations it does in storage + // - We know that it does not require a ct deposit + // - We know that it requires to unbond the lowest evaluation + #[benchmark] + fn evaluation_over_limit() { + // How many other evaluations the user did for that same project + let x = ::MaxEvaluationsPerUser::get(); + let (inst, project_id, extrinsic_evaluation, extrinsic_plmc_bonded, total_expected_plmc_bonded) = + evaluation_setup::(x); + + #[extrinsic_call] + evaluate(RawOrigin::Signed(extrinsic_evaluation.account.clone()), project_id, extrinsic_evaluation.usd_amount); + + evaluation_verification::( + inst, + project_id, + extrinsic_evaluation, + extrinsic_plmc_bonded, + total_expected_plmc_bonded, + ); + } + + fn bid_setup( + existing_bids_count: u32, + do_perform_bid_calls: u32, + ) -> ( + BenchInstantiator, + ProjectId, + ProjectMetadataOf, + BidParams, + Option>, + Vec>, + Vec>, + BalanceOf, + BalanceOf, + BalanceOf, + BalanceOf, + ) + where + ::Balance: From, + ::Price: From, + T::Hash: From, + ::RuntimeEvent: From>, + { // * setup * let mut inst = BenchInstantiator::::new(None); @@ -432,54 +815,161 @@ mod benchmarks { let project_id = inst.create_auctioning_project(project_metadata.clone(), issuer, default_evaluations::()); - let bid_params = BidParams::new( + let existing_bid = BidParams::new( bidder.clone(), - (50000u128 * ASSET_UNIT).into(), + (100u128 * ASSET_UNIT).into(), 1_u128.into(), - 1u8, + 5u8, AcceptedFundingAsset::USDT, ); - let bid_params = inst.simulate_bids_with_bucket(vec![bid_params], project_id)[0].clone(); - let necessary_plmc: Vec> = - BenchInstantiator::::calculate_auction_plmc_spent(&vec![bid_params.clone()], None); - let existential_deposits: Vec> = necessary_plmc.accounts().existential_deposits(); - let ct_account_deposits = necessary_plmc.accounts().ct_account_deposits(); - let necessary_usdt: Vec> = - BenchInstantiator::::calculate_auction_funding_asset_spent(&vec![bid_params.clone()], None); + let existing_bids = vec![existing_bid; existing_bids_count as usize]; + let existing_bids_post_bucketing = inst.simulate_bids_with_bucket(existing_bids.clone(), project_id); + let plmc_for_existing_bids = + BenchInstantiator::::calculate_auction_plmc_spent(&existing_bids_post_bucketing, None); + + let existential_deposits: Vec> = vec![bidder.clone()].existential_deposits(); + let ct_account_deposits = vec![bidder.clone()].ct_account_deposits(); - inst.mint_plmc_to(necessary_plmc.clone()); + let usdt_for_existing_bids: Vec> = + BenchInstantiator::::calculate_auction_funding_asset_spent(&existing_bids_post_bucketing, None); + let escrow_account = Pallet::::fund_account_id(project_id); + let prev_total_escrow_usdt_locked = + inst.get_free_statemint_asset_balances_for(usdt_id(), vec![escrow_account.clone()]); + + inst.mint_plmc_to(plmc_for_existing_bids.clone()); inst.mint_plmc_to(existential_deposits.clone()); inst.mint_plmc_to(ct_account_deposits.clone()); - inst.mint_statemint_asset_to(necessary_usdt.clone()); - - #[extrinsic_call] - bid(RawOrigin::Signed(bidder.clone()), project_id, bid_params.amount, bid_params.multiplier, bid_params.asset); + inst.mint_statemint_asset_to(usdt_for_existing_bids.clone()); + + // do "x" contributions for this user + inst.bid_for_users(project_id, existing_bids_post_bucketing.clone()); + + // to call do_perform_bid several times, we need the bucket to reach its limit. You can only bid over 10 buckets + // in a single bid, since the increase delta is 10% of the total allocation, and you cannot bid more than the allocation. + let mut ct_amount = (1000u128 * ASSET_UNIT).into(); + let mut maybe_filler_bid = None; + let new_bidder = account::>("new_bidder", 0, 0); + + let mut usdt_for_filler_bidder = vec![UserToStatemintAsset::::new( + new_bidder.clone(), + Zero::zero(), + AcceptedFundingAsset::USDT.to_statemint_id(), + )]; + if do_perform_bid_calls > 0 { + let current_bucket = Buckets::::get(project_id).unwrap(); + // first lets bring the bucket to almost its limit with another bidder: + assert!(new_bidder.clone() != bidder.clone()); + let bid_params = BidParams::new( + new_bidder, + current_bucket.amount_left, + // not used atm + 1_u128.into(), + 1u8, + AcceptedFundingAsset::USDT, + ); + maybe_filler_bid = Some(bid_params.clone()); + let plmc_for_new_bidder = + BenchInstantiator::::calculate_auction_plmc_spent(&vec![bid_params.clone()], None); + let plmc_ed = plmc_for_new_bidder.accounts().existential_deposits(); + let plmc_ct_deposit = plmc_for_new_bidder.accounts().ct_account_deposits(); + let usdt_for_new_bidder = + BenchInstantiator::::calculate_auction_funding_asset_spent(&vec![bid_params.clone()], None); + + inst.mint_plmc_to(plmc_for_new_bidder); + inst.mint_plmc_to(plmc_ed); + inst.mint_plmc_to(plmc_ct_deposit); + inst.mint_statemint_asset_to(usdt_for_new_bidder.clone()); + + inst.bid_for_users(project_id, vec![bid_params]); + + ct_amount = Percent::from_percent(10) + * (project_metadata.total_allocation_size.0 * (do_perform_bid_calls as u128).into()); + usdt_for_filler_bidder = usdt_for_new_bidder; + } + let extrinsic_bid = BidParams::new(bidder.clone(), ct_amount, 1_u128.into(), 1u8, AcceptedFundingAsset::USDT); + let original_extrinsic_bid = extrinsic_bid.clone(); + // we need to call this after bidding `x` amount of times, to get the latest bucket from storage + let extrinsic_bids_post_bucketing = inst.simulate_bids_with_bucket(vec![extrinsic_bid], project_id); + assert_eq!(extrinsic_bids_post_bucketing.len(), (do_perform_bid_calls as usize).max(1usize)); + let plmc_for_extrinsic_bids: Vec> = + BenchInstantiator::::calculate_auction_plmc_spent(&extrinsic_bids_post_bucketing, None); + let usdt_for_extrinsic_bids: Vec> = + BenchInstantiator::::calculate_auction_funding_asset_spent(&extrinsic_bids_post_bucketing, None); + inst.mint_plmc_to(plmc_for_extrinsic_bids.clone()); + inst.mint_statemint_asset_to(usdt_for_extrinsic_bids.clone()); + + let total_free_plmc = existential_deposits[0].plmc_amount; + let total_plmc_participation_bonded = BenchInstantiator::::sum_balance_mappings(vec![ + plmc_for_extrinsic_bids.clone(), + plmc_for_existing_bids.clone(), + ]); + let total_free_usdt = Zero::zero(); + let total_escrow_usdt_locked = BenchInstantiator::::sum_statemint_mappings(vec![ + prev_total_escrow_usdt_locked.clone(), + usdt_for_extrinsic_bids.clone(), + usdt_for_existing_bids.clone(), + usdt_for_filler_bidder.clone(), + ]); + + ( + inst, + project_id, + project_metadata, + original_extrinsic_bid, + maybe_filler_bid, + extrinsic_bids_post_bucketing, + existing_bids_post_bucketing, + total_free_plmc, + total_plmc_participation_bonded, + total_free_usdt, + total_escrow_usdt_locked, + ) + } + fn bid_verification( + mut inst: BenchInstantiator, + project_id: ProjectId, + project_metadata: ProjectMetadataOf, + maybe_filler_bid: Option>, + extrinsic_bids_post_bucketing: Vec>, + existing_bids_post_bucketing: Vec>, + total_free_plmc: BalanceOf, + total_plmc_bonded: BalanceOf, + total_free_usdt: BalanceOf, + total_usdt_locked: BalanceOf, + ) where + ::Balance: From, + ::Price: From, + T::Hash: From, + ::RuntimeEvent: From>, + { // * validity checks * + + let bidder = extrinsic_bids_post_bucketing[0].bidder.clone(); // Storage - let stored_bid = Bids::::iter_prefix_values((project_id, bidder.clone())) - .sorted_by(|a, b| a.id.cmp(&b.id)) - .last() - .unwrap(); - let bid_filter = BidInfoFilter:: { - id: None, - project_id: Some(project_id), - bidder: Some(bidder.clone()), - status: Some(BidStatus::YetUnknown), - original_ct_amount: Some(bid_params.amount), - original_ct_usd_price: Some(bid_params.price), - final_ct_amount: Some(bid_params.amount), - final_ct_usd_price: Some(bid_params.price), - funding_asset: Some(AcceptedFundingAsset::USDT), - funding_asset_amount_locked: Some(necessary_usdt[0].asset_amount), - multiplier: Some(bid_params.multiplier), - plmc_bond: Some(necessary_plmc[0].plmc_amount), - plmc_vesting_info: Some(None), - when: None, - funds_released: Some(false), - ct_minted: Some(false), - }; - assert!(bid_filter.matches_bid(&stored_bid)); + for bid_params in extrinsic_bids_post_bucketing.clone() { + let bid_filter = BidInfoFilter:: { + id: None, + project_id: Some(project_id), + bidder: Some(bidder.clone()), + status: Some(BidStatus::YetUnknown), + original_ct_amount: Some(bid_params.amount), + original_ct_usd_price: Some(bid_params.price), + final_ct_amount: Some(bid_params.amount), + final_ct_usd_price: Some(bid_params.price), + funding_asset: Some(AcceptedFundingAsset::USDT), + funding_asset_amount_locked: None, + multiplier: Some(bid_params.multiplier), + plmc_bond: None, + plmc_vesting_info: Some(None), + when: None, + funds_released: Some(false), + ct_minted: Some(false), + }; + Bids::::iter_prefix_values((project_id, bidder.clone())) + .find(|stored_bid| bid_filter.matches_bid(stored_bid)) + .expect("bid not found"); + } // Bucket Storage Check let bucket_delta_amount = Percent::from_percent(10) * project_metadata.total_allocation_size.0; @@ -492,7 +982,15 @@ mod benchmarks { bucket_delta_amount, ); - starting_bucket.update(bid_params.amount); + for bid_params in existing_bids_post_bucketing.clone() { + starting_bucket.update(bid_params.amount); + } + if let Some(bid_params) = maybe_filler_bid { + starting_bucket.update(bid_params.amount); + } + for bid_params in extrinsic_bids_post_bucketing.clone() { + starting_bucket.update(bid_params.amount); + } let current_bucket = Buckets::::get(project_id).unwrap(); assert_eq!(current_bucket, starting_bucket); @@ -501,32 +999,153 @@ mod benchmarks { let bonded_plmc = inst .get_reserved_plmc_balances_for(vec![bidder.clone()], HoldReason::Participation(project_id).into())[0] .plmc_amount; - assert_eq!(bonded_plmc, necessary_plmc[0].plmc_amount); + assert_eq!(bonded_plmc, total_plmc_bonded); let free_plmc = inst.get_free_plmc_balances_for(vec![bidder.clone()])[0].plmc_amount; - assert_eq!(free_plmc, existential_deposits[0].plmc_amount); + assert_eq!(free_plmc, total_free_plmc); + + let escrow_account = Pallet::::fund_account_id(project_id); + let locked_usdt = + inst.get_free_statemint_asset_balances_for(usdt_id(), vec![escrow_account.clone()])[0].asset_amount; + assert_eq!(locked_usdt, total_usdt_locked); let free_usdt = inst.get_free_statemint_asset_balances_for(usdt_id(), vec![bidder])[0].asset_amount; - assert_eq!(free_usdt, 0.into()); + assert_eq!(free_usdt, total_free_usdt); // Events - frame_system::Pallet::::assert_last_event( - Event::Bid { - project_id, - amount: bid_params.amount, - price: bid_params.price, - multiplier: bid_params.multiplier, - } - .into(), + for bid_params in extrinsic_bids_post_bucketing { + frame_system::Pallet::::assert_has_event( + Event::Bid { + project_id, + amount: bid_params.amount, + price: bid_params.price, + multiplier: bid_params.multiplier, + } + .into(), + ); + } + } + + #[benchmark] + fn bid_no_ct_deposit( + // amount of already made bids by the same user + x: Linear<0, { T::MaxBidsPerUser::get() - 1 }>, + // amount of times where `perform_bid` is called (i.e how many buckets) + y: Linear<0, 10>, + ) { + let ( + inst, + project_id, + project_metadata, + original_extrinsic_bid, + maybe_filler_bid, + extrinsic_bids_post_bucketing, + existing_bids_post_bucketing, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + ) = bid_setup::(x, y); + + make_ct_deposit_for::(original_extrinsic_bid.bidder.clone(), project_id); + + #[extrinsic_call] + bid( + RawOrigin::Signed(original_extrinsic_bid.bidder.clone()), + project_id, + original_extrinsic_bid.amount, + original_extrinsic_bid.multiplier, + original_extrinsic_bid.asset, + ); + + bid_verification::( + inst, + project_id, + project_metadata, + maybe_filler_bid, + extrinsic_bids_post_bucketing, + existing_bids_post_bucketing, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, ); } #[benchmark] - fn contribute() { + fn bid_with_ct_deposit( + // amount of times where `perform_bid` is called (i.e how many buckets) + y: Linear<0, 10>, + ) { + // if x were > 0, then the ct deposit would already be paid + let x = 0; + let ( + inst, + project_id, + project_metadata, + original_extrinsic_bid, + maybe_filler_bid, + extrinsic_bids_post_bucketing, + existing_bids_post_bucketing, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + ) = bid_setup::(x, y); + + #[extrinsic_call] + bid( + RawOrigin::Signed(original_extrinsic_bid.bidder.clone()), + project_id, + original_extrinsic_bid.amount, + original_extrinsic_bid.multiplier, + original_extrinsic_bid.asset, + ); + + bid_verification::( + inst, + project_id, + project_metadata, + maybe_filler_bid, + extrinsic_bids_post_bucketing, + existing_bids_post_bucketing, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + ); + } + + fn contribution_setup( + x: u32, + ends_round: Option<(u32, u32)>, + ) -> ( + BenchInstantiator, + ProjectId, + ProjectMetadataOf, + ContributionParams, + BalanceOf, + BalanceOf, + BalanceOf, + BalanceOf, + BalanceOf, + ) + where + ::Balance: From, + ::Price: From, + T::Hash: From, + ::RuntimeEvent: From>, + { // setup let mut inst = BenchInstantiator::::new(None); - // real benchmark starts at block 0, and we can't call `events()` at block 0 - inst.advance_time(1u32.into()).unwrap(); + + // We need to leave enough block numbers to fill `ProjectsToUpdate` before our project insertion + let mut time_advance: u32 = 1; + if let Some((y, z)) = ends_round { + let u32_remaining_vecs: u32 = z.saturating_sub(y); + time_advance += u32_remaining_vecs + 1; + } + inst.advance_time(time_advance.into()).unwrap(); let issuer = account::>("issuer", 0, 0); let contributor = account::>("contributor", 0, 0); @@ -538,94 +1157,484 @@ mod benchmarks { project_metadata.clone(), issuer, default_evaluations::(), - default_bids::(), + full_bids::(), ); let price = inst.get_project_details(project_id).weighted_average_price.unwrap(); - let contribution_params = - ContributionParams::new(contributor.clone(), (100 * ASSET_UNIT).into(), 1u8, AcceptedFundingAsset::USDT); - let necessary_plmc = - BenchInstantiator::::calculate_contributed_plmc_spent(vec![contribution_params.clone()], price); - let existential_deposits: Vec> = necessary_plmc.accounts().existential_deposits(); - let ct_account_deposits: Vec> = necessary_plmc.accounts().ct_account_deposits(); - let necessary_usdt = - BenchInstantiator::::calculate_contributed_funding_asset_spent(vec![contribution_params.clone()], price); - - inst.mint_plmc_to(necessary_plmc.clone()); + let existing_amount: BalanceOf = (50 * ASSET_UNIT).into(); + let extrinsic_amount: BalanceOf = if ends_round.is_some() { + project_metadata.total_allocation_size.0 + - existing_amount * (x.min(::MaxContributionsPerUser::get() - 1) as u128).into() + } else { + (100 * ASSET_UNIT).into() + }; + let existing_contribution = + ContributionParams::new(contributor.clone(), existing_amount, 1u8, AcceptedFundingAsset::USDT); + let extrinsic_contribution = + ContributionParams::new(contributor.clone(), extrinsic_amount, 1u8, AcceptedFundingAsset::USDT); + let existing_contributions = vec![existing_contribution; x as usize]; + + let mut total_ct_sold: BalanceOf = existing_amount * (x as u128).into() + extrinsic_amount; + + let plmc_for_existing_contributions = + BenchInstantiator::::calculate_contributed_plmc_spent(existing_contributions.clone(), price); + let plmc_for_extrinsic_contribution = + BenchInstantiator::::calculate_contributed_plmc_spent(vec![extrinsic_contribution.clone()], price); + let usdt_for_existing_contributions = + BenchInstantiator::::calculate_contributed_funding_asset_spent(existing_contributions.clone(), price); + let usdt_for_extrinsic_contribution = BenchInstantiator::::calculate_contributed_funding_asset_spent( + vec![extrinsic_contribution.clone()], + price, + ); + + let existential_deposits: Vec> = + plmc_for_extrinsic_contribution.accounts().existential_deposits(); + let ct_account_deposits: Vec> = + plmc_for_extrinsic_contribution.accounts().ct_account_deposits(); + + let escrow_account = Pallet::::fund_account_id(project_id); + let prev_total_usdt_locked = + inst.get_free_statemint_asset_balances_for(usdt_id(), vec![escrow_account.clone()]); + + inst.mint_plmc_to(plmc_for_existing_contributions.clone()); + inst.mint_plmc_to(plmc_for_extrinsic_contribution.clone()); inst.mint_plmc_to(existential_deposits.clone()); inst.mint_plmc_to(ct_account_deposits.clone()); - inst.mint_statemint_asset_to(necessary_usdt.clone()); + inst.mint_statemint_asset_to(usdt_for_existing_contributions.clone()); + inst.mint_statemint_asset_to(usdt_for_extrinsic_contribution.clone()); + + // do "x" contributions for this user + inst.contribute_for_users(project_id, existing_contributions).expect("All contributions are accepted"); + + let mut total_plmc_bonded = BenchInstantiator::::sum_balance_mappings(vec![ + plmc_for_existing_contributions.clone(), + plmc_for_extrinsic_contribution.clone(), + ]); + let mut total_usdt_locked = BenchInstantiator::::sum_statemint_mappings(vec![ + prev_total_usdt_locked, + usdt_for_existing_contributions.clone(), + usdt_for_extrinsic_contribution.clone(), + ]); + + let over_limit_count = x.saturating_sub(::MaxContributionsPerUser::get() - 1); + + let mut total_free_plmc = existential_deposits[0].plmc_amount; + let mut total_free_usdt = Zero::zero(); + + if x > 0 { + let plmc_returned = plmc_for_existing_contributions[0].plmc_amount * (over_limit_count as u128).into(); + total_plmc_bonded -= plmc_returned; + + let usdt_returned = usdt_for_existing_contributions[0].asset_amount * (over_limit_count as u128).into(); + total_usdt_locked -= usdt_returned; + total_ct_sold -= existing_amount * (over_limit_count as u128).into(); + total_free_plmc += plmc_returned; + total_free_usdt += usdt_returned; + } - let contribution_id = NextContributionId::::get(); + if let Some((fully_filled_vecs_from_insertion, total_vecs_in_storage)) = ends_round { + // if all CTs are sold, next round is scheduled for next block (either remainder or success) + let expected_insertion_block = inst.current_block() + One::one(); + fill_projects_to_update::( + fully_filled_vecs_from_insertion, + expected_insertion_block, + Some(total_vecs_in_storage), + ); + } - #[extrinsic_call] - contribute( - RawOrigin::Signed(contributor.clone()), + ( + inst, project_id, - contribution_params.amount, - contribution_params.multiplier, - contribution_params.asset, - ); + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) + } + fn contribution_verification( + mut inst: BenchInstantiator, + project_id: ProjectId, + project_metadata: ProjectMetadataOf, + extrinsic_contribution: ContributionParams, + total_free_plmc: BalanceOf, + total_plmc_bonded: BalanceOf, + total_free_usdt: BalanceOf, + total_usdt_locked: BalanceOf, + total_ct_sold: BalanceOf, + ) where + ::Balance: From, + ::Price: From, + T::Hash: From, + ::RuntimeEvent: From>, + { // * validity checks * // Storage + let contributor = extrinsic_contribution.contributor.clone(); let stored_contribution = Contributions::::iter_prefix_values((project_id, contributor.clone())) .sorted_by(|a, b| a.id.cmp(&b.id)) .last() .unwrap(); - let contribution = ContributionInfoOf:: { - id: contribution_id, - project_id, - contributor: contributor.clone(), - ct_amount: contribution_params.amount, - usd_contribution_amount: necessary_usdt[0].asset_amount, - multiplier: contribution_params.multiplier, - funding_asset: contribution_params.asset, - funding_asset_amount: necessary_usdt[0].asset_amount, - plmc_bond: necessary_plmc[0].plmc_amount, - plmc_vesting_info: None, - funds_released: false, - ct_minted: false, - ct_migration_status: MigrationStatus::NotStarted, - }; - assert_eq!(stored_contribution, contribution); - - assert_eq!(NextContributionId::::get(), contribution_id.saturating_add(One::one())); + match stored_contribution { + ContributionInfoOf:: { project_id, contributor, ct_amount, .. } + if project_id == project_id + && contributor == contributor + && ct_amount == extrinsic_contribution.amount => {}, + _ => { + assert!(false, "Contribution is not stored correctly") + }, + } let stored_project_details = ProjectsDetails::::get(project_id).unwrap(); assert_eq!( stored_project_details.remaining_contribution_tokens.1, - project_metadata.total_allocation_size.1.saturating_sub(contribution_params.amount) + project_metadata.total_allocation_size.1.saturating_sub(total_ct_sold) ); // Balances let bonded_plmc = inst .get_reserved_plmc_balances_for(vec![contributor.clone()], HoldReason::Participation(project_id).into())[0] .plmc_amount; - assert_eq!(bonded_plmc, necessary_plmc[0].plmc_amount); + assert_eq!(bonded_plmc, total_plmc_bonded); let free_plmc = inst.get_free_plmc_balances_for(vec![contributor.clone()])[0].plmc_amount; - assert_eq!(free_plmc, existential_deposits[0].plmc_amount); + assert_eq!(free_plmc, total_free_plmc); + + let escrow_account = Pallet::::fund_account_id(project_id); + let locked_usdt = + inst.get_free_statemint_asset_balances_for(usdt_id(), vec![escrow_account.clone()])[0].asset_amount; + assert_eq!(locked_usdt, total_usdt_locked); let free_usdt = inst.get_free_statemint_asset_balances_for(usdt_id(), vec![contributor.clone()])[0].asset_amount; - assert_eq!(free_usdt, 0.into()); + assert_eq!(free_usdt, total_free_usdt); // Events frame_system::Pallet::::assert_last_event( Event::Contribution { project_id, contributor, - amount: contribution_params.amount, - multiplier: contribution_params.multiplier, + amount: extrinsic_contribution.amount, + multiplier: extrinsic_contribution.multiplier, } .into(), ); } + // - We know how many iterations it does in storage + // - We know it requires no CT deposit (remainder round only) + // - We know that it does not require to unbond the lowest contribution + // - We know it doesn't end the round + #[benchmark] + fn first_contribution_with_ct_deposit() { + // How many other contributions the user did for that same project + let x = 0; + let ends_round = None; + + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + + // - We know how many iterations it does in storage + // - We know it requires a CT deposit + // - We know that it does not require to unbond the lowest contribution + // - We know it doesn't end the round + #[benchmark] + fn first_contribution_no_ct_deposit() { + // How many other contributions the user did for that same project + let x = 0; + let ends_round = None; + + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + make_ct_deposit_for::(extrinsic_contribution.contributor.clone(), project_id); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + #[benchmark] + fn first_contribution_ends_round_with_ct_deposit( + // Insertion attempts in add_to_update_store. Total amount of storage items iterated through in `ProjectsToUpdate`. Leave one free to make the extrinsic pass + y: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + // Total amount of storage items iterated through in `ProjectsToUpdate` when trying to remove our project in `remove_from_update_store`. + // Upper bound is assumed to be enough + z: Linear<1, 10_000>, + ) { + // How many other contributions the user did for that same project + let x = 0; + let ends_round = Some((y, z)); + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + + #[benchmark] + fn first_contribution_ends_round_no_ct_deposit( + // Insertion attempts in add_to_update_store. Total amount of storage items iterated through in `ProjectsToUpdate`. Leave one free to make the extrinsic pass + y: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + // Total amount of storage items iterated through in `ProjectsToUpdate` when trying to remove our project in `remove_from_update_store`. + // Upper bound is assumed to be enough + z: Linear<1, 10_000>, + ) { + // How many other contributions the user did for that same project + let x = 0; + let ends_round = Some((y, z)); + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + make_ct_deposit_for::(extrinsic_contribution.contributor.clone(), project_id); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + + #[benchmark] + fn second_to_limit_contribution( + // How many other contributions the user did for that same project + x: Linear<1, { T::MaxContributionsPerUser::get() - 1 }>, + ) { + let ends_round = None; + + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + + #[benchmark] + fn second_to_limit_contribution_ends_round( + // How many other contributions the user did for that same project + x: Linear<1, { T::MaxContributionsPerUser::get() - 1 }>, + // Insertion attempts in add_to_update_store. Total amount of storage items iterated through in `ProjectsToUpdate`. Leave one free to make the extrinsic pass + y: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + // Total amount of storage items iterated through in `ProjectsToUpdate` when trying to remove our project in `remove_from_update_store`. + // Upper bound is assumed to be enough + z: Linear<1, 10_000>, + ) { + let ends_round = Some((y, z)); + + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + + #[benchmark] + fn contribution_over_limit() { + // How many other contributions the user did for that same project + let x = ::MaxContributionsPerUser::get(); + let ends_round = None; + + let ( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ) = contribution_setup::(x, ends_round); + + #[extrinsic_call] + contribute( + RawOrigin::Signed(extrinsic_contribution.contributor.clone()), + project_id, + extrinsic_contribution.amount, + extrinsic_contribution.multiplier, + extrinsic_contribution.asset, + ); + + contribution_verification::( + inst, + project_id, + project_metadata, + extrinsic_contribution, + total_free_plmc, + total_plmc_bonded, + total_free_usdt, + total_usdt_locked, + total_ct_sold, + ); + } + #[benchmark] fn evaluation_unbond_for() { // setup @@ -660,7 +1669,7 @@ mod benchmarks { inst.execute(|| { PalletFunding::::evaluation_reward_payout_for( - ::RuntimeOrigin::signed(evaluator.clone().into()), + ::RuntimeOrigin::signed(evaluator.clone()), project_id, evaluator.clone(), evaluation_to_unbond.id, @@ -695,6 +1704,165 @@ mod benchmarks { ); } + #[benchmark] + fn evaluation_reward_payout_for_with_ct_account_creation() { + // setup + let mut inst = BenchInstantiator::::new(None); + + // real benchmark starts at block 0, and we can't call `events()` at block 0 + inst.advance_time(1u32.into()).unwrap(); + + let issuer = account::>("issuer", 0, 0); + let evaluations: Vec> = vec![ + UserToUSDBalance::new(account::>("evaluator_bench", 0, 0), (50_000 * US_DOLLAR).into()), + UserToUSDBalance::new(account::>("evaluator_bench", 0, 0), (25_000 * US_DOLLAR).into()), + UserToUSDBalance::new(account::>("evaluator_3", 0, 0), (32_000 * US_DOLLAR).into()), + ]; + let evaluator: AccountIdOf = evaluations[0].account.clone(); + whitelist_account!(evaluator); + + let project_id = inst.create_finished_project( + default_project::(inst.get_new_nonce(), issuer.clone()), + issuer, + evaluations, + default_bids::(), + default_community_contributions::(), + vec![], + ); + + inst.advance_time(::SuccessToSettlementTime::get()).unwrap(); + assert_eq!( + inst.get_project_details(project_id).cleanup, + Cleaner::Success(CleanerState::Initialized(PhantomData)) + ); + + let evaluation_to_unbond = + inst.execute(|| Evaluations::::iter_prefix_values((project_id, evaluator.clone())).next().unwrap()); + + #[extrinsic_call] + evaluation_reward_payout_for( + RawOrigin::Signed(evaluator.clone()), + project_id, + evaluator.clone(), + evaluation_to_unbond.id, + ); + + // * validity checks * + // Storage + let stored_evaluation = + Evaluations::::get((project_id, evaluator.clone(), evaluation_to_unbond.id)).unwrap(); + assert!(stored_evaluation.rewarded_or_slashed.is_some()); + + // Balances + let project_details = ProjectsDetails::::get(project_id).unwrap(); + let reward_info = match project_details.evaluation_round_info.evaluators_outcome { + EvaluatorsOutcome::Rewarded(reward_info) => reward_info, + _ => panic!("EvaluatorsOutcome should be Rewarded"), + }; + let total_reward = + BenchInstantiator::::calculate_total_reward_for_evaluation(stored_evaluation.clone(), reward_info); + let ct_amount = inst.get_ct_asset_balances_for(project_id, vec![evaluator.clone()])[0]; + assert_eq!(ct_amount, total_reward); + + // Events + frame_system::Pallet::::assert_last_event( + Event::EvaluationRewarded { + project_id, + evaluator: evaluator.clone(), + id: stored_evaluation.id, + amount: total_reward, + caller: evaluator, + } + .into(), + ); + } + + #[benchmark] + fn evaluation_reward_payout_for_no_ct_account_creation() { + // setup + let mut inst = BenchInstantiator::::new(None); + + // real benchmark starts at block 0, and we can't call `events()` at block 0 + inst.advance_time(1u32.into()).unwrap(); + + let issuer = account::>("issuer", 0, 0); + let evaluations: Vec> = vec![ + UserToUSDBalance::new(account::>("evaluator_1", 0, 0), (50_000 * US_DOLLAR).into()), + UserToUSDBalance::new(account::>("evaluator_1", 0, 0), (25_000 * US_DOLLAR).into()), + UserToUSDBalance::new(account::>("evaluator_3", 0, 0), (32_000 * US_DOLLAR).into()), + ]; + let evaluator: AccountIdOf = evaluations[0].account.clone(); + whitelist_account!(evaluator); + + let project_id = inst.create_finished_project( + default_project::(inst.get_new_nonce(), issuer.clone()), + issuer, + evaluations, + default_bids::(), + default_community_contributions::(), + vec![], + ); + + inst.advance_time(::SuccessToSettlementTime::get()).unwrap(); + assert_eq!( + inst.get_project_details(project_id).cleanup, + Cleaner::Success(CleanerState::Initialized(PhantomData)) + ); + + let mut evaluations_to_unbond = + inst.execute(|| Evaluations::::iter_prefix_values((project_id, evaluator.clone()))); + + let pre_evaluation = evaluations_to_unbond.next().unwrap(); + let bench_evaluation = evaluations_to_unbond.next().unwrap(); + + Pallet::::evaluation_reward_payout_for( + RawOrigin::Signed(evaluator.clone()).into(), + project_id, + evaluator.clone(), + pre_evaluation.id, + ) + .unwrap(); + + #[extrinsic_call] + evaluation_reward_payout_for( + RawOrigin::Signed(evaluator.clone()), + project_id, + evaluator.clone(), + bench_evaluation.id, + ); + + // * validity checks * + // Storage + let stored_evaluation = Evaluations::::get((project_id, evaluator.clone(), bench_evaluation.id)).unwrap(); + assert!(stored_evaluation.rewarded_or_slashed.is_some()); + + // Balances + let project_details = ProjectsDetails::::get(project_id).unwrap(); + let reward_info = match project_details.evaluation_round_info.evaluators_outcome { + EvaluatorsOutcome::Rewarded(reward_info) => reward_info, + _ => panic!("EvaluatorsOutcome should be Rewarded"), + }; + + let pre_reward = + BenchInstantiator::::calculate_total_reward_for_evaluation(pre_evaluation.clone(), reward_info.clone()); + let bench_reward = + BenchInstantiator::::calculate_total_reward_for_evaluation(bench_evaluation.clone(), reward_info); + let ct_amount = inst.get_ct_asset_balances_for(project_id, vec![evaluator.clone()])[0]; + assert_eq!(ct_amount, pre_reward + bench_reward); + + // Events + frame_system::Pallet::::assert_last_event( + Event::EvaluationRewarded { + project_id, + evaluator: evaluator.clone(), + id: stored_evaluation.id, + amount: bench_reward, + caller: evaluator, + } + .into(), + ); + } + #[benchmark] fn evaluation_slash_for() { // setup @@ -779,7 +1947,7 @@ mod benchmarks { } #[benchmark] - fn evaluation_reward_payout_for() { + fn bid_ct_mint_for_with_ct_account_creation() { // setup let mut inst = BenchInstantiator::::new(None); @@ -787,15 +1955,15 @@ mod benchmarks { inst.advance_time(1u32.into()).unwrap(); let issuer = account::>("issuer", 0, 0); - let evaluations = default_evaluations::(); - let evaluator = evaluations[0].account.clone(); - whitelist_account!(evaluator); + let bids = default_bids::(); + let bidder = bids[0].bidder.clone(); + whitelist_account!(bidder); let project_id = inst.create_finished_project( default_project::(inst.get_new_nonce(), issuer.clone()), issuer, - evaluations, - default_bids::(), + default_evaluations::(), + bids, default_community_contributions::(), vec![], ); @@ -806,49 +1974,30 @@ mod benchmarks { Cleaner::Success(CleanerState::Initialized(PhantomData)) ); - let evaluation_to_unbond = - inst.execute(|| Evaluations::::iter_prefix_values((project_id, evaluator.clone())).next().unwrap()); + let bid_to_mint_ct = + inst.execute(|| Bids::::iter_prefix_values((project_id, bidder.clone())).next().unwrap()); #[extrinsic_call] - evaluation_reward_payout_for( - RawOrigin::Signed(evaluator.clone()), - project_id, - evaluator.clone(), - evaluation_to_unbond.id, - ); + bid_ct_mint_for(RawOrigin::Signed(bidder.clone()), project_id, bidder.clone(), bid_to_mint_ct.id); // * validity checks * // Storage - let stored_evaluation = - Evaluations::::get((project_id, evaluator.clone(), evaluation_to_unbond.id)).unwrap(); - assert!(stored_evaluation.rewarded_or_slashed.is_some()); + let stored_bid = Bids::::get((project_id, bidder.clone(), bid_to_mint_ct.id)).unwrap(); + assert!(stored_bid.ct_minted); // Balances - let project_details = ProjectsDetails::::get(project_id).unwrap(); - let reward_info = match project_details.evaluation_round_info.evaluators_outcome { - EvaluatorsOutcome::Rewarded(reward_info) => reward_info, - _ => panic!("EvaluatorsOutcome should be Rewarded"), - }; - let total_reward = - BenchInstantiator::::calculate_total_reward_for_evaluation(stored_evaluation.clone(), reward_info); - let ct_amount = inst.get_ct_asset_balances_for(project_id, vec![evaluator.clone()])[0]; - assert_eq!(ct_amount, total_reward); + let ct_amount = inst.get_ct_asset_balances_for(project_id, vec![bidder.clone()])[0]; + assert_eq!(stored_bid.final_ct_amount, ct_amount); // Events frame_system::Pallet::::assert_last_event( - Event::EvaluationRewarded { - project_id, - evaluator: evaluator.clone(), - id: stored_evaluation.id, - amount: total_reward, - caller: evaluator, - } - .into(), + Event::ContributionTokenMinted { releaser: bidder.clone(), project_id, claimer: bidder, amount: ct_amount } + .into(), ); } #[benchmark] - fn bid_ct_mint_for() { + fn bid_ct_mint_for_no_ct_account_creation() { // setup let mut inst = BenchInstantiator::::new(None); @@ -856,7 +2005,22 @@ mod benchmarks { inst.advance_time(1u32.into()).unwrap(); let issuer = account::>("issuer", 0, 0); - let bids = default_bids::(); + let bids: Vec> = vec![ + BidParams::new( + account::>("bidder_1", 0, 0), + (40_000 * ASSET_UNIT).into(), + 1_u128.into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + BidParams::new( + account::>("bidder_1", 0, 0), + (5_000 * ASSET_UNIT).into(), + 1_u128.into(), + 7u8, + AcceptedFundingAsset::USDT, + ), + ]; let bidder = bids[0].bidder.clone(); whitelist_account!(bidder); @@ -875,30 +2039,45 @@ mod benchmarks { Cleaner::Success(CleanerState::Initialized(PhantomData)) ); - let bid_to_mint_ct = - inst.execute(|| Bids::::iter_prefix_values((project_id, bidder.clone())).next().unwrap()); + let mut bids_to_mint_ct = inst.execute(|| Bids::::iter_prefix_values((project_id, bidder.clone()))); + + let pre_bid_to_mint_ct = bids_to_mint_ct.next().unwrap(); + let bench_bid_to_mint_ct = bids_to_mint_ct.next().unwrap(); + + Pallet::::bid_ct_mint_for( + RawOrigin::Signed(bidder.clone()).into(), + project_id, + bidder.clone(), + pre_bid_to_mint_ct.id, + ) + .unwrap(); #[extrinsic_call] - bid_ct_mint_for(RawOrigin::Signed(bidder.clone()), project_id, bidder.clone(), bid_to_mint_ct.id); + bid_ct_mint_for(RawOrigin::Signed(bidder.clone()), project_id, bidder.clone(), bench_bid_to_mint_ct.id); // * validity checks * // Storage - let stored_bid = Bids::::get((project_id, bidder.clone(), bid_to_mint_ct.id)).unwrap(); + let stored_bid = Bids::::get((project_id, bidder.clone(), bench_bid_to_mint_ct.id)).unwrap(); assert!(stored_bid.ct_minted); // Balances let ct_amount = inst.get_ct_asset_balances_for(project_id, vec![bidder.clone()])[0]; - assert_eq!(stored_bid.final_ct_amount, ct_amount); + assert_eq!(ct_amount, pre_bid_to_mint_ct.final_ct_amount + stored_bid.final_ct_amount); // Events frame_system::Pallet::::assert_last_event( - Event::ContributionTokenMinted { releaser: bidder.clone(), project_id, claimer: bidder, amount: ct_amount } - .into(), + Event::ContributionTokenMinted { + releaser: bidder.clone(), + project_id, + claimer: bidder, + amount: bench_bid_to_mint_ct.final_ct_amount, + } + .into(), ); } #[benchmark] - fn contribution_ct_mint_for() { + fn contribution_ct_mint_for_with_ct_account_creation() { // setup let mut inst = BenchInstantiator::::new(None); @@ -958,6 +2137,97 @@ mod benchmarks { ); } + #[benchmark] + fn contribution_ct_mint_for_no_ct_account_creation() { + // setup + let mut inst = BenchInstantiator::::new(None); + + // real benchmark starts at block 0, and we can't call `events()` at block 0 + inst.advance_time(1u32.into()).unwrap(); + + let issuer = account::>("issuer", 0, 0); + let contributions: Vec> = vec![ + ContributionParams::new( + account::>("contributor_1", 0, 0), + (10_000 * ASSET_UNIT).into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + ContributionParams::new( + account::>("contributor_1", 0, 0), + (6_000 * ASSET_UNIT).into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + ContributionParams::new( + account::>("contributor_3", 0, 0), + (30_000 * ASSET_UNIT).into(), + 1u8, + AcceptedFundingAsset::USDT, + ), + ]; + let contributor = contributions[0].contributor.clone(); + whitelist_account!(contributor); + + let project_id = inst.create_finished_project( + default_project::(inst.get_new_nonce(), issuer.clone()), + issuer, + default_evaluations::(), + default_bids::(), + contributions, + vec![], + ); + + inst.advance_time(::SuccessToSettlementTime::get()).unwrap(); + assert_eq!( + inst.get_project_details(project_id).cleanup, + Cleaner::Success(CleanerState::Initialized(PhantomData)) + ); + + let mut contributions_to_mint_ct = + inst.execute(|| Contributions::::iter_prefix_values((project_id, contributor.clone()))); + + let pre_contribution_to_mint_ct = contributions_to_mint_ct.next().unwrap(); + let bench_contribution_to_mint_ct = contributions_to_mint_ct.next().unwrap(); + + Pallet::::contribution_ct_mint_for( + RawOrigin::Signed(contributor.clone()).into(), + project_id, + contributor.clone(), + pre_contribution_to_mint_ct.id, + ) + .unwrap(); + + #[extrinsic_call] + contribution_ct_mint_for( + RawOrigin::Signed(contributor.clone()), + project_id, + contributor.clone(), + bench_contribution_to_mint_ct.id, + ); + + // * validity checks * + // Storage + let stored_contribution = + Contributions::::get((project_id, contributor.clone(), bench_contribution_to_mint_ct.id)).unwrap(); + assert!(stored_contribution.ct_minted); + + // Balances + let ct_amount = inst.get_ct_asset_balances_for(project_id, vec![contributor.clone()])[0]; + assert_eq!(ct_amount, pre_contribution_to_mint_ct.ct_amount + bench_contribution_to_mint_ct.ct_amount); + + // Events + frame_system::Pallet::::assert_last_event( + Event::ContributionTokenMinted { + releaser: contributor.clone(), + project_id, + claimer: contributor, + amount: bench_contribution_to_mint_ct.ct_amount, + } + .into(), + ); + } + #[benchmark] fn start_bid_vesting_schedule_for() { // setup @@ -1194,12 +2464,20 @@ mod benchmarks { } #[benchmark] - fn decide_project_outcome() { + fn decide_project_outcome( + // Insertion attempts in add_to_update_store. Total amount of storage items iterated through in `ProjectsToUpdate`. Leave one free to make the extrinsic pass + x: Linear<1, { ::MaxProjectsToUpdateInsertionAttempts::get() - 1 }>, + // Total amount of storage items iterated through in `ProjectsToUpdate` when trying to remove our project in `remove_from_update_store`. + // Upper bound is assumed to be enough + y: Linear<1, 10_000>, + ) { // setup let mut inst = BenchInstantiator::::new(None); - // real benchmark starts at block 0, and we can't call `events()` at block 0 - inst.advance_time(1u32.into()).unwrap(); + // We need to leave enough block numbers to fill `ProjectsToUpdate` before our project insertion + let u32_remaining_vecs: u32 = y.saturating_sub(x); + let time_advance: u32 = 1 + u32_remaining_vecs + 1; + inst.advance_time(time_advance.into()).unwrap(); let issuer = account::>("issuer", 0, 0); let evaluations = default_evaluations::(); @@ -1232,6 +2510,11 @@ mod benchmarks { inst.advance_time(One::one()).unwrap(); + let current_block = inst.current_block(); + let insertion_block_number: BlockNumberFor = current_block + One::one(); + + fill_projects_to_update::(x, insertion_block_number, Some(y)); + #[extrinsic_call] decide_project_outcome(RawOrigin::Signed(issuer), project_id, FundingOutcomeDecision::AcceptFunding); @@ -1319,7 +2602,7 @@ mod benchmarks { } #[benchmark] - fn bid_unbond_for() { + fn release_contribution_funds_for() { // setup let mut inst = BenchInstantiator::::new(None); @@ -1335,20 +2618,20 @@ mod benchmarks { let bids: Vec> = BenchInstantiator::generate_bids_from_total_usd( Percent::from_percent(15) * target_funding_amount, - 10u128.into(), + 1u128.into(), default_weights(), default_bidders::(), default_bidder_multipliers(), ); - let bidder = bids[0].bidder.clone(); - whitelist_account!(bidder); - let contributions = BenchInstantiator::generate_contributions_from_total_usd( + let contributions: Vec> = BenchInstantiator::generate_contributions_from_total_usd( Percent::from_percent(10) * target_funding_amount, BenchInstantiator::calculate_price_from_test_bids(bids.clone()), default_weights(), default_contributors::(), default_community_contributor_multipliers(), ); + let contributor = contributions[0].contributor.clone(); + whitelist_account!(contributor); let project_id = inst.create_finished_project(project_metadata, issuer, evaluations, bids, contributions, vec![]); @@ -1359,39 +2642,45 @@ mod benchmarks { Cleaner::Failure(CleanerState::Initialized(PhantomData)) ); - let stored_bid = inst.execute(|| Bids::::iter_prefix_values((project_id, bidder.clone())).next().unwrap()); - - inst.execute(|| { - PalletFunding::::release_bid_funds_for( - ::RuntimeOrigin::signed(bidder.clone().into()), - project_id, - bidder.clone(), - stored_bid.id, - ) - .expect("Funds are released") - }); + let contribution_to_payout = + inst.execute(|| Contributions::::iter_prefix_values((project_id, contributor.clone())).next().unwrap()); + let asset = contribution_to_payout.funding_asset.to_statemint_id(); + let free_assets_before = + inst.get_free_statemint_asset_balances_for(asset, vec![contributor.clone()])[0].asset_amount; #[extrinsic_call] - bid_unbond_for(RawOrigin::Signed(bidder.clone()), project_id, bidder.clone(), stored_bid.id); + release_contribution_funds_for( + RawOrigin::Signed(contributor.clone()), + project_id, + contributor.clone(), + contribution_to_payout.id, + ); // * validity checks * // Storage - assert!(!Bids::::contains_key((project_id, bidder.clone(), stored_bid.id))); + let stored_contribution = + Contributions::::get((project_id, contributor.clone(), contribution_to_payout.id)).unwrap(); + assert!(stored_contribution.funds_released); + // Balances - let reserved_plmc = inst - .get_reserved_plmc_balances_for(vec![bidder.clone()], HoldReason::Participation(project_id).into())[0] - .plmc_amount; - assert_eq!(reserved_plmc, 0.into()); + let free_assets = inst.get_free_statemint_asset_balances_for(asset, vec![contributor.clone()])[0].asset_amount; + assert_eq!(free_assets, stored_contribution.funding_asset_amount + free_assets_before); // Events frame_system::Pallet::::assert_last_event( - Event::BondReleased { project_id, amount: stored_bid.plmc_bond, bonder: bidder.clone(), releaser: bidder } - .into(), + Event::ContributionFundingReleased { + project_id, + contributor: contributor.clone(), + id: stored_contribution.id, + amount: stored_contribution.funding_asset_amount, + caller: contributor, + } + .into(), ); } #[benchmark] - fn release_contribution_funds_for() { + fn bid_unbond_for() { // setup let mut inst = BenchInstantiator::::new(None); @@ -1407,20 +2696,20 @@ mod benchmarks { let bids: Vec> = BenchInstantiator::generate_bids_from_total_usd( Percent::from_percent(15) * target_funding_amount, - 1u128.into(), + 10u128.into(), default_weights(), default_bidders::(), default_bidder_multipliers(), ); - let contributions: Vec> = BenchInstantiator::generate_contributions_from_total_usd( + let bidder = bids[0].bidder.clone(); + whitelist_account!(bidder); + let contributions = BenchInstantiator::generate_contributions_from_total_usd( Percent::from_percent(10) * target_funding_amount, BenchInstantiator::calculate_price_from_test_bids(bids.clone()), default_weights(), default_contributors::(), default_community_contributor_multipliers(), ); - let contributor = contributions[0].contributor.clone(); - whitelist_account!(contributor); let project_id = inst.create_finished_project(project_metadata, issuer, evaluations, bids, contributions, vec![]); @@ -1431,40 +2720,34 @@ mod benchmarks { Cleaner::Failure(CleanerState::Initialized(PhantomData)) ); - let contribution_to_payout = - inst.execute(|| Contributions::::iter_prefix_values((project_id, contributor.clone())).next().unwrap()); + let stored_bid = inst.execute(|| Bids::::iter_prefix_values((project_id, bidder.clone())).next().unwrap()); + + inst.execute(|| { + PalletFunding::::release_bid_funds_for( + ::RuntimeOrigin::signed(bidder.clone()), + project_id, + bidder.clone(), + stored_bid.id, + ) + .expect("Funds are released") + }); - let asset = contribution_to_payout.funding_asset.to_statemint_id(); - let free_assets_before = - inst.get_free_statemint_asset_balances_for(asset, vec![contributor.clone()])[0].asset_amount; #[extrinsic_call] - release_contribution_funds_for( - RawOrigin::Signed(contributor.clone()), - project_id, - contributor.clone(), - contribution_to_payout.id, - ); + bid_unbond_for(RawOrigin::Signed(bidder.clone()), project_id, bidder.clone(), stored_bid.id); // * validity checks * // Storage - let stored_contribution = - Contributions::::get((project_id, contributor.clone(), contribution_to_payout.id)).unwrap(); - assert!(stored_contribution.funds_released); - + assert!(!Bids::::contains_key((project_id, bidder.clone(), stored_bid.id))); // Balances - let free_assets = inst.get_free_statemint_asset_balances_for(asset, vec![contributor.clone()])[0].asset_amount; - assert_eq!(free_assets, stored_contribution.funding_asset_amount + free_assets_before); + let reserved_plmc = inst + .get_reserved_plmc_balances_for(vec![bidder.clone()], HoldReason::Participation(project_id).into())[0] + .plmc_amount; + assert_eq!(reserved_plmc, 0.into()); // Events frame_system::Pallet::::assert_last_event( - Event::ContributionFundingReleased { - project_id, - contributor: contributor.clone(), - id: stored_contribution.id, - amount: stored_contribution.funding_asset_amount, - caller: contributor, - } - .into(), + Event::BondReleased { project_id, amount: stored_bid.plmc_bond, bonder: bidder.clone(), releaser: bidder } + .into(), ); } @@ -1514,7 +2797,7 @@ mod benchmarks { inst.execute(|| { PalletFunding::::release_contribution_funds_for( - ::RuntimeOrigin::signed(contributor.clone().into()), + ::RuntimeOrigin::signed(contributor.clone()), project_id, contributor.clone(), stored_contribution.id, @@ -1551,30 +2834,6 @@ mod benchmarks { ); } - // #[benchmark] - // fn test(){ - // let mut inst = BenchInstantiator::::new(None); - // inst.advance_time(5u32.into()).unwrap(); - // let issuer = account::>("issuer", 0, 0); - // frame_system::Pallet::::remark_with_event(RawOrigin::Signed(issuer.clone()).into(), vec![1u8,2u8,3u8,4u8]); - // - // let debug_events = frame_system::Pallet::::events(); - // if debug_events.len() == 0 { - // panic!("events in store: {:?}", debug_events.len()); - // } - // - // #[block] - // { - // - // } - // - // let debug_events = frame_system::Pallet::::events(); - // log::info!( - // "frame system default events {:?}", - // debug_events - // ); - // } - #[macro_export] macro_rules! find_event { ($env: expr, $pattern:pat) => { @@ -1586,14 +2845,258 @@ mod benchmarks { let runtime_event = event_record.event.clone(); if let Ok(eve) = runtime_event.try_into() { if let $pattern = &eve { - return Some(Rc::new(eve)) + return Some(Rc::new(eve)); } else { - return None + return None; } } - return None + return None; }) }) }; } + + #[cfg(test)] + mod tests { + use super::*; + use crate::mock::{new_test_ext, TestRuntime}; + + #[test] + fn bench_create() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_create()); + }); + } + + #[test] + fn bench_edit_metadata() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_edit_metadata()); + }); + } + + #[test] + fn bench_start_evaluation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_start_evaluation()); + }); + } + + #[test] + fn bench_first_evaluation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_first_evaluation()); + }); + } + + #[test] + fn bench_second_to_limit_evaluation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_second_to_limit_evaluation()); + }); + } + + #[test] + fn bench_evaluation_over_limit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_evaluation_over_limit()); + }); + } + + #[test] + fn bench_start_auction_manually() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_start_auction_manually()); + }); + } + + #[test] + fn bench_start_auction_automatically() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_start_auction_automatically()); + }); + } + + #[test] + fn bench_bid_with_ct_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_bid_with_ct_deposit()); + }); + } + + #[test] + fn bench_bid_no_ct_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_bid_no_ct_deposit()); + }); + } + + #[test] + fn bench_first_contribution_no_ct_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_first_contribution_no_ct_deposit()); + }); + } + + #[test] + fn bench_first_contribution_with_ct_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_first_contribution_with_ct_deposit()); + }); + } + + #[test] + fn bench_first_contribution_ends_round_no_ct_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_first_contribution_ends_round_no_ct_deposit()); + }); + } + + #[test] + fn bench_first_contribution_ends_round_with_ct_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_first_contribution_ends_round_with_ct_deposit()); + }); + } + + #[test] + fn bench_second_to_limit_contribution() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_second_to_limit_contribution()); + }); + } + + #[test] + fn bench_second_to_limit_contribution_ends_round() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_second_to_limit_contribution_ends_round()); + }); + } + + #[test] + fn bench_contribution_over_limit() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_contribution_over_limit()); + }); + } + + #[test] + fn bench_evaluation_unbond_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_evaluation_unbond_for()); + }); + } + + #[test] + fn bench_evaluation_reward_payout_for_with_ct_account_creation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_evaluation_reward_payout_for_with_ct_account_creation()); + }); + } + + #[test] + fn bench_evaluation_reward_payout_for_no_ct_account_creation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_evaluation_reward_payout_for_no_ct_account_creation()); + }); + } + + #[test] + fn bench_evaluation_slash_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_evaluation_slash_for()); + }); + } + + #[test] + fn bench_bid_ct_mint_for_with_ct_account_creation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_bid_ct_mint_for_with_ct_account_creation()); + }); + } + + #[test] + fn bench_bid_ct_mint_for_no_ct_account_creation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_bid_ct_mint_for_no_ct_account_creation()); + }); + } + + #[test] + fn bench_contribution_ct_mint_for_with_ct_account_creation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_contribution_ct_mint_for_with_ct_account_creation()); + }); + } + + #[test] + fn bench_contribution_ct_mint_for_no_ct_account_creation() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_contribution_ct_mint_for_no_ct_account_creation()); + }); + } + + #[test] + fn bench_start_bid_vesting_schedule_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_start_bid_vesting_schedule_for()); + }); + } + + #[test] + fn bench_start_contribution_vesting_schedule_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_start_contribution_vesting_schedule_for()); + }); + } + + #[test] + fn bench_payout_bid_funds_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_payout_bid_funds_for()); + }); + } + + #[test] + fn bench_payout_contribution_funds_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_payout_contribution_funds_for()); + }); + } + + #[test] + fn bench_decide_project_outcome() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_decide_project_outcome()); + }); + } + + #[test] + fn bench_release_bid_funds_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_release_bid_funds_for()); + }); + } + + #[test] + fn bench_release_contribution_funds_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_release_contribution_funds_for()); + }); + } + + #[test] + fn bench_bid_unbond_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_bid_unbond_for()); + }); + } + + #[test] + fn bench_contribution_unbond_for() { + new_test_ext().execute_with(|| { + assert_ok!(PalletFunding::::test_contribution_unbond_for()); + }); + } + } } diff --git a/pallets/funding/src/functions.rs b/pallets/funding/src/functions.rs index 638144f92..48473a86f 100644 --- a/pallets/funding/src/functions.rs +++ b/pallets/funding/src/functions.rs @@ -19,7 +19,7 @@ //! Functions for the Funding pallet. use frame_support::{ - dispatch::DispatchResult, + dispatch::{DispatchErrorWithPostInfo, DispatchResult, DispatchResultWithPostInfo, PostDispatchInfo}, ensure, pallet_prelude::*, traits::{ @@ -36,7 +36,7 @@ use sp_arithmetic::{ Percent, Perquintill, }; use sp_runtime::traits::{Convert, ConvertBack}; -use sp_std::marker::PhantomData; +use sp_std::{marker::PhantomData, ops::Not}; use xcm::v3::MaxDispatchErrorLen; use crate::ProjectStatus::FundingSuccessful; @@ -71,7 +71,7 @@ impl Pallet { /// /// # Next step /// The issuer will call an extrinsic to start the evaluation round of the project. - /// [`do_evaluation_start`](Self::do_evaluation_start) will be executed. + /// [`do_start_evaluation`](Self::do_start_evaluation) will be executed. pub fn do_create(issuer: &AccountIdOf, initial_metadata: ProjectMetadataOf) -> DispatchResult { // * Get variables * let project_id = Self::next_project_id(); @@ -86,7 +86,7 @@ impl Pallet { ValidityError::PriceTooLow => Err(Error::::PriceTooLow.into()), ValidityError::ParticipantsSizeError => Err(Error::::ParticipantsSizeError.into()), ValidityError::TicketSizeError => Err(Error::::TicketSizeError.into()), - } + }; } let total_allocation_size = initial_metadata.total_allocation_size.0.saturating_add(initial_metadata.total_allocation_size.1); @@ -126,7 +126,7 @@ impl Pallet { let escrow_account = Self::fund_account_id(project_id); // transfer ED from issuer to escrow T::NativeCurrency::transfer( - &issuer, + issuer, &escrow_account, ::ExistentialDeposit::get(), Preservation::Preserve, @@ -165,7 +165,7 @@ impl Pallet { /// # Next step /// Users will pond PLMC for this project, and when the time comes, the project will be transitioned /// to the next round by `on_initialize` using [`do_evaluation_end`](Self::do_evaluation_end) - pub fn do_evaluation_start(caller: AccountIdOf, project_id: ProjectId) -> DispatchResult { + pub fn do_start_evaluation(caller: AccountIdOf, project_id: ProjectId) -> DispatchResultWithPostInfo { // * Get variables * let project_metadata = ProjectsMetadata::::get(project_id).ok_or(Error::::ProjectNotFound)?; let mut project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; @@ -186,12 +186,29 @@ impl Pallet { // * Update storage * ProjectsDetails::::insert(project_id, project_details); - Self::add_to_update_store(evaluation_end_block + 1u32.into(), (&project_id, UpdateType::EvaluationEnd)); + let actual_insertion_attempts = match Self::add_to_update_store( + evaluation_end_block + 1u32.into(), + (&project_id, UpdateType::EvaluationEnd), + ) { + Ok(insertions) => insertions, + Err(insertions) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::start_evaluation(insertions)), + pays_fee: Pays::Yes, + }, + error: Error::::TooManyInsertionAttempts.into(), + }) + }, + }; // * Emit events * Self::deposit_event(Event::EvaluationStarted { project_id }); - Ok(()) + Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::start_evaluation(actual_insertion_attempts)), + pays_fee: Pays::Yes, + }) } /// Called automatically by on_initialize. @@ -265,10 +282,14 @@ impl Pallet { .update(Some(auction_initialize_period_start_block), Some(auction_initialize_period_end_block)); project_details.status = ProjectStatus::AuctionInitializePeriod; ProjectsDetails::::insert(project_id, project_details); - Self::add_to_update_store( + // TODO: return real weights + let _insertions_attempts = match Self::add_to_update_store( auction_initialize_period_end_block + 1u32.into(), (&project_id, UpdateType::EnglishAuctionStart), - ); + ) { + Ok(insertions) => insertions, + Err(_insertions) => return Err(Error::::TooManyInsertionAttempts.into()), + }; // * Emit events * Self::deposit_event(Event::AuctionInitializePeriod { @@ -313,7 +334,7 @@ impl Pallet { /// Professional and Institutional users set bids for the project using the [`bid`](Self::bid) extrinsic. /// Later on, `on_initialize` transitions the project into the candle auction round, by calling /// [`do_candle_auction`](Self::do_candle_auction). - pub fn do_english_auction(caller: AccountIdOf, project_id: ProjectId) -> DispatchResult { + pub fn do_english_auction(caller: AccountIdOf, project_id: ProjectId) -> DispatchResultWithPostInfo { // * Get variables * let mut project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let now = >::block_number(); @@ -353,16 +374,59 @@ impl Pallet { // If this function was called inside the period, then it was called by the extrinsic and we need to // remove the scheduled automatic transition + let mut remove_attempts: u32 = 0u32; + let mut insertion_attempts: u32 = 0u32; if now <= auction_initialize_period_end_block { - Self::remove_from_update_store(&project_id)?; + match Self::remove_from_update_store(&project_id) { + Ok(iterations) => { + remove_attempts = iterations; + }, + Err(iterations) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::start_auction_manually( + insertion_attempts, + iterations, + )), + pays_fee: Pays::Yes, + }, + error: Error::::ProjectNotInUpdateStore.into(), + }) + }, + } } // Schedule for automatic transition to candle auction round - Self::add_to_update_store(english_end_block + 1u32.into(), (&project_id, UpdateType::CandleAuctionStart)); + match Self::add_to_update_store(english_end_block + 1u32.into(), (&project_id, UpdateType::CandleAuctionStart)) + { + Ok(iterations) => { + insertion_attempts = iterations; + }, + Err(insertion_attempts) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: if remove_attempts == 0u32 { + Some(WeightInfoOf::::start_auction_automatically(insertion_attempts)) + } else { + Some(WeightInfoOf::::start_auction_manually(insertion_attempts, remove_attempts)) + }, + pays_fee: Pays::Yes, + }, + error: Error::::TooManyInsertionAttempts.into(), + }) + }, + }; // * Emit events * Self::deposit_event(Event::EnglishAuctionStarted { project_id, when: now }); - Ok(()) + Ok(PostDispatchInfo { + actual_weight: if remove_attempts == 0u32 { + Some(WeightInfoOf::::start_auction_automatically(insertion_attempts)) + } else { + Some(WeightInfoOf::::start_auction_manually(insertion_attempts, remove_attempts)) + }, + pays_fee: Pays::Yes, + }) } /// Called automatically by on_initialize @@ -411,7 +475,14 @@ impl Pallet { project_details.status = ProjectStatus::AuctionRound(AuctionPhase::Candle); ProjectsDetails::::insert(project_id, project_details); // Schedule for automatic check by on_initialize. Success depending on enough funding reached - Self::add_to_update_store(candle_end_block + 1u32.into(), (&project_id, UpdateType::CommunityFundingStart)); + // TODO: return real weights + let _iterations = match Self::add_to_update_store( + candle_end_block + 1u32.into(), + (&project_id, UpdateType::CommunityFundingStart), + ) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; // * Emit events * Self::deposit_event(Event::CandleAuctionStarted { project_id, when: now }); @@ -471,10 +542,14 @@ impl Pallet { Err(pallet_error) if pallet_error == Error::::NoBidsFound.into() => { project_details.status = ProjectStatus::FundingFailed; ProjectsDetails::::insert(project_id, project_details); - Self::add_to_update_store( + // TODO: return real weights + let _iterations = match Self::add_to_update_store( >::block_number() + 1u32.into(), (&project_id, UpdateType::FundingEnd), - ); + ) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; // * Emit events * Self::deposit_event(Event::AuctionFailed { project_id }); @@ -491,10 +566,14 @@ impl Pallet { .update(Some(community_start_block), Some(community_end_block)); project_details.status = ProjectStatus::CommunityRound; ProjectsDetails::::insert(project_id, project_details); - Self::add_to_update_store( + // TODO: return real weights + let _iterations = match Self::add_to_update_store( community_end_block + 1u32.into(), (&project_id, UpdateType::RemainderFundingStart), - ); + ) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; // * Emit events * Self::deposit_event(Event::CommunityFundingStarted { project_id }); @@ -548,7 +627,12 @@ impl Pallet { project_details.status = ProjectStatus::RemainderRound; ProjectsDetails::::insert(project_id, project_details); // Schedule for automatic transition by `on_initialize` - Self::add_to_update_store(remainder_end_block + 1u32.into(), (&project_id, UpdateType::FundingEnd)); + // TODO: return real weights + let _iterations = + match Self::add_to_update_store(remainder_end_block + 1u32.into(), (&project_id, UpdateType::FundingEnd)) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; // * Emit events * Self::deposit_event(Event::RemainderFundingStarted { project_id }); @@ -598,9 +682,9 @@ impl Pallet { // * Validity checks * ensure!( - remaining_cts == Zero::zero() || - project_details.status == ProjectStatus::FundingFailed || - matches!(remainder_end_block, Some(end_block) if now > end_block), + remaining_cts == Zero::zero() + || project_details.status == ProjectStatus::FundingFailed + || matches!(remainder_end_block, Some(end_block) if now > end_block), Error::::TooEarlyForFundingEnd ); @@ -621,19 +705,27 @@ impl Pallet { } else if funding_ratio <= Perquintill::from_percent(75u64) { project_details.evaluation_round_info.evaluators_outcome = EvaluatorsOutcome::Slashed; project_details.status = ProjectStatus::AwaitingProjectDecision; - Self::add_to_update_store( + // TODO: return real weights + let _iterations = match Self::add_to_update_store( now + T::ManualAcceptanceDuration::get() + 1u32.into(), (&project_id, UpdateType::ProjectDecision(FundingOutcomeDecision::AcceptFunding)), - ); + ) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; ProjectsDetails::::insert(project_id, project_details); Ok(()) } else if funding_ratio < Perquintill::from_percent(90u64) { project_details.evaluation_round_info.evaluators_outcome = EvaluatorsOutcome::Unchanged; project_details.status = ProjectStatus::AwaitingProjectDecision; - Self::add_to_update_store( + // TODO: return real weights + let _iterations = match Self::add_to_update_store( now + T::ManualAcceptanceDuration::get() + 1u32.into(), (&project_id, UpdateType::ProjectDecision(FundingOutcomeDecision::AcceptFunding)), - ); + ) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; ProjectsDetails::::insert(project_id, project_details); Ok(()) } else { @@ -684,8 +776,8 @@ impl Pallet { // * Validity checks * ensure!( - project_details.status == ProjectStatus::FundingSuccessful || - project_details.status == ProjectStatus::FundingFailed, + project_details.status == ProjectStatus::FundingSuccessful + || project_details.status == ProjectStatus::FundingFailed, Error::::NotAllowed ); @@ -754,7 +846,11 @@ impl Pallet { } // Note: usd_amount needs to have the same amount of decimals as PLMC,, so when multiplied by the plmc-usd price, it gives us the PLMC amount with the decimals we wanted. - pub fn do_evaluate(evaluator: &AccountIdOf, project_id: ProjectId, usd_amount: BalanceOf) -> DispatchResult { + pub fn do_evaluate( + evaluator: &AccountIdOf, + project_id: ProjectId, + usd_amount: BalanceOf, + ) -> DispatchResultWithPostInfo { // * Get variables * let mut project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let now = >::block_number(); @@ -806,12 +902,12 @@ impl Pallet { // * Update Storage * // Reserve plmc deposit to create a contribution token account for this project - if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), &evaluator) < ct_deposit { - T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), &evaluator, ct_deposit)?; + if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), evaluator) < ct_deposit { + T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), evaluator, ct_deposit)?; } if caller_existing_evaluations.len() < T::MaxEvaluationsPerUser::get() as usize { - T::NativeCurrency::hold(&HoldReason::Evaluation(project_id.into()).into(), evaluator, plmc_bond)?; + T::NativeCurrency::hold(&HoldReason::Evaluation(project_id).into(), evaluator, plmc_bond)?; } else { let (low_id, lowest_evaluation) = caller_existing_evaluations .iter() @@ -825,13 +921,13 @@ impl Pallet { ); T::NativeCurrency::release( - &HoldReason::Evaluation(project_id.into()).into(), + &HoldReason::Evaluation(project_id).into(), &lowest_evaluation.evaluator, lowest_evaluation.original_plmc_bond, Precision::Exact, )?; - T::NativeCurrency::hold(&HoldReason::Evaluation(project_id.into()).into(), evaluator, plmc_bond)?; + T::NativeCurrency::hold(&HoldReason::Evaluation(project_id).into(), evaluator, plmc_bond)?; Evaluations::::remove((project_id, evaluator, low_id)); } @@ -845,7 +941,16 @@ impl Pallet { // * Emit events * Self::deposit_event(Event::FundsBonded { project_id, amount: plmc_bond, bonder: evaluator.clone() }); - Ok(()) + let existing_evaluations_count = caller_existing_evaluations.len() as u32; + let actual_weight = if existing_evaluations_count.is_zero() { + WeightInfoOf::::first_evaluation() + } else if existing_evaluations_count < T::MaxEvaluationsPerUser::get() { + WeightInfoOf::::second_to_limit_evaluation(existing_evaluations_count) + } else { + WeightInfoOf::::evaluation_over_limit() + }; + // + Ok(PostDispatchInfo { actual_weight: Some(actual_weight), pays_fee: Pays::Yes }) } /// Bid for a project in the bidding stage. @@ -867,12 +972,18 @@ impl Pallet { ct_amount: BalanceOf, multiplier: MultiplierOf, funding_asset: AcceptedFundingAsset, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { // * Get variables * let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let project_metadata = ProjectsMetadata::::get(project_id).ok_or(Error::::ProjectNotFound)?; let plmc_usd_price = T::PriceProvider::get_price(PLMC_STATEMINT_ID).ok_or(Error::::PriceNotFound)?; let ct_deposit = T::ContributionTokenCurrency::deposit_required(project_id); + let existing_bids = Bids::::iter_prefix_values((project_id, bidder)).collect::>(); + + // weight return variables + let mut perform_bid_calls = 0; + let mut ct_deposit_required = false; + let existing_bids_amount = existing_bids.len() as u32; // * Validity checks * ensure!(ct_amount > Zero::zero(), Error::::BidTooLow); @@ -881,10 +992,12 @@ impl Pallet { ensure!(funding_asset == project_metadata.participation_currencies, Error::::FundingAssetNotAccepted); // Note: We limit the CT Amount to the total allocation size, to avoid long running loops. ensure!(ct_amount <= project_metadata.total_allocation_size.0, Error::::NotAllowed); + ensure!(existing_bids.len() < T::MaxBidsPerUser::get() as usize, Error::::TooManyBids); // Reserve plmc deposit to create a contribution token account for this project - if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), &bidder) < ct_deposit { - T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), &bidder, ct_deposit)?; + if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), bidder) < ct_deposit { + T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), bidder, ct_deposit)?; + ct_deposit_required = true } // Fetch current bucket details and other required info @@ -915,6 +1028,9 @@ impl Pallet { now, plmc_usd_price, )?; + + perform_bid_calls += 1; + // Update current bucket, and reduce the amount to bid by the amount we just bid current_bucket.update(bid_amount); amount_to_bid.saturating_reduce(bid_amount); @@ -923,7 +1039,18 @@ impl Pallet { // Note: If the bucket has been exhausted, the 'update' function has already made the 'current_bucket' point to the next one. Buckets::::insert(project_id, current_bucket); - Ok(()) + // if ct deposit was required, we already know it can only be the first bid, so existing_bids_amount == 0 + if ct_deposit_required { + Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::bid_with_ct_deposit(perform_bid_calls)), + pays_fee: Pays::Yes, + }) + } else { + Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::bid_no_ct_deposit(existing_bids_amount, perform_bid_calls)), + pays_fee: Pays::Yes, + }) + } } fn perform_do_bid( @@ -941,7 +1068,6 @@ impl Pallet { let ticket_size = ct_usd_price.checked_mul_int(ct_amount).ok_or(Error::::BadMath)?; let funding_asset_usd_price = T::PriceProvider::get_price(funding_asset.to_statemint_id()).ok_or(Error::::PriceNotFound)?; - let existing_bids = Bids::::iter_prefix_values((project_id, bidder)).collect::>(); if let Some(minimum_ticket_size) = project_ticket_size.minimum { // Make sure the bid amount is greater than the minimum specified by the issuer @@ -979,29 +1105,6 @@ impl Pallet { ct_migration_status: MigrationStatus::NotStarted, }; - // * Update storage * - if existing_bids.len() >= T::MaxBidsPerUser::get() as usize { - let lowest_bid = existing_bids.iter().min_by_key(|bid| &bid.id).ok_or(Error::::ImpossibleState)?; - - // TODO: Check how to handle this - // ensure!(new_bid.plmc_bond > lowest_bid.plmc_bond, Error::::BidTooLow); - - T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), - &lowest_bid.bidder, - lowest_bid.plmc_bond, - Precision::Exact, - )?; - T::FundingCurrency::transfer( - asset_id, - &Self::fund_account_id(project_id), - &lowest_bid.bidder, - lowest_bid.funding_asset_amount_locked, - Preservation::Expendable, - )?; - Bids::::remove((project_id, &lowest_bid.bidder, lowest_bid.id)); - } - Self::try_plmc_participation_lock(bidder, project_id, plmc_bond)?; Self::try_funding_asset_hold(bidder, project_id, funding_asset_amount_locked, asset_id)?; @@ -1037,13 +1140,37 @@ impl Pallet { let project_metadata = ProjectsMetadata::::get(project_id).ok_or(Error::::ProjectNotFound)?; let mut project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let ct_deposit = T::ContributionTokenCurrency::deposit_required(project_id); + let caller_existing_contributions = + Contributions::::iter_prefix_values((project_id, contributor)).collect::>(); + + // Weight flags + enum WeightContributionFlag { + First, + SecondToLimit, + OverLimit, + } + struct WeightRoundEndFlag { + fully_filled_vecs_from_insertion: u32, + total_vecs_in_storage: u32, + } + let weight_contribution_flag: WeightContributionFlag; + let mut weight_round_end_flag: Option = None; + let mut weight_ct_account_deposit = false; + + if caller_existing_contributions.is_empty() { + weight_contribution_flag = WeightContributionFlag::First; + } else if caller_existing_contributions.len() < T::MaxContributionsPerUser::get() as usize { + weight_contribution_flag = WeightContributionFlag::SecondToLimit; + } else { + weight_contribution_flag = WeightContributionFlag::OverLimit; + } // * Validity checks * ensure!(project_metadata.participation_currencies == asset, Error::::FundingAssetNotAccepted); ensure!(contributor.clone() != project_details.issuer, Error::::ContributionToThemselves); ensure!( - project_details.status == ProjectStatus::CommunityRound || - project_details.status == ProjectStatus::RemainderRound, + project_details.status == ProjectStatus::CommunityRound + || project_details.status == ProjectStatus::RemainderRound, Error::::AuctionNotStarted ); @@ -1094,19 +1221,17 @@ impl Pallet { // * Update storage * // Reserve plmc deposit to create a contribution token account for this project - if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), &contributor) < ct_deposit - { - T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), &contributor, ct_deposit)?; + if T::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), contributor) < ct_deposit { + weight_ct_account_deposit = true; + T::NativeCurrency::hold(&HoldReason::FutureDeposit(project_id).into(), contributor, ct_deposit)?; } // Try adding the new contribution to the system - let existing_contributions = - Contributions::::iter_prefix_values((project_id, contributor)).collect::>(); - if existing_contributions.len() < T::MaxContributionsPerUser::get() as usize { + if matches!(weight_contribution_flag, WeightContributionFlag::OverLimit).not() { Self::try_plmc_participation_lock(contributor, project_id, plmc_bond)?; Self::try_funding_asset_hold(contributor, project_id, funding_asset_amount, asset_id)?; } else { - let lowest_contribution = existing_contributions + let lowest_contribution = caller_existing_contributions .iter() .min_by_key(|contribution| contribution.plmc_bond) .ok_or(Error::::ImpossibleState)?; @@ -1114,7 +1239,7 @@ impl Pallet { ensure!(new_contribution.plmc_bond > lowest_contribution.plmc_bond, Error::::ContributionTooLow); T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), + &HoldReason::Participation(project_id).into(), &lowest_contribution.contributor, lowest_contribution.plmc_bond, Precision::Exact, @@ -1160,9 +1285,21 @@ impl Pallet { project_details.funding_amount_reached.saturating_accrue(new_contribution.usd_contribution_amount); ProjectsDetails::::insert(project_id, project_details); // If no CTs remain, end the funding phase + if remaining_cts_after_purchase.is_zero() { - Self::remove_from_update_store(&project_id)?; - Self::add_to_update_store(now + 1u32.into(), (&project_id, UpdateType::FundingEnd)); + // remove the remainder transition or the funding failed transition + let total_vecs_in_storage = match Self::remove_from_update_store(&project_id) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; + let fully_filled_vecs_from_insertion = + match Self::add_to_update_store(now + 1u32.into(), (&project_id, UpdateType::FundingEnd)) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; + + weight_round_end_flag = + Some(WeightRoundEndFlag { fully_filled_vecs_from_insertion, total_vecs_in_storage }); } // * Emit events * @@ -1173,7 +1310,64 @@ impl Pallet { multiplier, }); - Ok(Pays::No.into()) + // return correct weight function + match (weight_contribution_flag, weight_round_end_flag, weight_ct_account_deposit) { + (WeightContributionFlag::First, None, false) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::first_contribution_no_ct_deposit()), + pays_fee: Pays::Yes, + }), + (WeightContributionFlag::First, None, true) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::first_contribution_with_ct_deposit()), + pays_fee: Pays::Yes, + }), + ( + WeightContributionFlag::First, + Some(WeightRoundEndFlag { fully_filled_vecs_from_insertion, total_vecs_in_storage }), + false, + ) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::first_contribution_ends_round_no_ct_deposit( + fully_filled_vecs_from_insertion, + total_vecs_in_storage, + )), + pays_fee: Pays::Yes, + }), + ( + WeightContributionFlag::First, + Some(WeightRoundEndFlag { fully_filled_vecs_from_insertion, total_vecs_in_storage }), + true, + ) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::first_contribution_ends_round_with_ct_deposit( + fully_filled_vecs_from_insertion, + total_vecs_in_storage, + )), + pays_fee: Pays::Yes, + }), + + (WeightContributionFlag::SecondToLimit, None, _) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::second_to_limit_contribution( + caller_existing_contributions.len() as u32, + )), + pays_fee: Pays::Yes, + }), + ( + WeightContributionFlag::SecondToLimit, + Some(WeightRoundEndFlag { fully_filled_vecs_from_insertion, total_vecs_in_storage }), + _, + ) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::second_to_limit_contribution_ends_round( + caller_existing_contributions.len() as u32, + fully_filled_vecs_from_insertion, + total_vecs_in_storage, + )), + pays_fee: Pays::Yes, + }), + + // a contribution over the limit means removing an existing contribution, therefore you cannot have a round end + (WeightContributionFlag::OverLimit, _, _) => Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::contribution_over_limit()), + pays_fee: Pays::Yes, + }), + } } fn calculate_buyable_amount( @@ -1182,12 +1376,13 @@ impl Pallet { remaining_contribution_tokens: (BalanceOf, BalanceOf), ) -> BalanceOf { match status { - ProjectStatus::CommunityRound => + ProjectStatus::CommunityRound => { if amount <= remaining_contribution_tokens.1 { amount } else { remaining_contribution_tokens.1 - }, + } + }, ProjectStatus::RemainderRound => { let sum = remaining_contribution_tokens.0.saturating_add(remaining_contribution_tokens.1); if sum >= amount { @@ -1204,7 +1399,7 @@ impl Pallet { issuer: AccountIdOf, project_id: ProjectId, decision: FundingOutcomeDecision, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { // * Get variables * let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let now = >::block_number(); @@ -1214,12 +1409,40 @@ impl Pallet { ensure!(project_details.status == ProjectStatus::AwaitingProjectDecision, Error::::NotAllowed); // * Update storage * - Self::remove_from_update_store(&project_id)?; - Self::add_to_update_store(now + 1u32.into(), (&project_id, UpdateType::ProjectDecision(decision))); + + let mut insertion_attempts: u32 = 0u32; + + let remove_attempts: u32 = match Self::remove_from_update_store(&project_id) { + Ok(iterations) => iterations, + Err(iterations) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::decide_project_outcome(insertion_attempts, iterations)), + pays_fee: Pays::Yes, + }, + error: Error::::TooManyInsertionAttempts.into(), + }) + }, + }; + match Self::add_to_update_store(now + 1u32.into(), (&project_id, UpdateType::ProjectDecision(decision))) { + Ok(iterations) => insertion_attempts = iterations, + Err(iterations) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::decide_project_outcome(iterations, remove_attempts)), + pays_fee: Pays::Yes, + }, + error: Error::::TooManyInsertionAttempts.into(), + }) + }, + }; Self::deposit_event(Event::ProjectOutcomeDecided { project_id, decision }); - Ok(()) + Ok(PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::decide_project_outcome(insertion_attempts, remove_attempts)), + pays_fee: Pays::Yes, + }) } pub fn do_bid_ct_mint_for( @@ -1227,12 +1450,15 @@ impl Pallet { project_id: ProjectId, bidder: &AccountIdOf, bid_id: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { // * Get variables * let mut bid = Bids::::get((project_id, bidder, bid_id)).ok_or(Error::::BidNotFound)?; let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectNotFound)?; let ct_amount = bid.final_ct_amount; + // weight return variables + let mut ct_account_created = false; + // * Validity checks * ensure!(project_details.status == ProjectStatus::FundingSuccessful, Error::::NotAllowed); ensure!(!bid.ct_minted, Error::::NotAllowed); @@ -1244,6 +1470,7 @@ impl Pallet { // * Update storage * if !T::ContributionTokenCurrency::contains(&project_id, &bid.bidder) { + ct_account_created = true; T::NativeCurrency::release( &HoldReason::FutureDeposit(project_id).into(), &bid.bidder, @@ -1263,7 +1490,14 @@ impl Pallet { amount: ct_amount, }); - Ok(()) + Ok(PostDispatchInfo { + actual_weight: Some(if ct_account_created { + WeightInfoOf::::bid_ct_mint_for_with_ct_account_creation() + } else { + WeightInfoOf::::bid_ct_mint_for_no_ct_account_creation() + }), + pays_fee: Pays::Yes, + }) } pub fn do_contribution_ct_mint_for( @@ -1271,13 +1505,16 @@ impl Pallet { project_id: ProjectId, contributor: &AccountIdOf, contribution_id: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { // * Get variables * let mut contribution = Contributions::::get((project_id, contributor, contribution_id)).ok_or(Error::::BidNotFound)?; let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectNotFound)?; let ct_amount = contribution.ct_amount; + // weight return variables + let mut ct_account_created = false; + // * Validity checks * ensure!(project_details.status == ProjectStatus::FundingSuccessful, Error::::NotAllowed); ensure!(!contribution.ct_minted, Error::::NotAllowed); @@ -1288,6 +1525,7 @@ impl Pallet { // * Update storage * if !T::ContributionTokenCurrency::contains(&project_id, &contribution.contributor) { + ct_account_created = true; T::NativeCurrency::release( &HoldReason::FutureDeposit(project_id).into(), &contribution.contributor, @@ -1311,7 +1549,14 @@ impl Pallet { amount: ct_amount, }); - Ok(()) + Ok(PostDispatchInfo { + actual_weight: Some(if ct_account_created { + WeightInfoOf::::contribution_ct_mint_for_with_ct_account_creation() + } else { + WeightInfoOf::::contribution_ct_mint_for_no_ct_account_creation() + }), + pays_fee: Pays::Yes, + }) } pub fn do_evaluation_unbond_for( @@ -1328,9 +1573,9 @@ impl Pallet { // * Validity checks * ensure!( - (project_details.evaluation_round_info.evaluators_outcome == EvaluatorsOutcomeOf::::Unchanged || - released_evaluation.rewarded_or_slashed.is_some()) && - matches!( + (project_details.evaluation_round_info.evaluators_outcome == EvaluatorsOutcomeOf::::Unchanged + || released_evaluation.rewarded_or_slashed.is_some()) + && matches!( project_details.status, ProjectStatus::EvaluationFailed | ProjectStatus::FundingFailed | ProjectStatus::FundingSuccessful ), @@ -1339,7 +1584,7 @@ impl Pallet { // * Update Storage * T::NativeCurrency::release( - &HoldReason::Evaluation(project_id.into()).into(), + &HoldReason::Evaluation(project_id).into(), evaluator, released_evaluation.current_plmc_bond, Precision::Exact, @@ -1367,22 +1612,25 @@ impl Pallet { project_id: ProjectId, evaluator: &AccountIdOf, evaluation_id: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { // * Get variables * let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let reward_info = if let EvaluatorsOutcome::Rewarded(info) = project_details.evaluation_round_info.evaluators_outcome { info } else { - return Err(Error::::NotAllowed.into()) + return Err(Error::::NotAllowed.into()); }; let mut evaluation = Evaluations::::get((project_id, evaluator, evaluation_id)).ok_or(Error::::EvaluationNotFound)?; + // weight return variables + let mut ct_account_created = false; + // * Validity checks * ensure!( - evaluation.rewarded_or_slashed.is_none() && - matches!(project_details.status, ProjectStatus::FundingSuccessful), + evaluation.rewarded_or_slashed.is_none() + && matches!(project_details.status, ProjectStatus::FundingSuccessful), Error::::NotAllowed ); @@ -1396,8 +1644,10 @@ impl Pallet { let early_evaluators_rewards = early_reward_weight * reward_info.early_evaluator_reward_pot; let normal_evaluators_rewards = normal_reward_weight * reward_info.normal_evaluator_reward_pot; let total_reward_amount = early_evaluators_rewards.saturating_add(normal_evaluators_rewards); + // * Update storage * if !T::ContributionTokenCurrency::contains(&project_id, &evaluation.evaluator) { + ct_account_created = true; T::NativeCurrency::release( &HoldReason::FutureDeposit(project_id).into(), &evaluation.evaluator, @@ -1423,7 +1673,17 @@ impl Pallet { caller: caller.clone(), }); - Ok(()) + Ok(if ct_account_created { + PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::evaluation_reward_payout_for_with_ct_account_creation()), + pays_fee: Pays::Yes, + } + } else { + PostDispatchInfo { + actual_weight: Some(WeightInfoOf::::evaluation_reward_payout_for_no_ct_account_creation()), + pays_fee: Pays::Yes, + } + }) } pub fn do_evaluation_slash_for( @@ -1442,8 +1702,8 @@ impl Pallet { // * Validity checks * ensure!( - evaluation.rewarded_or_slashed.is_none() && - matches!(project_details.evaluation_round_info.evaluators_outcome, EvaluatorsOutcome::Slashed), + evaluation.rewarded_or_slashed.is_none() + && matches!(project_details.evaluation_round_info.evaluators_outcome, EvaluatorsOutcome::Slashed), Error::::NotAllowed ); @@ -1455,7 +1715,7 @@ impl Pallet { evaluation.rewarded_or_slashed = Some(RewardOrSlash::Slash(slashed_amount)); T::NativeCurrency::transfer_on_hold( - &HoldReason::Evaluation(project_id.into()).into(), + &HoldReason::Evaluation(project_id).into(), evaluator, &treasury_account, slashed_amount, @@ -1492,9 +1752,9 @@ impl Pallet { // * Validity checks * ensure!( - bid.plmc_vesting_info.is_none() && - project_details.status == ProjectStatus::FundingSuccessful && - matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)), + bid.plmc_vesting_info.is_none() + && project_details.status == ProjectStatus::FundingSuccessful + && matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)), Error::::NotAllowed ); @@ -1509,7 +1769,7 @@ impl Pallet { vest_info.total_amount, vest_info.amount_per_block, funding_end_block, - HoldReason::Participation(project_id.into()).into(), + HoldReason::Participation(project_id).into(), )?; Bids::::insert((project_id, bidder, bid_id), bid); @@ -1554,7 +1814,7 @@ impl Pallet { vest_info.total_amount, vest_info.amount_per_block, funding_end_block, - HoldReason::Participation(project_id.into()).into(), + HoldReason::Participation(project_id).into(), )?; Contributions::::insert((project_id, contributor, contribution_id), contribution); @@ -1582,7 +1842,7 @@ impl Pallet { ensure!(matches!(project_details.status, ProjectStatus::FundingSuccessful), Error::::NotAllowed); // * Update storage * - let vested_amount = T::Vesting::vest(participant.clone(), HoldReason::Participation(project_id.into()).into())?; + let vested_amount = T::Vesting::vest(participant.clone(), HoldReason::Participation(project_id).into())?; // * Emit events * Self::deposit_event(Event::ParticipantPlmcVested { project_id, participant, amount: vested_amount, caller }); @@ -1602,8 +1862,8 @@ impl Pallet { // * Validity checks * ensure!( - project_details.status == ProjectStatus::FundingFailed && - matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)), + project_details.status == ProjectStatus::FundingFailed + && matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)), Error::::NotAllowed ); @@ -1649,15 +1909,15 @@ impl Pallet { // * Validity checks * ensure!( - project_details.status == ProjectStatus::FundingFailed && - matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)) && - bid.funds_released, + project_details.status == ProjectStatus::FundingFailed + && matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)) + && bid.funds_released, Error::::NotAllowed ); // * Update Storage * T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), + &HoldReason::Participation(project_id).into(), bidder, bid.plmc_bond, Precision::Exact, @@ -1736,7 +1996,7 @@ impl Pallet { // * Update Storage * T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), + &HoldReason::Participation(project_id).into(), contributor, bid.plmc_bond, Precision::Exact, @@ -1767,8 +2027,8 @@ impl Pallet { // * Validity checks * ensure!( - project_details.status == ProjectStatus::FundingSuccessful && - matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)), + project_details.status == ProjectStatus::FundingSuccessful + && matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)), Error::::NotAllowed ); @@ -1913,10 +2173,10 @@ impl Pallet { match message { Instruction::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } - if max_message_size >= max_message_size_thresholds.0 && - max_message_size <= max_message_size_thresholds.1 && - max_capacity >= max_capacity_thresholds.0 && - max_capacity <= max_capacity_thresholds.1 => + if max_message_size >= max_message_size_thresholds.0 + && max_message_size <= max_message_size_thresholds.1 + && max_capacity >= max_capacity_thresholds.0 + && max_capacity <= max_capacity_thresholds.1 => { log::trace!(target: "pallet_funding::hrmp", "HrmpNewChannelOpenRequest accepted"); @@ -2039,8 +2299,8 @@ impl Pallet { // * Validity checks * ensure!(project_details.status == ProjectStatus::FundingSuccessful, Error::::NotAllowed); ensure!( - project_details.hrmp_channel_status == - HRMPChannelStatus { + project_details.hrmp_channel_status + == HRMPChannelStatus { project_to_polimec: ChannelStatus::Open, polimec_to_project: ChannelStatus::Open }, @@ -2127,7 +2387,7 @@ impl Pallet { details.migration_readiness_check { if holding_check.0 == query_id || pallet_check.0 == query_id { - return Some((project_id, details, check)) + return Some((project_id, details, check)); } } None @@ -2137,7 +2397,7 @@ impl Pallet { let para_id = if let MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } = location { ParaId::from(para_id) } else { - return Err(Error::::NotAllowed.into()) + return Err(Error::::NotAllowed.into()); }; let project_metadata = ProjectsMetadata::::get(project_id).ok_or(Error::::ProjectNotFound)?; @@ -2184,14 +2444,15 @@ impl Pallet { ( Response::PalletsInfo(pallets_info), MigrationReadinessCheck { pallet_check: (_, CheckOutcome::AwaitingResponse), .. }, - ) => + ) => { if pallets_info.len() == 1 && pallets_info[0] == T::PolimecReceiverInfo::get() { migration_check.pallet_check.1 = CheckOutcome::Passed; Self::deposit_event(Event::::MigrationCheckResponseAccepted { project_id, query_id, response }); } else { migration_check.pallet_check.1 = CheckOutcome::Failed; Self::deposit_event(Event::::MigrationCheckResponseRejected { project_id, query_id, response }); - }, + } + }, _ => return Err(Error::::NotAllowed.into()), }; @@ -2291,7 +2552,7 @@ impl Pallet { let para_id = if let MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } = location { ParaId::from(para_id) } else { - return Err(Error::::NotAllowed.into()) + return Err(Error::::NotAllowed.into()); }; let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; @@ -2307,8 +2568,8 @@ impl Pallet { // Self::deposit_event(Event::MigrationsConfirmed { project_id }); Ok(()) }, - Response::DispatchResult(MaybeErrorCode::Error(e)) | - Response::DispatchResult(MaybeErrorCode::TruncatedError(e)) => { + Response::DispatchResult(MaybeErrorCode::Error(e)) + | Response::DispatchResult(MaybeErrorCode::TruncatedError(e)) => { Self::mark_migrations_as_failed(unconfirmed_migrations.clone(), e); Self::deposit_event(Event::MigrationsFailed { project_id, @@ -2335,29 +2596,38 @@ impl Pallet { } /// Adds a project to the ProjectsToUpdate storage, so it can be updated at some later point in time. - pub fn add_to_update_store(block_number: BlockNumberFor, store: (&ProjectId, UpdateType)) { + pub fn add_to_update_store(block_number: BlockNumberFor, store: (&ProjectId, UpdateType)) -> Result { // Try to get the project into the earliest possible block to update. // There is a limit for how many projects can update each block, so we need to make sure we don't exceed that limit let mut block_number = block_number; - while ProjectsToUpdate::::try_append(block_number, store.clone()).is_err() { - // TODO: Should we end the loop if we iterated over too many blocks? - block_number += 1u32.into(); + for i in 1..T::MaxProjectsToUpdateInsertionAttempts::get() + 1 { + if ProjectsToUpdate::::try_append(block_number, store.clone()).is_err() { + block_number += 1u32.into(); + } else { + return Ok(i); + } } + Err(T::MaxProjectsToUpdateInsertionAttempts::get()) } - pub fn remove_from_update_store(project_id: &ProjectId) -> DispatchResult { + // returns the actual iterations for weight calculation either as an Err type or Ok type so the caller can add that + // to the corresponding weight function. + pub fn remove_from_update_store(project_id: &ProjectId) -> Result { + // used for extrinsic weight calculation + let mut total_iterations = 0u32; let (block_position, project_index) = ProjectsToUpdate::::iter() .find_map(|(block, project_vec)| { + total_iterations += 1; let project_index = project_vec.iter().position(|(id, _update_type)| id == project_id)?; Some((block, project_index)) }) - .ok_or(Error::::ProjectNotInUpdateStore)?; + .ok_or(total_iterations)?; ProjectsToUpdate::::mutate(block_position, |project_vec| { project_vec.remove(project_index); }); - Ok(()) + Ok(total_iterations) } pub fn create_bucket_from_metadata(metadata: &ProjectMetadataOf) -> Result, DispatchError> { @@ -2426,12 +2696,12 @@ impl Pallet { .map(|mut bid| { if bid.when > end_block { return Self::refund_bid(&mut bid, project_id, &project_account, RejectionReason::AfterCandleEnd) - .and(Ok(bid)) + .and(Ok(bid)); } let buyable_amount = total_allocation_size.saturating_sub(bid_token_amount_sum); if buyable_amount.is_zero() { return Self::refund_bid(&mut bid, project_id, &project_account, RejectionReason::NoTokensLeft) - .and(Ok(bid)) + .and(Ok(bid)); } else if bid.original_ct_amount <= buyable_amount { let maybe_ticket_size = bid.original_ct_usd_price.checked_mul_int(bid.original_ct_amount); if let Some(ticket_size) = maybe_ticket_size { @@ -2440,7 +2710,7 @@ impl Pallet { bid.status = BidStatus::Accepted; } else { return Self::refund_bid(&mut bid, project_id, &project_account, RejectionReason::BadMath) - .and(Ok(bid)) + .and(Ok(bid)); } } else { let maybe_ticket_size = bid.original_ct_usd_price.checked_mul_int(buyable_amount); @@ -2475,7 +2745,7 @@ impl Pallet { .checked_mul_int(usd_bond_needed) .ok_or(Error::::BadMath)?; T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), + &HoldReason::Participation(project_id).into(), &bid.bidder, bid.plmc_bond.saturating_sub(plmc_bond_needed), Precision::Exact, @@ -2485,7 +2755,7 @@ impl Pallet { bid.plmc_bond = plmc_bond_needed; } else { return Self::refund_bid(&mut bid, project_id, &project_account, RejectionReason::BadMath) - .and(Ok(bid)) + .and(Ok(bid)); } } @@ -2571,7 +2841,7 @@ impl Pallet { .ok_or(Error::::BadMath)?; T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), + &HoldReason::Participation(project_id).into(), &bid.bidder, bid.plmc_bond.saturating_sub(plmc_bond_needed), Precision::Exact, @@ -2619,7 +2889,7 @@ impl Pallet { Preservation::Preserve, )?; T::NativeCurrency::release( - &HoldReason::Participation(project_id.into()).into(), + &HoldReason::Participation(project_id).into(), &bid.bidder, bid.plmc_bond, Precision::Exact, @@ -2670,26 +2940,21 @@ impl Pallet { let mut to_convert = amount; for mut evaluation in user_evaluations { if to_convert == Zero::zero() { - break + break; } let slash_deposit = ::EvaluatorSlash::get() * evaluation.original_plmc_bond; let available_to_convert = evaluation.current_plmc_bond.saturating_sub(slash_deposit); let converted = to_convert.min(available_to_convert); evaluation.current_plmc_bond = evaluation.current_plmc_bond.saturating_sub(converted); Evaluations::::insert((project_id, who, evaluation.id), evaluation); - T::NativeCurrency::release( - &HoldReason::Evaluation(project_id.into()).into(), - who, - converted, - Precision::Exact, - ) - .map_err(|_| Error::::ImpossibleState)?; - T::NativeCurrency::hold(&HoldReason::Participation(project_id.into()).into(), who, converted) + T::NativeCurrency::release(&HoldReason::Evaluation(project_id).into(), who, converted, Precision::Exact) + .map_err(|_| Error::::ImpossibleState)?; + T::NativeCurrency::hold(&HoldReason::Participation(project_id).into(), who, converted) .map_err(|_| Error::::ImpossibleState)?; to_convert = to_convert.saturating_sub(converted) } - T::NativeCurrency::hold(&HoldReason::Participation(project_id.into()).into(), who, to_convert)?; + T::NativeCurrency::hold(&HoldReason::Participation(project_id).into(), who, to_convert)?; Ok(()) } @@ -2824,7 +3089,12 @@ impl Pallet { project_details.status = ProjectStatus::FundingSuccessful; ProjectsDetails::::insert(project_id, project_details); - Self::add_to_update_store(now + settlement_delta, (&project_id, UpdateType::StartSettlement)); + // TODO: add real weights + let _iterations = + match Self::add_to_update_store(now + settlement_delta, (&project_id, UpdateType::StartSettlement)) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; Self::deposit_event(Event::FundingEnded { project_id, outcome: FundingOutcome::Success(reason) }); @@ -2841,7 +3111,12 @@ impl Pallet { project_details.status = ProjectStatus::FundingFailed; ProjectsDetails::::insert(project_id, project_details); - Self::add_to_update_store(now + settlement_delta, (&project_id, UpdateType::StartSettlement)); + // TODO: add real weights + let _iterations = + match Self::add_to_update_store(now + settlement_delta, (&project_id, UpdateType::StartSettlement)) { + Ok(iterations) => iterations, + Err(_iterations) => return Err(Error::::TooManyInsertionAttempts.into()), + }; Self::deposit_event(Event::FundingEnded { project_id, outcome: FundingOutcome::Failure(reason) }); Ok(()) } diff --git a/pallets/funding/src/impls.rs b/pallets/funding/src/impls.rs index ca79be91e..57f1c2155 100644 --- a/pallets/funding/src/impls.rs +++ b/pallets/funding/src/impls.rs @@ -15,6 +15,7 @@ // along with this program. If not, see . use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, GetDispatchInfo}, traits::{fungible::InspectHold, Get}, weights::Weight, }; @@ -29,20 +30,24 @@ impl DoRemainingOperation for Cleaner { fn has_remaining_operations(&self) -> bool { match self { Cleaner::NotReady => false, - Cleaner::Success(state) => - as DoRemainingOperation>::has_remaining_operations(state), - Cleaner::Failure(state) => - as DoRemainingOperation>::has_remaining_operations(state), + Cleaner::Success(state) => { + as DoRemainingOperation>::has_remaining_operations(state) + }, + Cleaner::Failure(state) => { + as DoRemainingOperation>::has_remaining_operations(state) + }, } } fn do_one_operation(&mut self, project_id: ProjectId) -> Result { match self { Cleaner::NotReady => Err(DispatchError::Other("Cleaner not ready")), - Cleaner::Success(state) => - as DoRemainingOperation>::do_one_operation(state, project_id), - Cleaner::Failure(state) => - as DoRemainingOperation>::do_one_operation(state, project_id), + Cleaner::Success(state) => { + as DoRemainingOperation>::do_one_operation(state, project_id) + }, + Cleaner::Failure(state) => { + as DoRemainingOperation>::do_one_operation(state, project_id) + }, } } } @@ -67,16 +72,18 @@ impl DoRemainingOperation for CleanerState { ); Ok(base_weight) }, - CleanerState::EvaluationRewardOrSlash(remaining, PhantomData) => + CleanerState::EvaluationRewardOrSlash(remaining, PhantomData) => { if *remaining == 0 { *self = Self::EvaluationUnbonding(remaining_evaluations::(project_id), PhantomData); Ok(base_weight) } else { - let (consumed_weight, remaining_evaluations) = reward_or_slash_one_evaluation::(project_id)?; + let (consumed_weight, remaining_evaluations) = + reward_or_slash_one_evaluation::(project_id).map_err(|error_info| error_info.error)?; *self = CleanerState::EvaluationRewardOrSlash(remaining_evaluations, PhantomData); Ok(consumed_weight) - }, - CleanerState::EvaluationUnbonding(remaining, PhantomData) => + } + }, + CleanerState::EvaluationUnbonding(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::StartBidderVestingSchedule( remaining_successful_bids::(project_id), @@ -87,8 +94,9 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_evaluations) = unbond_one_evaluation::(project_id); *self = CleanerState::EvaluationUnbonding(remaining_evaluations, PhantomData); Ok(consumed_weight) - }, - CleanerState::StartBidderVestingSchedule(remaining, PhantomData) => + } + }, + CleanerState::StartBidderVestingSchedule(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::StartContributorVestingSchedule( remaining_contributions::(project_id), @@ -99,8 +107,9 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_evaluations) = start_one_bid_vesting_schedule::(project_id); *self = CleanerState::StartBidderVestingSchedule(remaining_evaluations, PhantomData); Ok(consumed_weight) - }, - CleanerState::StartContributorVestingSchedule(remaining, PhantomData) => + } + }, + CleanerState::StartContributorVestingSchedule(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::BidCTMint(remaining_bids_without_ct_minted::(project_id), PhantomData); Ok(base_weight) @@ -109,8 +118,9 @@ impl DoRemainingOperation for CleanerState { start_one_contribution_vesting_schedule::(project_id); *self = CleanerState::StartContributorVestingSchedule(remaining_evaluations, PhantomData); Ok(consumed_weight) - }, - CleanerState::BidCTMint(remaining, PhantomData) => + } + }, + CleanerState::BidCTMint(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::ContributionCTMint( remaining_contributions_without_ct_minted::(project_id), @@ -121,8 +131,9 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_bids) = mint_ct_for_one_bid::(project_id); *self = CleanerState::BidCTMint(remaining_bids, PhantomData); Ok(consumed_weight) - }, - CleanerState::ContributionCTMint(remaining, PhantomData) => + } + }, + CleanerState::ContributionCTMint(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::BidFundingPayout( remaining_bids_without_issuer_payout::(project_id), @@ -133,8 +144,9 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_contributions) = mint_ct_for_one_contribution::(project_id); *self = CleanerState::ContributionCTMint(remaining_contributions, PhantomData); Ok(consumed_weight) - }, - CleanerState::BidFundingPayout(remaining, PhantomData) => + } + }, + CleanerState::BidFundingPayout(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::ContributionFundingPayout( remaining_contributions_without_issuer_payout::(project_id), @@ -145,8 +157,9 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_contributions) = issuer_funding_payout_one_bid::(project_id); *self = CleanerState::BidFundingPayout(remaining_contributions, PhantomData); Ok(consumed_weight) - }, - CleanerState::ContributionFundingPayout(remaining, PhantomData) => + } + }, + CleanerState::ContributionFundingPayout(remaining, PhantomData) => { if *remaining == 0 { *self = CleanerState::Finished(PhantomData); Ok(base_weight) @@ -155,7 +168,8 @@ impl DoRemainingOperation for CleanerState { issuer_funding_payout_one_contribution::(project_id); *self = CleanerState::ContributionFundingPayout(remaining_contributions, PhantomData); Ok(consumed_weight) - }, + } + }, CleanerState::Finished(PhantomData) => Err(Error::::FinalizerFinished.into()), _ => Err(Error::::ImpossibleState.into()), @@ -183,7 +197,7 @@ impl DoRemainingOperation for CleanerState { Ok(base_weight) }, - CleanerState::EvaluationRewardOrSlash(remaining, PhantomData::) => + CleanerState::EvaluationRewardOrSlash(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::FutureDepositRelease( remaining_participants_with_future_ct_deposit::(project_id), @@ -191,12 +205,14 @@ impl DoRemainingOperation for CleanerState { ); Ok(base_weight) } else { - let (consumed_weight, remaining_evaluators) = reward_or_slash_one_evaluation::(project_id)?; + let (consumed_weight, remaining_evaluators) = + reward_or_slash_one_evaluation::(project_id).map_err(|error_info| error_info.error)?; *self = CleanerState::EvaluationRewardOrSlash(remaining_evaluators, PhantomData); Ok(consumed_weight) - }, + } + }, - CleanerState::FutureDepositRelease(remaining, PhantomData::) => + CleanerState::FutureDepositRelease(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::EvaluationUnbonding( remaining_evaluations::(project_id), @@ -208,9 +224,10 @@ impl DoRemainingOperation for CleanerState { release_future_ct_deposit_one_participant::(project_id); *self = CleanerState::FutureDepositRelease(remaining_participants, PhantomData::); Ok(consumed_weight) - }, + } + }, - CleanerState::EvaluationUnbonding(remaining, PhantomData::) => + CleanerState::EvaluationUnbonding(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::BidFundingRelease( remaining_bids_to_release_funds::(project_id), @@ -221,9 +238,10 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_evaluators) = unbond_one_evaluation::(project_id); *self = CleanerState::EvaluationUnbonding(remaining_evaluators, PhantomData); Ok(consumed_weight) - }, + } + }, - CleanerState::BidFundingRelease(remaining, PhantomData::) => + CleanerState::BidFundingRelease(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::BidUnbonding(remaining_bids::(project_id), PhantomData::); Ok(base_weight) @@ -231,9 +249,10 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_bids) = release_funds_one_bid::(project_id); *self = CleanerState::BidFundingRelease(remaining_bids, PhantomData); Ok(consumed_weight) - }, + } + }, - CleanerState::BidUnbonding(remaining, PhantomData::) => + CleanerState::BidUnbonding(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::ContributionFundingRelease( remaining_contributions_to_release_funds::(project_id), @@ -244,9 +263,10 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_bids) = unbond_one_bid::(project_id); *self = CleanerState::BidUnbonding(remaining_bids, PhantomData::); Ok(consumed_weight) - }, + } + }, - CleanerState::ContributionFundingRelease(remaining, PhantomData::) => + CleanerState::ContributionFundingRelease(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::ContributionUnbonding( remaining_contributions::(project_id), @@ -257,9 +277,10 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_contributions) = release_funds_one_contribution::(project_id); *self = CleanerState::ContributionFundingRelease(remaining_contributions, PhantomData::); Ok(consumed_weight) - }, + } + }, - CleanerState::ContributionUnbonding(remaining, PhantomData::) => + CleanerState::ContributionUnbonding(remaining, PhantomData::) => { if *remaining == 0 { *self = CleanerState::Finished(PhantomData::); Ok(base_weight) @@ -267,7 +288,8 @@ impl DoRemainingOperation for CleanerState { let (consumed_weight, remaining_contributions) = unbond_one_contribution::(project_id); *self = CleanerState::ContributionUnbonding(remaining_contributions, PhantomData::); Ok(consumed_weight) - }, + } + }, CleanerState::Finished(PhantomData::) => Err(Error::::FinalizerFinished.into()), @@ -340,13 +362,15 @@ fn remaining_participants_with_future_ct_deposit(project_id: ProjectI all_participants .into_iter() .filter(|account| { - ::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), account) > - Zero::zero() + ::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), account) + > Zero::zero() }) .count() as u64 } -fn reward_or_slash_one_evaluation(project_id: ProjectId) -> Result<(Weight, u64), DispatchError> { +fn reward_or_slash_one_evaluation( + project_id: ProjectId, +) -> Result<(Weight, u64), DispatchErrorWithPostInfo> { let project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectNotFound)?; let project_evaluations = Evaluations::::iter_prefix_values((project_id,)); let mut remaining_evaluations = project_evaluations.filter(|evaluation| evaluation.rewarded_or_slashed.is_none()); @@ -355,25 +379,41 @@ fn reward_or_slash_one_evaluation(project_id: ProjectId) -> Result<(W if let Some(evaluation) = remaining_evaluations.next() { // TODO: This base weight and the one in all other functions below should be calculated with a benchmark let remaining = remaining_evaluations.count() as u64; - match project_details.evaluation_round_info.evaluators_outcome { EvaluatorsOutcome::Rewarded(_) => { + let mut weight_consumed = crate::Call::::evaluation_reward_payout_for { + project_id: evaluation.project_id, + evaluator: evaluation.evaluator.clone(), + bond_id: evaluation.id, + } + .get_dispatch_info() + .weight; + match Pallet::::do_evaluation_reward_payout_for( &T::PalletId::get().into_account_truncating(), evaluation.project_id, &evaluation.evaluator, evaluation.id, ) { - Ok(_) => (), - Err(e) => Pallet::::deposit_event(Event::EvaluationRewardFailed { - project_id: evaluation.project_id, - evaluator: evaluation.evaluator.clone(), - id: evaluation.id, - error: e, - }), + Ok(result) => { + if let Some(weight) = result.actual_weight { + weight_consumed = weight + }; + }, + Err(e) => { + if let Some(weight) = e.post_info.actual_weight { + weight_consumed = weight + }; + Pallet::::deposit_event(Event::EvaluationRewardFailed { + project_id: evaluation.project_id, + evaluator: evaluation.evaluator.clone(), + id: evaluation.id, + error: e.error, + }) + }, }; - Ok((base_weight.saturating_add(WeightInfoOf::::evaluation_reward_payout_for()), remaining)) + Ok((base_weight.saturating_add(weight_consumed), remaining)) }, EvaluatorsOutcome::Slashed => { match Pallet::::do_evaluation_slash_for( @@ -494,8 +534,8 @@ fn release_future_ct_deposit_one_participant(project_id: ProjectId) - let remaining_participants = all_participants .into_iter() .filter(|account| { - ::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), account) > - Zero::zero() + ::NativeCurrency::balance_on_hold(&HoldReason::FutureDeposit(project_id).into(), account) + > Zero::zero() }) .collect_vec(); let mut iter_participants = remaining_participants.into_iter(); @@ -519,11 +559,11 @@ fn release_future_ct_deposit_one_participant(project_id: ProjectId) - }); // TODO: replace when benchmark is done // return (base_weight.saturating_add(WeightInfoOf::::release_future_ct_deposit_for()), iter_participants.collect_vec()); - return (base_weight, iter_participants.count() as u64) + return (base_weight, iter_participants.count() as u64); }, }; } - return (base_weight, 0u64) + (base_weight, 0u64) } fn release_funds_one_contribution(project_id: ProjectId) -> (Weight, u64) { @@ -671,10 +711,13 @@ fn mint_ct_for_one_bid(project_id: ProjectId) -> (Weight, u64) { project_id: bid.project_id, claimer: bid.bidder.clone(), id: bid.id, - error: e, + error: e.error, }), }; - (base_weight.saturating_add(WeightInfoOf::::bid_ct_mint_for()), remaining_bids.count() as u64) + ( + base_weight.saturating_add(WeightInfoOf::::bid_ct_mint_for_with_ct_account_creation()), + remaining_bids.count() as u64, + ) } else { (base_weight, 0u64) } @@ -697,11 +740,11 @@ fn mint_ct_for_one_contribution(project_id: ProjectId) -> (Weight, u6 project_id: contribution.project_id, claimer: contribution.contributor.clone(), id: contribution.id, - error: e, + error: e.error, }), }; ( - base_weight.saturating_add(WeightInfoOf::::contribution_ct_mint_for()), + base_weight.saturating_add(WeightInfoOf::::contribution_ct_mint_for_with_ct_account_creation()), remaining_contributions.count() as u64, ) } else { diff --git a/pallets/funding/src/instantiator.rs b/pallets/funding/src/instantiator.rs index fc1a149fd..eab0b88a3 100644 --- a/pallets/funding/src/instantiator.rs +++ b/pallets/funding/src/instantiator.rs @@ -111,7 +111,7 @@ impl< pub fn execute(&mut self, execution: impl FnOnce() -> R) -> R { #[cfg(feature = "std")] if let Some(ext) = &self.ext { - return ext.borrow_mut().execute_with(execution) + return ext.borrow_mut().execute_with(execution); } execution() } @@ -401,6 +401,12 @@ impl< expected_reserved_plmc_balances: Vec>, total_plmc_supply: BalanceOf, ) { + // just in case we forgot to merge accounts: + let expected_free_plmc_balances = + Self::generic_map_operation(vec![expected_free_plmc_balances], MergeOperation::Add); + let expected_reserved_plmc_balances = + Self::generic_map_operation(vec![expected_reserved_plmc_balances], MergeOperation::Add); + let project_details = self.get_project_details(project_id); let accounts = expected_reserved_plmc_balances.accounts(); let expected_ct_account_deposits = accounts @@ -731,10 +737,8 @@ impl< let last_event_record = events.into_iter().last().expect("No events found for this action."); let last_event = last_event_record.event; let maybe_funding_event = last_event.try_into(); - if let Ok(funding_event) = maybe_funding_event { - if let Event::TransitionError { project_id, error } = funding_event { - panic!("Project {:?} transition failed in on_initialize: {:?}", project_id, error); - } + if let Ok(Event::TransitionError { project_id, error }) = maybe_funding_event { + panic!("Project {:?} transition failed in on_initialize: {:?}", project_id, error); } } @@ -745,11 +749,10 @@ impl< let last_event = last_event_record.event; let maybe_funding_event = ::RuntimeEvent::from(last_event).try_into(); if let Ok(funding_event) = maybe_funding_event { - if let Event::TransitionError { project_id: _, error } = funding_event { - if let DispatchError::Module(module_error) = error { - let pallet_error: Error = Decode::decode(&mut &module_error.error[..]).unwrap(); - return Err(pallet_error) - } + if let Event::TransitionError { project_id: _, error: DispatchError::Module(module_error) } = funding_event + { + let pallet_error: Error = Decode::decode(&mut &module_error.error[..]).unwrap(); + return Err(pallet_error); } } Ok(()) @@ -865,7 +868,7 @@ impl< pub fn start_evaluation(&mut self, project_id: ProjectId, caller: AccountIdOf) -> Result<(), DispatchError> { assert_eq!(self.get_project_details(project_id).status, ProjectStatus::Application); - self.execute(|| crate::Pallet::::do_evaluation_start(caller, project_id))?; + self.execute(|| crate::Pallet::::do_start_evaluation(caller, project_id).unwrap()); assert_eq!(self.get_project_details(project_id).status, ProjectStatus::EvaluationRound); Ok(()) @@ -885,11 +888,11 @@ impl< &mut self, project_id: ProjectId, bonds: Vec>, - ) -> Result<(), DispatchError> { + ) -> DispatchResultWithPostInfo { for UserToUSDBalance { account, usd_amount } in bonds { self.execute(|| crate::Pallet::::do_evaluate(&account, project_id, usd_amount))?; } - Ok(()) + Ok(().into()) } pub fn start_auction(&mut self, project_id: ProjectId, caller: AccountIdOf) -> Result<(), DispatchError> { @@ -904,7 +907,7 @@ impl< assert_eq!(self.get_project_details(project_id).status, ProjectStatus::AuctionInitializePeriod); - self.execute(|| crate::Pallet::::do_english_auction(caller, project_id))?; + self.execute(|| crate::Pallet::::do_english_auction(caller, project_id).unwrap()); assert_eq!(self.get_project_details(project_id).status, ProjectStatus::AuctionRound(AuctionPhase::English)); @@ -952,13 +955,11 @@ impl< project_id } - pub fn bid_for_users(&mut self, project_id: ProjectId, bids: Vec>) -> Result<(), DispatchError> { + pub fn bid_for_users(&mut self, project_id: ProjectId, bids: Vec>) { for bid in bids { - self.execute(|| { - crate::Pallet::::do_bid(&bid.bidder, project_id, bid.amount, bid.multiplier, bid.asset) - })?; + self.execute(|| crate::Pallet::::do_bid(&bid.bidder, project_id, bid.amount, bid.multiplier, bid.asset)) + .unwrap(); } - Ok(()) } pub fn start_community_funding(&mut self, project_id: ProjectId) -> Result<(), DispatchError> { @@ -1045,7 +1046,7 @@ impl< self.mint_plmc_to(plmc_ct_account_deposits.clone()); self.mint_statemint_asset_to(funding_asset_deposits.clone()); - self.bid_for_users(project_id, bids.clone()).expect("Bidding should work"); + self.bid_for_users(project_id, bids.clone()); self.do_reserved_plmc_assertions( total_plmc_participation_locked.merge_accounts(MergeOperation::Add), @@ -1129,9 +1130,9 @@ impl< assert!( matches!( project_details.status, - ProjectStatus::FundingSuccessful | - ProjectStatus::FundingFailed | - ProjectStatus::AwaitingProjectDecision + ProjectStatus::FundingSuccessful + | ProjectStatus::FundingFailed + | ProjectStatus::AwaitingProjectDecision ), "Project should be in Finished status" ); @@ -1151,7 +1152,7 @@ impl< if contributions.is_empty() { self.start_remainder_or_end_funding(project_id).unwrap(); - return (project_id, accepted_bids) + return (project_id, accepted_bids); } let ct_price = self.get_project_details(project_id).weighted_average_price.unwrap(); @@ -1205,10 +1206,7 @@ impl< total_plmc_participation_locked.merge_accounts(MergeOperation::Add), HoldReason::Participation(project_id).into(), ); - self.do_contribution_transferred_statemint_asset_assertions( - funding_asset_deposits.merge_accounts(MergeOperation::Add), - project_id, - ); + self.do_contribution_transferred_statemint_asset_assertions(funding_asset_deposits, project_id); self.do_free_plmc_assertions(expected_free_plmc_balances.merge_accounts(MergeOperation::Add)); self.do_free_statemint_asset_assertions(prev_funding_asset_balances.merge_accounts(MergeOperation::Add)); assert_eq!(self.get_plmc_total_supply(), post_supply); @@ -1238,7 +1236,7 @@ impl< ProjectStatus::FundingSuccessful => return project_id, ProjectStatus::RemainderRound if remainder_contributions.is_empty() => { self.finish_funding(project_id).unwrap(); - return project_id + return project_id; }, _ => {}, }; @@ -1249,9 +1247,9 @@ impl< .clone() .into_iter() .filter(|account| { - evaluations.accounts().contains(account).not() && - bids.accounts().contains(account).not() && - community_contributions.accounts().contains(account).not() + evaluations.accounts().contains(account).not() + && bids.accounts().contains(account).not() + && community_contributions.accounts().contains(account).not() }) .collect_vec(); let asset_id = remainder_contributions[0].asset.to_statemint_id(); @@ -1326,10 +1324,10 @@ impl< assert_eq!( project_details.remaining_contribution_tokens.0 + project_details.remaining_contribution_tokens.1, - project_metadata.total_allocation_size.0 + project_metadata.total_allocation_size.1 - - auction_bought_tokens - - community_bought_tokens - - remainder_bought_tokens, + project_metadata.total_allocation_size.0 + project_metadata.total_allocation_size.1 + - auction_bought_tokens + - community_bought_tokens + - remainder_bought_tokens, "Remaining CTs are incorrect" ); } @@ -1356,7 +1354,7 @@ impl< community_contributions, remainder_contributions, ), - ProjectStatus::RemainderRound => + ProjectStatus::RemainderRound => { self.create_remainder_contributing_project( project_metadata, issuer, @@ -1364,11 +1362,14 @@ impl< bids, community_contributions, ) - .0, - ProjectStatus::CommunityRound => - self.create_community_contributing_project(project_metadata, issuer, evaluations, bids).0, - ProjectStatus::AuctionRound(AuctionPhase::English) => - self.create_auctioning_project(project_metadata, issuer, evaluations), + .0 + }, + ProjectStatus::CommunityRound => { + self.create_community_contributing_project(project_metadata, issuer, evaluations, bids).0 + }, + ProjectStatus::AuctionRound(AuctionPhase::English) => { + self.create_auctioning_project(project_metadata, issuer, evaluations) + }, ProjectStatus::EvaluationRound => self.create_evaluating_project(project_metadata, issuer), ProjectStatus::Application => self.create_new_project(project_metadata, issuer), _ => panic!("unsupported project creation in that status"), @@ -1410,7 +1411,7 @@ pub mod async_features { ) { loop { if !block_orchestrator.continue_running() { - break + break; } let maybe_target_reached = block_orchestrator.advance_to_next_target(instantiator.clone()).await; @@ -1423,6 +1424,17 @@ pub mod async_features { } } + impl< + T: Config + pallet_balances::Config>, + AllPalletsWithoutSystem: OnFinalize> + OnIdle> + OnInitialize>, + RuntimeEvent: From> + TryInto> + Parameter + Member + IsType<::RuntimeEvent>, + > Default for BlockOrchestrator + { + fn default() -> Self { + Self::new() + } + } + impl< T: Config + pallet_balances::Config>, AllPalletsWithoutSystem: OnFinalize> + OnIdle> + OnInitialize>, @@ -1508,11 +1520,6 @@ pub mod async_features { ) -> ProjectId { let mut inst = instantiator.lock().await; - let asset_account_deposit = - inst.execute(|| ::ContributionTokenCurrency::deposit_required(One::one())); - let ed = Instantiator::::get_ed(); - dbg!(asset_account_deposit); - dbg!(ed); let now = inst.current_block(); // One ED for the issuer, one for the escrow account inst.mint_plmc_to(vec![UserToPLMCBalance::new( @@ -1580,7 +1587,7 @@ pub mod async_features { assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AuctionInitializePeriod); - inst.execute(|| crate::Pallet::::do_english_auction(caller, project_id))?; + inst.execute(|| crate::Pallet::::do_english_auction(caller, project_id).unwrap()); assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AuctionRound(AuctionPhase::English)); @@ -1773,7 +1780,7 @@ pub mod async_features { inst.mint_plmc_to(plmc_ct_account_deposits.clone()); inst.mint_statemint_asset_to(funding_asset_deposits.clone()); - inst.bid_for_users(project_id, bids.clone()).expect("Bidding should work"); + inst.bid_for_users(project_id, bids.clone()); inst.do_reserved_plmc_assertions( total_plmc_participation_locked.merge_accounts(MergeOperation::Add), @@ -1878,7 +1885,7 @@ pub mod async_features { async_start_remainder_or_end_funding(instantiator.clone(), block_orchestrator.clone(), project_id) .await .unwrap(); - return (project_id, accepted_bids) + return (project_id, accepted_bids); } let mut inst = instantiator.lock().await; @@ -1999,9 +2006,9 @@ pub mod async_features { assert!( matches!( project_details.status, - ProjectStatus::FundingSuccessful | - ProjectStatus::FundingFailed | - ProjectStatus::AwaitingProjectDecision + ProjectStatus::FundingSuccessful + | ProjectStatus::FundingFailed + | ProjectStatus::AwaitingProjectDecision ), "Project should be in Finished status" ); @@ -2055,7 +2062,7 @@ pub mod async_features { ProjectStatus::FundingSuccessful => return project_id, ProjectStatus::RemainderRound if remainder_contributions.is_empty() => { inst.finish_funding(project_id).unwrap(); - return project_id + return project_id; }, _ => {}, }; @@ -2066,9 +2073,9 @@ pub mod async_features { .clone() .into_iter() .filter(|account| { - evaluations.accounts().contains(account).not() && - bids.accounts().contains(account).not() && - community_contributions.accounts().contains(account).not() + evaluations.accounts().contains(account).not() + && bids.accounts().contains(account).not() + && community_contributions.accounts().contains(account).not() }) .collect_vec(); let asset_id = remainder_contributions[0].asset.to_statemint_id(); @@ -2161,10 +2168,10 @@ pub mod async_features { assert_eq!( project_details.remaining_contribution_tokens.0 + project_details.remaining_contribution_tokens.1, - project_metadata.total_allocation_size.0 + project_metadata.total_allocation_size.1 - - auction_bought_tokens - - community_bought_tokens - - remainder_bought_tokens, + project_metadata.total_allocation_size.0 + project_metadata.total_allocation_size.1 + - auction_bought_tokens + - community_bought_tokens + - remainder_bought_tokens, "Remaining CTs are incorrect" ); } @@ -2182,7 +2189,7 @@ pub mod async_features { test_project_params: TestProjectParams, ) -> ProjectId { match test_project_params.expected_state { - ProjectStatus::FundingSuccessful => + ProjectStatus::FundingSuccessful => { async_create_finished_project( instantiator, block_orchestrator, @@ -2193,8 +2200,9 @@ pub mod async_features { test_project_params.community_contributions, test_project_params.remainder_contributions, ) - .await, - ProjectStatus::RemainderRound => + .await + }, + ProjectStatus::RemainderRound => { async_create_remainder_contributing_project( instantiator, block_orchestrator, @@ -2205,8 +2213,9 @@ pub mod async_features { test_project_params.community_contributions, ) .map(|(project_id, _)| project_id) - .await, - ProjectStatus::CommunityRound => + .await + }, + ProjectStatus::CommunityRound => { async_create_community_contributing_project( instantiator, block_orchestrator, @@ -2216,8 +2225,9 @@ pub mod async_features { test_project_params.bids, ) .map(|(project_id, _)| project_id) - .await, - ProjectStatus::AuctionRound(AuctionPhase::English) => + .await + }, + ProjectStatus::AuctionRound(AuctionPhase::English) => { async_create_auctioning_project( instantiator, block_orchestrator, @@ -2225,12 +2235,15 @@ pub mod async_features { test_project_params.issuer, test_project_params.evaluations, ) - .await, - ProjectStatus::EvaluationRound => + .await + }, + ProjectStatus::EvaluationRound => { async_create_evaluating_project(instantiator, test_project_params.metadata, test_project_params.issuer) - .await, - ProjectStatus::Application => - async_create_new_project(instantiator, test_project_params.metadata, test_project_params.issuer).await, + .await + }, + ProjectStatus::Application => { + async_create_new_project(instantiator, test_project_params.metadata, test_project_params.issuer).await + }, _ => panic!("unsupported project creation in that status"), } } @@ -2248,9 +2261,9 @@ pub mod async_features { let time_to_evaluation: BlockNumberFor = time_to_new_project + Zero::zero(); // we immediately start the auction, so we dont wait for T::AuctionInitializePeriodDuration. let time_to_auction: BlockNumberFor = time_to_evaluation + ::EvaluationDuration::get(); - let time_to_community: BlockNumberFor = time_to_auction + - ::EnglishAuctionDuration::get() + - ::CandleAuctionDuration::get(); + let time_to_community: BlockNumberFor = time_to_auction + + ::EnglishAuctionDuration::get() + + ::CandleAuctionDuration::get(); let time_to_remainder: BlockNumberFor = time_to_community + ::CommunityFundingDuration::get(); let time_to_finish: BlockNumberFor = time_to_remainder + ::RemainderFundingDuration::get(); let mut inst = mutex_inst.lock().await; @@ -2358,8 +2371,6 @@ pub mod async_features { instantiator: Instantiator, projects: Vec>, ) -> (Vec, Instantiator) { - // let tokio_runtime = Runtime::new().unwrap(); - use tokio::runtime::Builder; let tokio_runtime = Builder::new_current_thread().enable_all().build().unwrap(); let local = tokio::task::LocalSet::new(); @@ -2699,54 +2710,54 @@ pub struct BidInfoFilter { impl BidInfoFilter { pub(crate) fn matches_bid(&self, bid: &BidInfoOf) -> bool { if self.id.is_some() && self.id.unwrap() != bid.id { - return false + return false; } if self.project_id.is_some() && self.project_id.unwrap() != bid.project_id { - return false + return false; } if self.bidder.is_some() && self.bidder.clone().unwrap() != bid.bidder.clone() { - return false + return false; } if self.status.is_some() && self.status.as_ref().unwrap() != &bid.status { - return false + return false; } if self.original_ct_amount.is_some() && self.original_ct_amount.unwrap() != bid.original_ct_amount { - return false + return false; } if self.original_ct_usd_price.is_some() && self.original_ct_usd_price.unwrap() != bid.original_ct_usd_price { - return false + return false; } if self.final_ct_amount.is_some() && self.final_ct_amount.unwrap() != bid.final_ct_amount { - return false + return false; } if self.final_ct_usd_price.is_some() && self.final_ct_usd_price.unwrap() != bid.final_ct_usd_price { - return false + return false; } if self.funding_asset.is_some() && self.funding_asset.unwrap() != bid.funding_asset { - return false + return false; } - if self.funding_asset_amount_locked.is_some() && - self.funding_asset_amount_locked.unwrap() != bid.funding_asset_amount_locked + if self.funding_asset_amount_locked.is_some() + && self.funding_asset_amount_locked.unwrap() != bid.funding_asset_amount_locked { - return false + return false; } if self.multiplier.is_some() && self.multiplier.unwrap() != bid.multiplier { - return false + return false; } if self.plmc_bond.is_some() && self.plmc_bond.unwrap() != bid.plmc_bond { - return false + return false; } if self.plmc_vesting_info.is_some() && self.plmc_vesting_info.unwrap() != bid.plmc_vesting_info { - return false + return false; } if self.when.is_some() && self.when.unwrap() != bid.when { - return false + return false; } if self.funds_released.is_some() && self.funds_released.unwrap() != bid.funds_released { - return false + return false; } if self.ct_minted.is_some() && self.ct_minted.unwrap() != bid.ct_minted { - return false + return false; } true @@ -2778,17 +2789,42 @@ impl Default for BidInfoFilter { pub mod testing_macros { #[macro_export] + /// Example: + /// ``` + /// use pallet_funding::assert_close_enough; + /// use sp_arithmetic::Perquintill; + /// + /// let real = 98u64; + /// let desired = 100u64; + /// assert_close_enough!(real, desired, Perquintill::from_float(0.02)); + /// // This would fail + /// // assert_close_enough!(real, desired, Perquintill::from_float(0.01)); + /// ``` + /// + /// - Use this macro when you deal with operations with lots of decimals, and you are ok with the real value being an approximation of the desired one. + /// - The max_approximation should be an upper bound such that 1-real/desired <= approximation in the case where the desired is smaller than the real, + /// and 1-desired/real <= approximation in the case where the real is bigger than the desired. + /// - You probably should define the max_approximation from a float number or a percentage, like in the example. macro_rules! assert_close_enough { // Match when a message is provided ($real:expr, $desired:expr, $max_approximation:expr, $msg:expr) => { - let real_parts = Perquintill::from_rational($real, $desired); + if $real <= $desired { + let real_parts = Perquintill::from_rational($real, $desired); + } else { + let real_parts = Perquintill::from_rational($desired, $real); + } let one = Perquintill::from_percent(100u64); let real_approximation = one - real_parts; assert!(real_approximation <= $max_approximation, $msg); }; // Match when no message is provided ($real:expr, $desired:expr, $max_approximation:expr) => { - let real_parts = Perquintill::from_rational($real, $desired); + let real_parts; + if $real <= $desired { + real_parts = Perquintill::from_rational($real, $desired); + } else { + real_parts = Perquintill::from_rational($desired, $real); + } let one = Perquintill::from_percent(100u64); let real_approximation = one - real_parts; assert!( diff --git a/pallets/funding/src/lib.rs b/pallets/funding/src/lib.rs index 624e864e2..8a448e3b4 100644 --- a/pallets/funding/src/lib.rs +++ b/pallets/funding/src/lib.rs @@ -45,7 +45,7 @@ //! |---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------| //! | Creation | Issuer creates a project with the [`create()`](Pallet::create) extrinsic. | [`Application`](ProjectStatus::Application) | //! | Evaluation Start | Issuer starts the evaluation round with the [`start_evaluation()`](Pallet::start_evaluation) extrinsic. | [`EvaluationRound`](ProjectStatus::EvaluationRound) | -//! | Evaluation Submissions | Evaluators assess the project information, and if they think it is good enough to get funding, they bond Polimec's native token PLMC with [`bond_evaluation()`](Pallet::bond_evaluation) | [`EvaluationRound`](ProjectStatus::EvaluationRound) | +//! | Evaluation Submissions | Evaluators assess the project information, and if they think it is good enough to get funding, they bond Polimec's native token PLMC with [`bond_evaluation()`](Pallet::evaluate) | [`EvaluationRound`](ProjectStatus::EvaluationRound) | //! | Evaluation End | Evaluation round ends automatically after the [`Config::EvaluationDuration`] has passed. This is achieved by the [`on_initialize()`](Pallet::on_initialize) function. | [`AuctionInitializePeriod`](ProjectStatus::AuctionInitializePeriod) | //! | Auction Start | Issuer starts the auction round within the [`Config::AuctionInitializePeriodDuration`], by calling the extrinsic [`start_auction()`](Pallet::start_auction) | [`AuctionRound(English)`](ProjectStatus::AuctionRound) | //! | Bid Submissions | Institutional and Professional users can place bids with [`bid()`](Pallet::bid) by choosing their desired token price, amount, and multiplier (for vesting). Their bids are guaranteed to be considered | [`AuctionRound(English)`](ProjectStatus::AuctionRound) | | | @@ -66,7 +66,7 @@ //! * [`edit_metadata`](Pallet::edit_metadata) : Submit a new Hash of the project metadata. //! * [`start_evaluation`](Pallet::start_evaluation) : Start the Evaluation round of a project. //! * [`start_auction`](Pallet::start_auction) : Start the English Auction round of a project. -//! * [`bond_evaluation`](Pallet::bond_evaluation) : Bond PLMC on a project in the evaluation stage. A sort of "bet" that you think the project will be funded +//! * [`bond_evaluation`](Pallet::evaluate) : Bond PLMC on a project in the evaluation stage. A sort of "bet" that you think the project will be funded //! * [`failed_evaluation_unbond_for`](Pallet::failed_evaluation_unbond_for) : Unbond the PLMC bonded on a project's evaluation round for any user, if the project failed the evaluation. //! * [`bid`](Pallet::bid) : Perform a bid during the English or Candle Auction Round. //! * [`contribute`](Pallet::contribute) : Buy contribution tokens if a project during the Community or Remainder round @@ -243,13 +243,17 @@ pub mod pallet { use super::*; use crate::traits::{BondingRequirementCalculation, ProvideStatemintPrice, VestingDurationCalculation}; use frame_support::{ + dispatch::PostDispatchInfo, pallet_prelude::*, traits::{OnFinalize, OnIdle, OnInitialize}, }; use frame_system::pallet_prelude::*; use local_macros::*; use sp_arithmetic::Percent; - use sp_runtime::traits::{Convert, ConvertBack}; + use sp_runtime::{ + traits::{Convert, ConvertBack}, + DispatchErrorWithPostInfo, + }; #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] use crate::traits::SetPrices; @@ -385,6 +389,7 @@ pub mod pallet { type MaxProjectsToUpdatePerBlock: Get; /// How many distinct evaluations per user per project + #[pallet::constant] type MaxEvaluationsPerUser: Get; /// The maximum number of bids per user per project @@ -402,8 +407,10 @@ pub mod pallet { /// Weight information for extrinsics in this pallet. type WeightInfo: weights::WeightInfo; + #[pallet::constant] type FeeBrackets: Get::Balance)>>; + #[pallet::constant] type EvaluationSuccessThreshold: Get; type Vesting: polimec_common::ReleaseSchedule< @@ -413,12 +420,16 @@ pub mod pallet { Moment = BlockNumberFor, >; /// For now we expect 3 days until the project is automatically accepted. Timeline decided by MiCA regulations. + #[pallet::constant] type ManualAcceptanceDuration: Get>; /// For now we expect 4 days from acceptance to settlement due to MiCA regulations. + #[pallet::constant] type SuccessToSettlementTime: Get>; + #[pallet::constant] type EvaluatorSlash: Get; + #[pallet::constant] type TreasuryAccount: Get>; /// Convert 24 hours as FixedU128, to the corresponding amount of blocks in the same type as frame_system @@ -426,16 +437,28 @@ pub mod pallet { type BlockNumberToBalance: Convert, BalanceOf>; + #[pallet::constant] type PolimecReceiverInfo: Get; /// Range of max_message_size values for the hrmp config where we accept the incoming channel request + #[pallet::constant] type MaxMessageSizeThresholds: Get<(u32, u32)>; + /// Range of max_capacity_thresholds values for the hrmp config where we accept the incoming channel request + #[pallet::constant] type MaxCapacityThresholds: Get<(u32, u32)>; + /// max_capacity config required for the channel from polimec to the project + #[pallet::constant] type RequiredMaxCapacity: Get; + /// max_message_size config required for the channel from polimec to the project + #[pallet::constant] type RequiredMaxMessageSize: Get; + + /// max iterations for trying to insert a project on the projects_to_update storage + #[pallet::constant] + type MaxProjectsToUpdateInsertionAttempts: Get; } #[pallet::storage] @@ -928,6 +951,10 @@ pub mod pallet { NoFutureDepositHeld, /// The issuer doesn't have enough funds (ExistentialDeposit), to create the escrow account NotEnoughFundsForEscrowCreation, + /// Too many attempts to insert project in to ProjectsToUpdate storage + TooManyInsertionAttempts, + /// Reached bid limit for this user on this project + TooManyBids, } #[pallet::call] @@ -955,51 +982,64 @@ pub mod pallet { /// Starts the evaluation round of a project. It needs to be called by the project issuer. #[pallet::call_index(2)] - #[pallet::weight(WeightInfoOf::::start_evaluation())] - pub fn start_evaluation(origin: OriginFor, project_id: ProjectId) -> DispatchResult { + #[pallet::weight(WeightInfoOf::::start_evaluation(::MaxProjectsToUpdateInsertionAttempts::get() - 1))] + pub fn start_evaluation(origin: OriginFor, project_id: ProjectId) -> DispatchResultWithPostInfo { let issuer = ensure_signed(origin)?; - Self::do_evaluation_start(issuer, project_id) + Self::do_start_evaluation(issuer, project_id) } /// Starts the auction round for a project. From the next block forward, any professional or /// institutional user can set bids for a token_amount/token_price pair. /// Any bids from this point until the candle_auction starts, will be considered as valid. #[pallet::call_index(3)] - #[pallet::weight(WeightInfoOf::::start_auction())] - pub fn start_auction(origin: OriginFor, project_id: ProjectId) -> DispatchResult { + #[pallet::weight(WeightInfoOf::::start_auction_manually(::MaxProjectsToUpdateInsertionAttempts::get() - 1, 10_000u32))] + pub fn start_auction(origin: OriginFor, project_id: ProjectId) -> DispatchResultWithPostInfo { let issuer = ensure_signed(origin)?; Self::do_english_auction(issuer, project_id) } /// Bond PLMC for a project in the evaluation stage #[pallet::call_index(4)] - #[pallet::weight(WeightInfoOf::::bond_evaluation())] - pub fn bond_evaluation( + #[pallet::weight(WeightInfoOf::::evaluation_over_limit())] + pub fn evaluate( origin: OriginFor, project_id: ProjectId, #[pallet::compact] usd_amount: BalanceOf, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let evaluator = ensure_signed(origin)?; Self::do_evaluate(&evaluator, project_id, usd_amount) } /// Bid for a project in the Auction round #[pallet::call_index(5)] - #[pallet::weight(WeightInfoOf::::bid())] + #[pallet::weight(WeightInfoOf::::bid_no_ct_deposit( + // Last bid possible + ::MaxBidsPerUser::get() - 1, + // Assuming the current bucket is full, and has a price higher than the minimum. + // This user is buying 100% of the bid allocation, since each bucket has 10% of the allocation at a 10% increase + 10, + ))] pub fn bid( origin: OriginFor, project_id: ProjectId, #[pallet::compact] amount: BalanceOf, multiplier: T::Multiplier, asset: AcceptedFundingAsset, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let bidder = ensure_signed(origin)?; Self::do_bid(&bidder, project_id, amount, multiplier, asset) } /// Buy tokens in the Community or Remainder round at the price set in the Auction Round #[pallet::call_index(6)] - #[pallet::weight(WeightInfoOf::::contribute())] + #[pallet::weight(WeightInfoOf::::second_to_limit_contribution_ends_round( + // Last contribution possible before having to remove an old lower one + ::MaxContributionsPerUser::get() -1, + // Since we didn't remove any previous lower contribution, we can buy all remaining CTs and try to move to the next phase + ::MaxProjectsToUpdateInsertionAttempts::get() - 1, + // Assumed upper bound for deletion attempts for the previous scheduled transition + 10_000u32, + ))] pub fn contribute( origin: OriginFor, project_id: ProjectId, @@ -1037,37 +1077,37 @@ pub mod pallet { } #[pallet::call_index(9)] - #[pallet::weight(WeightInfoOf::::evaluation_reward_payout_for())] + #[pallet::weight(WeightInfoOf::::evaluation_reward_payout_for_with_ct_account_creation())] pub fn evaluation_reward_payout_for( origin: OriginFor, project_id: ProjectId, evaluator: AccountIdOf, bond_id: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let caller = ensure_signed(origin)?; Self::do_evaluation_reward_payout_for(&caller, project_id, &evaluator, bond_id) } #[pallet::call_index(10)] - #[pallet::weight(WeightInfoOf::::bid_ct_mint_for())] + #[pallet::weight(WeightInfoOf::::bid_ct_mint_for_with_ct_account_creation())] pub fn bid_ct_mint_for( origin: OriginFor, project_id: ProjectId, bidder: AccountIdOf, bid_id: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let caller = ensure_signed(origin)?; Self::do_bid_ct_mint_for(&caller, project_id, &bidder, bid_id) } #[pallet::call_index(11)] - #[pallet::weight(WeightInfoOf::::contribution_ct_mint_for())] + #[pallet::weight(WeightInfoOf::::contribution_ct_mint_for_with_ct_account_creation())] pub fn contribution_ct_mint_for( origin: OriginFor, project_id: ProjectId, contributor: AccountIdOf, contribution_id: u32, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let caller = ensure_signed(origin)?; Self::do_contribution_ct_mint_for(&caller, project_id, &contributor, contribution_id) } @@ -1121,12 +1161,15 @@ pub mod pallet { } #[pallet::call_index(16)] - #[pallet::weight(WeightInfoOf::::decide_project_outcome())] + #[pallet::weight(WeightInfoOf::::decide_project_outcome( + ::MaxProjectsToUpdateInsertionAttempts::get() - 1, + 10_000u32 + ))] pub fn decide_project_outcome( origin: OriginFor, project_id: ProjectId, outcome: FundingOutcomeDecision, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let caller = ensure_signed(origin)?; Self::do_decide_project_outcome(caller, project_id, outcome) } @@ -1241,7 +1284,7 @@ pub mod pallet { match update_type { // EvaluationRound -> AuctionInitializePeriod | EvaluationFailed UpdateType::EvaluationEnd => { - unwrap_result_or_skip!(Self::do_evaluation_end(project_id), project_id); + unwrap_result_or_skip!(Self::do_evaluation_end(project_id), project_id, |e| e); }, // AuctionInitializePeriod -> AuctionRound(AuctionPhase::English) @@ -1249,36 +1292,37 @@ pub mod pallet { UpdateType::EnglishAuctionStart => { unwrap_result_or_skip!( Self::do_english_auction(T::PalletId::get().into_account_truncating(), project_id), - project_id + project_id, + |e: DispatchErrorWithPostInfo| { e.error } ); }, // AuctionRound(AuctionPhase::English) -> AuctionRound(AuctionPhase::Candle) UpdateType::CandleAuctionStart => { - unwrap_result_or_skip!(Self::do_candle_auction(project_id), project_id); + unwrap_result_or_skip!(Self::do_candle_auction(project_id), project_id, |e| e); }, // AuctionRound(AuctionPhase::Candle) -> CommunityRound UpdateType::CommunityFundingStart => { - unwrap_result_or_skip!(Self::do_community_funding(project_id), project_id); + unwrap_result_or_skip!(Self::do_community_funding(project_id), project_id, |e| e); }, // CommunityRound -> RemainderRound UpdateType::RemainderFundingStart => { - unwrap_result_or_skip!(Self::do_remainder_funding(project_id), project_id) + unwrap_result_or_skip!(Self::do_remainder_funding(project_id), project_id, |e| e) }, // CommunityRound || RemainderRound -> FundingEnded UpdateType::FundingEnd => { - unwrap_result_or_skip!(Self::do_end_funding(project_id), project_id) + unwrap_result_or_skip!(Self::do_end_funding(project_id), project_id, |e| e) }, UpdateType::ProjectDecision(decision) => { - unwrap_result_or_skip!(Self::do_project_decision(project_id, decision), project_id) + unwrap_result_or_skip!(Self::do_project_decision(project_id, decision), project_id, |e| e) }, UpdateType::StartSettlement => { - unwrap_result_or_skip!(Self::do_start_settlement(project_id), project_id) + unwrap_result_or_skip!(Self::do_start_settlement(project_id), project_id, |e| e) }, } } @@ -1428,11 +1472,11 @@ pub mod local_macros { /// used to unwrap storage values that can be Err in places where an error cannot be returned, /// but an event should be emitted, and skip to the next iteration of a loop macro_rules! unwrap_result_or_skip { - ($option:expr, $project_id:expr) => { + ($option:expr, $project_id:expr, $error_handler:expr) => { match $option { Ok(val) => val, Err(err) => { - Self::deposit_event(Event::TransitionError { project_id: $project_id, error: err }); + Self::deposit_event(Event::TransitionError { project_id: $project_id, error: $error_handler(err) }); continue }, } diff --git a/pallets/funding/src/mock.rs b/pallets/funding/src/mock.rs index 09755424e..482f69385 100644 --- a/pallets/funding/src/mock.rs +++ b/pallets/funding/src/mock.rs @@ -351,13 +351,13 @@ impl Config for TestRuntime { type FeeBrackets = FeeBrackets; type FundingCurrency = StatemintAssets; type ManualAcceptanceDuration = ManualAcceptanceDuration; - // Low value to simplify the tests type MaxBidsPerUser = ConstU32<4>; type MaxCapacityThresholds = MaxCapacityThresholds; type MaxContributionsPerUser = ConstU32<4>; type MaxEvaluationsPerUser = ConstU32<4>; type MaxMessageSizeThresholds = MaxMessageSizeThresholds; - type MaxProjectsToUpdatePerBlock = ConstU32<100>; + type MaxProjectsToUpdateInsertionAttempts = ConstU32<10>; + type MaxProjectsToUpdatePerBlock = ConstU32<5>; type Multiplier = Multiplier; type NativeCurrency = Balances; type PalletId = FundingPalletId; diff --git a/pallets/funding/src/tests.rs b/pallets/funding/src/tests.rs index c28de0d6a..9993766ce 100644 --- a/pallets/funding/src/tests.rs +++ b/pallets/funding/src/tests.rs @@ -107,6 +107,30 @@ pub mod defaults { } } + pub fn knowledge_hub_project(nonce: u64) -> ProjectMetadataOf { + let bounded_name = BoundedVec::try_from("Contribution Token TEST".as_bytes().to_vec()).unwrap(); + let bounded_symbol = BoundedVec::try_from("CTEST".as_bytes().to_vec()).unwrap(); + let metadata_hash = hashed(format!("{}-{}", METADATA, nonce)); + let project_metadata = ProjectMetadataOf:: { + token_information: CurrencyMetadata { + name: bounded_name, + symbol: bounded_symbol, + decimals: ASSET_DECIMALS, + }, + mainnet_token_max_supply: 8_000_000 * ASSET_UNIT, + total_allocation_size: (50_000 * ASSET_UNIT, 50_000 * ASSET_UNIT), + minimum_price: PriceOf::::from_float(10.0), + ticket_size: TicketSize { minimum: Some(1), maximum: None }, + participants_size: ParticipantsSize { minimum: Some(2), maximum: None }, + funding_thresholds: Default::default(), + conversion_rate: 0, + participation_currencies: AcceptedFundingAsset::USDT, + funding_destination_account: ISSUER, + offchain_information_hash: Some(metadata_hash), + }; + project_metadata + } + pub fn default_plmc_balances() -> Vec> { vec![ UserToPLMCBalance::new(ISSUER, 20_000 * PLMC), @@ -128,6 +152,14 @@ pub mod defaults { ] } + pub fn knowledge_hub_evaluations() -> Vec> { + vec![ + UserToUSDBalance::new(EVALUATOR_1, 75_000 * USDT_UNIT), + UserToUSDBalance::new(EVALUATOR_2, 65_000 * USDT_UNIT), + UserToUSDBalance::new(EVALUATOR_3, 60_000 * USDT_UNIT), + ] + } + pub fn default_failing_evaluations() -> Vec> { vec![UserToUSDBalance::new(EVALUATOR_1, 3_000 * PLMC), UserToUSDBalance::new(EVALUATOR_2, 1_000 * PLMC)] } @@ -140,6 +172,18 @@ pub mod defaults { ] } + pub fn knowledge_hub_bids() -> Vec> { + // This should reflect the bidding currency, which currently is USDT + vec![ + BidParams::new(BIDDER_1, 10_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(BIDDER_2, 20_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(BIDDER_3, 20_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(BIDDER_4, 10_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(BIDDER_5, 5_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(BIDDER_6, 5_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + ] + } + pub fn default_community_buys() -> Vec> { vec![ ContributionParams::new(BUYER_1, 8_100 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), @@ -156,6 +200,18 @@ pub mod defaults { ] } + pub fn knowledge_hub_buys() -> Vec> { + vec![ + ContributionParams::new(BUYER_1, 4_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_2, 2_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_3, 2_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_4, 5_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_5, 30_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_6, 5_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_7, 2_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), + ] + } + pub fn default_weights() -> Vec { vec![20u8, 15u8, 10u8, 25u8, 30u8] } @@ -366,65 +422,17 @@ mod evaluation_round_success { fn rewards_are_paid_full_funding() { let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); - let bounded_name = BoundedVec::try_from("Contribution Token TEST".as_bytes().to_vec()).unwrap(); - let bounded_symbol = BoundedVec::try_from("CTEST".as_bytes().to_vec()).unwrap(); - let metadata_hash = hashed(format!("{}-{}", METADATA, 420)); - let project_metadata = ProjectMetadataOf:: { - token_information: CurrencyMetadata { - name: bounded_name, - symbol: bounded_symbol, - decimals: ASSET_DECIMALS, - }, - mainnet_token_max_supply: 8_000_000 * ASSET_UNIT, - total_allocation_size: (50_000 * ASSET_UNIT, 50_000 * ASSET_UNIT), - minimum_price: PriceOf::::from_float(1.0), - ticket_size: TicketSize { minimum: Some(1), maximum: None }, - participants_size: ParticipantsSize { minimum: Some(2), maximum: None }, - funding_thresholds: Default::default(), - conversion_rate: 0, - participation_currencies: AcceptedFundingAsset::USDT, - funding_destination_account: ISSUER, - offchain_information_hash: Some(metadata_hash), - }; - - // all values taken from the knowledge hub - let evaluations: Vec> = default_evaluations(); - - let bids: Vec> = vec![ - BidParams::new(BIDDER_1, 10_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), - BidParams::new(BIDDER_2, 20_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), - BidParams::new(BIDDER_4, 20_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), - ]; - - let contributions: Vec> = vec![ - ContributionParams::new(BUYER_1, 4_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_2, 2_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_3, 2_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_4, 5_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_5, 30_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_6, 5_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_7, 2_000 * ASSET_UNIT, 1u8, AcceptedFundingAsset::USDT), - ]; - - let (project_id, _) = inst.create_community_contributing_project(project_metadata, ISSUER, evaluations, bids); - let details = inst.get_project_details(project_id); - let ct_price = details.weighted_average_price.unwrap(); - let plmc_deposits = MockInstantiator::calculate_contributed_plmc_spent(contributions.clone(), ct_price); - let existential_deposits = plmc_deposits.accounts().existential_deposits(); - let ct_account_deposits = plmc_deposits.accounts().ct_account_deposits(); - let funding_deposits = - MockInstantiator::calculate_contributed_funding_asset_spent(contributions.clone(), ct_price); + let project_metadata = knowledge_hub_project(0); + let evaluations = knowledge_hub_evaluations(); + let bids = knowledge_hub_bids(); + let contributions = knowledge_hub_buys(); - inst.mint_plmc_to(plmc_deposits); - inst.mint_plmc_to(existential_deposits); - inst.mint_plmc_to(ct_account_deposits); - inst.mint_statemint_asset_to(funding_deposits); + let project_id = + inst.create_finished_project(project_metadata, ISSUER, evaluations, bids, contributions, vec![]); - inst.contribute_for_users(project_id, contributions).unwrap(); - inst.finish_funding(project_id).unwrap(); inst.advance_time(::SuccessToSettlementTime::get()).unwrap(); - inst.advance_time(10).unwrap(); + let actual_reward_balances = inst.execute(|| { vec![ (EVALUATOR_1, ::ContributionTokenCurrency::balance(project_id, EVALUATOR_1)), @@ -432,13 +440,15 @@ mod evaluation_round_success { (EVALUATOR_3, ::ContributionTokenCurrency::balance(project_id, EVALUATOR_3)), ] }); - let expected_ct_rewards = - vec![(EVALUATOR_1, 17214953271028), (EVALUATOR_2, 5607476635514), (EVALUATOR_3, 6_379_471_698_137)]; + let expected_ct_rewards = vec![ + (EVALUATOR_1, 1_332_4_500_000_000), + (EVALUATOR_2, 917_9_100_000_000), + (EVALUATOR_3, 710_6_400_000_000), + ]; for (real, desired) in zip(actual_reward_balances.iter(), expected_ct_rewards.iter()) { - assert_eq!(real.0, desired.0, "bad accounts order"); - // 0.01 parts of a Perbill - assert_close_enough!(real.1, desired.1, Perquintill::from_parts(10_000_000u64)); + // TODO: Check if either knowledge hub needs updating, or we need to update our weighted average price calculation + assert_close_enough!(real.1, desired.1, Perquintill::from_float(0.01)); } } @@ -748,64 +758,7 @@ mod auction_round_success { )]); inst.mint_statemint_asset_to(necessary_usdt_for_bid); - inst.bid_for_users(project_id, vec![evaluator_bid]).unwrap(); - } - - #[test] - fn evaluation_bond_counts_towards_bid_vec_full() { - let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); - let issuer = ISSUER; - let project = default_project(inst.get_new_nonce(), issuer); - let mut evaluations = default_evaluations(); - let evaluator_bidder = 69; - let evaluator_bid = - BidParams::new(evaluator_bidder, 600 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT); - - let mut bids = Vec::new(); - for _ in 0..::MaxBidsPerUser::get() { - bids.push(BidParams::new(evaluator_bidder, 100 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT)); - } - - let fill_necessary_plmc_for_bids = MockInstantiator::calculate_auction_plmc_spent(&bids.clone(), None); - let fill_necessary_usdt_for_bids = MockInstantiator::calculate_auction_funding_asset_spent(&bids, None); - - let bid_necessary_plmc = MockInstantiator::calculate_auction_plmc_spent(&vec![evaluator_bid.clone()], None); - let bid_necessary_usdt = - MockInstantiator::calculate_auction_funding_asset_spent(&vec![evaluator_bid.clone()], None); - - let evaluation_bond = - MockInstantiator::sum_balance_mappings(vec![fill_necessary_plmc_for_bids, bid_necessary_plmc]); - let plmc_available_for_participation = - evaluation_bond - ::EvaluatorSlash::get() * evaluation_bond; - - let evaluation_usd_amount = ::PriceProvider::get_price(PLMC_STATEMINT_ID) - .unwrap() - .saturating_mul_int(evaluation_bond); - evaluations.push(UserToUSDBalance::new(evaluator_bidder, evaluation_usd_amount)); - - let project_id = inst.create_auctioning_project(project, issuer, evaluations); - - inst.mint_plmc_to(vec![UserToPLMCBalance::new( - evaluator_bidder, - evaluation_bond - plmc_available_for_participation, - )]); - inst.mint_statemint_asset_to(fill_necessary_usdt_for_bids); - inst.mint_statemint_asset_to(bid_necessary_usdt); - - inst.bid_for_users(project_id, bids).unwrap(); - inst.bid_for_users(project_id, vec![evaluator_bid]).unwrap(); - - let evaluation_bonded = inst.execute(|| { - ::NativeCurrency::balance_on_hold( - &HoldReason::Evaluation(project_id.into()).into(), - &evaluator_bidder, - ) - }); - assert_close_enough!( - evaluation_bonded, - ::EvaluatorSlash::get() * evaluation_bond, - Perquintill::from_parts(1_000_000_000) - ); + inst.bid_for_users(project_id, vec![evaluator_bid]); } #[test] @@ -829,45 +782,82 @@ mod auction_round_success { inst.mint_plmc_to(plmc_funding); inst.mint_statemint_asset_to(statemint_funding); - inst.bid_for_users(project_id, bids).unwrap(); + inst.bid_for_users(project_id, bids); inst.start_community_funding(project_id).unwrap(); - // let token_price = inst.get_project_details(project_id).weighted_average_price.unwrap(); - - // let price_in_10_decimals = token_price.checked_mul_int(1_0_000_000_000_u128).unwrap(); - // let price_in_12_decimals = token_price.checked_mul_int(1_000_000_000_000_u128).unwrap(); - // assert_eq!(price_in_10_decimals, 16_3_333_333_333_u128); - // assert_eq!(price_in_12_decimals, 16_333_333_333_333_u128); } #[test] fn price_calculation_2() { - // From the knowledge hub + // From the knowledge hub: https://hub.polimec.org/learn/calculation-example#auction-round-calculation-example let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); - let project_metadata = default_project(inst.get_new_nonce(), ISSUER); + + const ADAM: u64 = 60; + const TOM: u64 = 61; + const SOFIA: u64 = 62; + const FRED: u64 = 63; + const ANNA: u64 = 64; + const DAMIAN: u64 = 65; + + let accounts = vec![ADAM, TOM, SOFIA, FRED, ANNA, DAMIAN]; + + let bounded_name = BoundedVec::try_from("Contribution Token TEST".as_bytes().to_vec()).unwrap(); + let bounded_symbol = BoundedVec::try_from("CTEST".as_bytes().to_vec()).unwrap(); + let metadata_hash = hashed(format!("{}-{}", METADATA, 0)); + let project_metadata = ProjectMetadata { + token_information: CurrencyMetadata { + name: bounded_name, + symbol: bounded_symbol, + decimals: ASSET_DECIMALS, + }, + mainnet_token_max_supply: 8_000_000 * ASSET_UNIT, + total_allocation_size: (50_000 * ASSET_UNIT, 50_000 * ASSET_UNIT), + minimum_price: PriceOf::::from_float(10.0), + ticket_size: TicketSize { minimum: Some(1), maximum: None }, + participants_size: ParticipantsSize { minimum: Some(2), maximum: None }, + funding_thresholds: Default::default(), + conversion_rate: 0, + participation_currencies: AcceptedFundingAsset::USDT, + funding_destination_account: ISSUER, + offchain_information_hash: Some(metadata_hash), + }; + + // overfund with plmc + let plmc_fundings = accounts + .iter() + .map(|acc| UserToPLMCBalance { account: acc.clone(), plmc_amount: PLMC * 1_000_000 }) + .collect_vec(); + let usdt_fundings = accounts + .iter() + .map(|acc| UserToStatemintAsset { + account: acc.clone(), + asset_amount: US_DOLLAR * 1_000_000, + asset_id: AcceptedFundingAsset::USDT.to_statemint_id(), + }) + .collect_vec(); + inst.mint_plmc_to(plmc_fundings); + inst.mint_statemint_asset_to(usdt_fundings); + let project_id = inst.create_auctioning_project(project_metadata, ISSUER, default_evaluations()); + let bids = vec![ - BidParams::new(BIDDER_1, 10_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), - BidParams::new(BIDDER_2, 40_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), - BidParams::new(BIDDER_3, 35_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(ADAM, 10_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(TOM, 20_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(SOFIA, 20_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(FRED, 10_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(ANNA, 5_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), + BidParams::new(DAMIAN, 5_000 * ASSET_UNIT, 1.into(), 1u8, AcceptedFundingAsset::USDT), ]; - let statemint_funding = MockInstantiator::calculate_auction_funding_asset_spent(&bids, None); - let plmc_funding = MockInstantiator::calculate_auction_plmc_spent(&bids, None); - let ed_funding = plmc_funding.accounts().existential_deposits(); - let ct_account_deposits = plmc_funding.accounts().ct_account_deposits(); - - inst.mint_plmc_to(ed_funding); - inst.mint_plmc_to(plmc_funding); - inst.mint_plmc_to(ct_account_deposits); - inst.mint_statemint_asset_to(statemint_funding); - - inst.bid_for_users(project_id, bids).unwrap(); + inst.bid_for_users(project_id, bids); inst.start_community_funding(project_id).unwrap(); - let token_price = inst.get_project_details(project_id).weighted_average_price.unwrap().to_float(); - assert_eq!(token_price, 1.283606557377049); + let token_price = + inst.get_project_details(project_id).weighted_average_price.unwrap().saturating_mul_int(ASSET_UNIT); + let desired_price = PriceOf::::from_float(11.1818f64).saturating_mul_int(ASSET_UNIT); + + assert_close_enough!(token_price, desired_price, Perquintill::from_float(0.01)); } #[test] @@ -933,7 +923,7 @@ mod auction_round_success { multiplier: bid_info.multiplier, asset: bid_info.asset, }]; - inst.bid_for_users(project_id, bids.clone()).expect("Candle Bidding should not fail"); + inst.bid_for_users(project_id, bids.clone()); bids_made.push(bids[0].clone()); bidding_account += 1; @@ -1413,7 +1403,7 @@ mod auction_round_success { let bidders_funding_assets = MockInstantiator::calculate_auction_funding_asset_spent(&bids, None); inst.mint_statemint_asset_to(bidders_funding_assets); - inst.bid_for_users(project_id, bids).unwrap(); + inst.bid_for_users(project_id, bids); inst.start_community_funding(project_id).unwrap(); let final_price = inst.get_project_details(project_id).weighted_average_price.unwrap(); @@ -1837,53 +1827,21 @@ mod auction_round_failure { } #[test] - fn bids_overflow() { + fn bid_with_asset_not_accepted() { let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); let project_id = inst.create_auctioning_project(default_project(0, ISSUER), ISSUER, default_evaluations()); - const DAVE: AccountId = 42; - let bids: Vec> = vec![ - BidParams::new(DAVE, 10_000 * USDT_UNIT, 2_u128.into(), 1u8, AcceptedFundingAsset::USDT), // 20k - BidParams::new(DAVE, 12_000 * USDT_UNIT, 8_u128.into(), 1u8, AcceptedFundingAsset::USDT), // 96k - BidParams::new(DAVE, 15_000 * USDT_UNIT, 5_u128.into(), 1u8, AcceptedFundingAsset::USDT), // 75k - // Bid with lowest PLMC bonded gets dropped - BidParams::new(DAVE, 1_000 * USDT_UNIT, 7_u128.into(), 1u8, AcceptedFundingAsset::USDT), // 7k - BidParams::new(DAVE, 20_000 * USDT_UNIT, 5_u128.into(), 1u8, AcceptedFundingAsset::USDT), // 100k - ]; - - let mut plmc_fundings = MockInstantiator::calculate_auction_plmc_spent(&bids, None); - // Existential deposit on DAVE - plmc_fundings.push(UserToPLMCBalance::new(DAVE, MockInstantiator::get_ed())); - - let statemint_asset_fundings = MockInstantiator::calculate_auction_funding_asset_spent(&bids, None); - - // Fund enough for all PLMC bonds for the bids (multiplier of 1) - inst.mint_plmc_to(plmc_fundings); - - // Fund enough for all bids - inst.mint_statemint_asset_to(statemint_asset_fundings); - - inst.bid_for_users(project_id, bids).expect("Bids should pass"); + let bids = + vec![BidParams::::new(BIDDER_1, 10_000, 2_u128.into(), 1u8, AcceptedFundingAsset::USDC)]; - inst.execute(|| { - let mut stored_bids = Bids::::iter_prefix_values((project_id, DAVE)).collect::>(); - assert_eq!(stored_bids.len(), 4); - stored_bids.sort(); - assert_eq!(stored_bids[0].original_ct_usd_price.to_float(), 1.0); - assert_eq!(stored_bids[1].original_ct_usd_price.to_float(), 1.0); - assert_eq!(stored_bids[2].original_ct_usd_price.to_float(), 1.1); - assert_eq!(stored_bids[3].original_ct_usd_price.to_float(), 1.2); + let outcome = inst.execute(|| { + Pallet::::do_bid( + &bids[0].bidder, + project_id, + bids[0].amount, + bids[0].multiplier, + bids[0].asset, + ) }); - } - - #[test] - fn bid_with_asset_not_accepted() { - let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); - let project_id = inst.create_auctioning_project(default_project(0, ISSUER), ISSUER, default_evaluations()); - let bids = vec![ - BidParams::new(BIDDER_1, 10_000, 2_u128.into(), 1u8, AcceptedFundingAsset::USDC), - BidParams::new(BIDDER_2, 13_000, 3_u128.into(), 2u8, AcceptedFundingAsset::USDC), - ]; - let outcome = inst.bid_for_users(project_id, bids); frame_support::assert_err!(outcome, Error::::FundingAssetNotAccepted); } @@ -1941,7 +1899,7 @@ mod auction_round_failure { inst.mint_plmc_to(plmc_ct_account_deposits.clone()); inst.mint_statemint_asset_to(usdt_fundings.clone()); - inst.bid_for_users(project_id, vec![glutton_bid_1, rejected_bid, glutton_bid_2]).expect("Bids should pass"); + inst.bid_for_users(project_id, vec![glutton_bid_1, rejected_bid, glutton_bid_2]); inst.do_free_plmc_assertions(vec![ UserToPLMCBalance::new(BIDDER_1, MockInstantiator::get_ed()), @@ -2029,7 +1987,7 @@ mod auction_round_failure { inst.mint_plmc_to(plmc_ct_account_deposits.clone()); inst.mint_statemint_asset_to(usdt_fundings.clone()); - inst.bid_for_users(project_id, vec![bid_in]).expect("Bids should pass"); + inst.bid_for_users(project_id, vec![bid_in]); inst.advance_time( ::EnglishAuctionDuration::get() + ::CandleAuctionDuration::get() - @@ -2037,7 +1995,7 @@ mod auction_round_failure { ) .unwrap(); - inst.bid_for_users(project_id, vec![bid_out]).expect("Bids should pass"); + inst.bid_for_users(project_id, vec![bid_out]); inst.do_free_plmc_assertions(vec![ UserToPLMCBalance::new(BIDDER_1, MockInstantiator::get_ed()), @@ -5822,9 +5780,9 @@ mod misc_features { let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); let now = inst.current_block(); inst.execute(|| { - PolimecFunding::add_to_update_store(now + 10u64, (&42u32, CommunityFundingStart)); - PolimecFunding::add_to_update_store(now + 20u64, (&69u32, RemainderFundingStart)); - PolimecFunding::add_to_update_store(now + 5u64, (&404u32, RemainderFundingStart)); + assert_ok!(PolimecFunding::add_to_update_store(now + 10u64, (&42u32, CommunityFundingStart))); + assert_ok!(PolimecFunding::add_to_update_store(now + 20u64, (&69u32, RemainderFundingStart))); + assert_ok!(PolimecFunding::add_to_update_store(now + 5u64, (&404u32, RemainderFundingStart))); }); inst.advance_time(2u64).unwrap(); inst.execute(|| { diff --git a/pallets/funding/src/weights.rs b/pallets/funding/src/weights.rs index ffca8c7e9..c7fa8edc2 100644 --- a/pallets/funding/src/weights.rs +++ b/pallets/funding/src/weights.rs @@ -17,13 +17,13 @@ // If you feel like getting in touch with us, you can do so at info@polimec.org -//! Autogenerated weights for pallet_funding +//! Autogenerated weights for `pallet_funding` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-09-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Juans-MacBook-Pro.fritz.box`, CPU: `` -//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("polimec-rococo-local")`, DB CACHE: `1024` +//! HOSTNAME: `Juans-MBP.home`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("polimec-rococo-local")`, DB CACHE: `1024` // Executed Command: // target/release/polimec-parachain-node @@ -35,7 +35,6 @@ // --pallet=pallet_funding // --extrinsic // * -// --execution=wasm // --heap-pages=4096 // --output=pallets/funding/src/weights-test.rs // --template=./.maintain/frame-weight-template.hbs @@ -48,389 +47,1559 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_funding. +/// Weight functions needed for `pallet_funding`. pub trait WeightInfo { fn create() -> Weight; fn edit_metadata() -> Weight; - fn start_evaluation() -> Weight; - fn start_auction() -> Weight; - fn bond_evaluation() -> Weight; - fn bid() -> Weight; - fn contribute() -> Weight; + fn start_evaluation(x: u32, ) -> Weight; + fn start_auction_manually(x: u32, y: u32, ) -> Weight; + fn start_auction_automatically(x: u32, ) -> Weight; + fn first_evaluation() -> Weight; + fn second_to_limit_evaluation(x: u32, ) -> Weight; + fn evaluation_over_limit() -> Weight; + fn bid_with_ct_deposit(y: u32, ) -> Weight; + fn bid_no_ct_deposit(x: u32, y: u32, ) -> Weight; + fn first_contribution_with_ct_deposit() -> Weight; + fn first_contribution_no_ct_deposit() -> Weight; + fn first_contribution_ends_round_with_ct_deposit(y: u32, z: u32, ) -> Weight; + fn first_contribution_ends_round_no_ct_deposit(y: u32, z: u32, ) -> Weight; + fn second_to_limit_contribution(x: u32, ) -> Weight; + fn second_to_limit_contribution_ends_round(x: u32, y: u32, z: u32, ) -> Weight; + fn contribution_over_limit() -> Weight; fn evaluation_unbond_for() -> Weight; + fn evaluation_reward_payout_for_with_ct_account_creation() -> Weight; + fn evaluation_reward_payout_for_no_ct_account_creation() -> Weight; fn evaluation_slash_for() -> Weight; - fn evaluation_reward_payout_for() -> Weight; - fn bid_ct_mint_for() -> Weight; - fn contribution_ct_mint_for() -> Weight; + fn bid_ct_mint_for_with_ct_account_creation() -> Weight; + fn bid_ct_mint_for_no_ct_account_creation() -> Weight; + fn contribution_ct_mint_for_with_ct_account_creation() -> Weight; + fn contribution_ct_mint_for_no_ct_account_creation() -> Weight; fn start_bid_vesting_schedule_for() -> Weight; fn start_contribution_vesting_schedule_for() -> Weight; fn payout_bid_funds_for() -> Weight; fn payout_contribution_funds_for() -> Weight; - fn decide_project_outcome() -> Weight; + fn decide_project_outcome(x: u32, y: u32, ) -> Weight; fn release_bid_funds_for() -> Weight; - fn bid_unbond_for() -> Weight; fn release_contribution_funds_for() -> Weight; + fn bid_unbond_for() -> Weight; fn contribution_unbond_for() -> Weight; } -/// Weights for pallet_funding using the Substrate node and recommended hardware. +/// Weights for `pallet_funding` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: PolimecFunding NextProjectId (r:1 w:1) - /// Proof Skipped: PolimecFunding NextProjectId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolimecFunding Images (r:1 w:1) - /// Proof Skipped: PolimecFunding Images (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsMetadata (r:0 w:1) - /// Proof Skipped: PolimecFunding ProjectsMetadata (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:0 w:1) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolimecFunding::NextProjectId` (r:1 w:1) + /// Proof: `PolimecFunding::NextProjectId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Images` (r:1 w:1) + /// Proof: `PolimecFunding::Images` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Buckets` (r:0 w:1) + /// Proof: `PolimecFunding::Buckets` (`max_values`: None, `max_size`: Some(100), added: 2575, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:0 w:1) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:0 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: - // Measured: `6` - // Estimated: `3471` - // Minimum execution time: 16_000_000 picoseconds. - Weight::from_parts(17_000_000, 3471) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + // Measured: `161` + // Estimated: `3593` + // Minimum execution time: 60_000_000 picoseconds. + Weight::from_parts(62_000_000, 3593) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: PolimecFunding ProjectsMetadata (r:1 w:1) - /// Proof Skipped: PolimecFunding ProjectsMetadata (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Images (r:1 w:0) - /// Proof Skipped: PolimecFunding Images (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Images` (r:1 w:0) + /// Proof: `PolimecFunding::Images` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) fn edit_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `536` - // Estimated: `4001` + // Measured: `609` + // Estimated: `3814` // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(18_000_000, 4001) + Weight::from_parts(19_000_000, 3814) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: PolimecFunding ProjectsMetadata (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsMetadata (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:1 w:1) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsToUpdate (r:1 w:1) - /// Proof Skipped: PolimecFunding ProjectsToUpdate (max_values: None, max_size: None, mode: Measured) - fn start_evaluation() -> Weight { - // Proof Size summary in bytes: - // Measured: `467` - // Estimated: `3932` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(20_000_000, 3932) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:100 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + fn start_evaluation(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `563 + x * (529 ±0)` + // Estimated: `4087 + x * (3097 ±0)` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(19_253_978, 4087) + // Standard Error: 15_066 + .saturating_add(Weight::from_parts(2_633_080, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(Weight::from_parts(0, 3097).saturating_mul(x.into())) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:1) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsToUpdate (r:3 w:2) - /// Proof Skipped: PolimecFunding ProjectsToUpdate (max_values: None, max_size: None, mode: Measured) - fn start_auction() -> Weight { + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:4558 w:2) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + /// The range of component `y` is `[1, 10000]`. + fn start_auction_manually(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `380` - // Estimated: `8795` - // Minimum execution time: 33_000_000 picoseconds. - Weight::from_parts(37_000_000, 8795) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `0 + x * (1281 ±0) + y * (21 ±0)` + // Estimated: `268395 + x * (9966 ±8_383) + y * (1212 ±82)` + // Minimum execution time: 397_000_000 picoseconds. + Weight::from_parts(420_000_000, 268395) + // Standard Error: 4_704_303 + .saturating_add(Weight::from_parts(12_350_427, 0).saturating_mul(x.into())) + // Standard Error: 46_630 + .saturating_add(Weight::from_parts(1_402_043, 0).saturating_mul(y.into())) + .saturating_add(T::DbWeight::get().reads(87_u64)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(x.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(Weight::from_parts(0, 9966).saturating_mul(x.into())) + .saturating_add(Weight::from_parts(0, 1212).saturating_mul(y.into())) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:1) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding NextEvaluationId (r:1 w:1) - /// Proof Skipped: PolimecFunding NextEvaluationId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolimecFunding Evaluations (r:1 w:1) - /// Proof Skipped: PolimecFunding Evaluations (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) - fn bond_evaluation() -> Weight { - // Proof Size summary in bytes: - // Measured: `428` - // Estimated: `4564` - // Minimum execution time: 53_000_000 picoseconds. - Weight::from_parts(58_000_000, 4564) - .saturating_add(T::DbWeight::get().reads(4_u64)) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:100 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + fn start_auction_automatically(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `411 + x * (529 ±0)` + // Estimated: `4087 + x * (3097 ±0)` + // Minimum execution time: 20_000_000 picoseconds. + Weight::from_parts(20_242_112, 4087) + // Standard Error: 18_140 + .saturating_add(Weight::from_parts(2_666_357, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(Weight::from_parts(0, 3097).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextEvaluationId` (r:1 w:1) + /// Proof: `PolimecFunding::NextEvaluationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:1 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn first_evaluation() -> Weight { + // Proof Size summary in bytes: + // Measured: `676` + // Estimated: `4614` + // Minimum execution time: 92_000_000 picoseconds. + Weight::from_parts(94_000_000, 4614) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: PolimecFunding ProjectsMetadata (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsMetadata (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding NextBidId (r:1 w:1) - /// Proof Skipped: PolimecFunding NextBidId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolimecFunding Bids (r:1 w:1) - /// Proof Skipped: PolimecFunding Bids (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Evaluations (r:1 w:0) - /// Proof Skipped: PolimecFunding Evaluations (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) - /// Storage: StatemintAssets Asset (r:1 w:1) - /// Proof: StatemintAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: StatemintAssets Account (r:2 w:2) - /// Proof: StatemintAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - fn bid() -> Weight { - // Proof Size summary in bytes: - // Measured: `1555` + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextEvaluationId` (r:1 w:1) + /// Proof: `PolimecFunding::NextEvaluationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:256 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:1 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 255]`. + fn second_to_limit_evaluation(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `893 + x * (137 ±0)` + // Estimated: `4614 + x * (2820 ±0)` + // Minimum execution time: 71_000_000 picoseconds. + Weight::from_parts(58_910_334, 4614) + // Standard Error: 11_575 + .saturating_add(Weight::from_parts(3_780_894, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 2820).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextEvaluationId` (r:1 w:1) + /// Proof: `PolimecFunding::NextEvaluationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:257 w:2) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:1 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn evaluation_over_limit() -> Weight { + // Proof Size summary in bytes: + // Measured: `36120` + // Estimated: `725730` + // Minimum execution time: 1_017_000_000 picoseconds. + Weight::from_parts(1_051_000_000, 725730) + .saturating_add(T::DbWeight::get().reads(261_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:10) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Buckets` (r:1 w:1) + /// Proof: `PolimecFunding::Buckets` (`max_values`: None, `max_size`: Some(100), added: 2575, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextBidId` (r:1 w:1) + /// Proof: `PolimecFunding::NextBidId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `y` is `[0, 10]`. + fn bid_with_ct_deposit(y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2140` // Estimated: `6208` - // Minimum execution time: 130_000_000 picoseconds. - Weight::from_parts(140_000_000, 6208) - .saturating_add(T::DbWeight::get().reads(10_u64)) + // Minimum execution time: 143_000_000 picoseconds. + Weight::from_parts(106_855_955, 6208) + // Standard Error: 319_819 + .saturating_add(Weight::from_parts(70_108_416, 0).saturating_mul(y.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(y.into()))) } - /// Storage: PolimecFunding ProjectsMetadata (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsMetadata (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:1 w:1) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding NextContributionId (r:1 w:1) - /// Proof Skipped: PolimecFunding NextContributionId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolimecFunding Contributions (r:1 w:1) - /// Proof Skipped: PolimecFunding Contributions (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Evaluations (r:1 w:0) - /// Proof Skipped: PolimecFunding Evaluations (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) - /// Storage: StatemintAssets Asset (r:1 w:1) - /// Proof: StatemintAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: StatemintAssets Account (r:2 w:2) - /// Proof: StatemintAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - fn contribute() -> Weight { - // Proof Size summary in bytes: - // Measured: `1682` + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:256 w:10) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Buckets` (r:1 w:1) + /// Proof: `PolimecFunding::Buckets` (`max_values`: None, `max_size`: Some(100), added: 2575, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextBidId` (r:1 w:1) + /// Proof: `PolimecFunding::NextBidId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// The range of component `x` is `[0, 255]`. + /// The range of component `y` is `[0, 10]`. + fn bid_no_ct_deposit(x: u32, y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2227 + x * (164 ±0)` + // Estimated: `6208 + x * (2893 ±0)` + // Minimum execution time: 760_000_000 picoseconds. + Weight::from_parts(69_652_890, 6208) + // Standard Error: 11_684 + .saturating_add(Weight::from_parts(4_020_612, 0).saturating_mul(x.into())) + // Standard Error: 283_589 + .saturating_add(Weight::from_parts(72_460_034, 0).saturating_mul(y.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(y.into()))) + .saturating_add(Weight::from_parts(0, 2893).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn first_contribution_with_ct_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `1996` // Estimated: `6208` - // Minimum execution time: 122_000_000 picoseconds. - Weight::from_parts(131_000_000, 6208) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Minimum execution time: 147_000_000 picoseconds. + Weight::from_parts(155_000_000, 6208) + .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn first_contribution_no_ct_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `2073` + // Estimated: `6208` + // Minimum execution time: 119_000_000 picoseconds. + Weight::from_parts(126_000_000, 6208) + .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:9832 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `y` is `[1, 99]`. + /// The range of component `z` is `[1, 10000]`. + fn first_contribution_ends_round_with_ct_deposit(y: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + y * (443 ±0) + z * (37 ±0)` + // Estimated: `78415 + y * (14240 ±4_378) + z * (1371 ±43)` + // Minimum execution time: 264_000_000 picoseconds. + Weight::from_parts(268_000_000, 78415) + // Standard Error: 5_143_014 + .saturating_add(Weight::from_parts(16_318_492, 0).saturating_mul(y.into())) + // Standard Error: 50_979 + .saturating_add(Weight::from_parts(1_601_983, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(36_u64)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(y.into()))) + .saturating_add(T::DbWeight::get().writes(8_u64)) + .saturating_add(Weight::from_parts(0, 14240).saturating_mul(y.into())) + .saturating_add(Weight::from_parts(0, 1371).saturating_mul(z.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:9832 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `y` is `[1, 99]`. + /// The range of component `z` is `[1, 10000]`. + fn first_contribution_ends_round_no_ct_deposit(y: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + y * (443 ±0) + z * (37 ±0)` + // Estimated: `78415 + y * (14240 ±4_378) + z * (1371 ±43)` + // Minimum execution time: 226_000_000 picoseconds. + Weight::from_parts(239_000_000, 78415) + // Standard Error: 5_135_841 + .saturating_add(Weight::from_parts(15_722_813, 0).saturating_mul(y.into())) + // Standard Error: 50_908 + .saturating_add(Weight::from_parts(1_606_667, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(36_u64)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(y.into()))) + .saturating_add(T::DbWeight::get().writes(8_u64)) + .saturating_add(Weight::from_parts(0, 14240).saturating_mul(y.into())) + .saturating_add(Weight::from_parts(0, 1371).saturating_mul(z.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:256 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 255]`. + fn second_to_limit_contribution(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2213 + x * (137 ±0)` + // Estimated: `6208 + x * (2839 ±0)` + // Minimum execution time: 124_000_000 picoseconds. + Weight::from_parts(117_868_102, 6208) + // Standard Error: 10_026 + .saturating_add(Weight::from_parts(3_746_658, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(Weight::from_parts(0, 2839).saturating_mul(x.into())) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Evaluations (r:1 w:1) - /// Proof Skipped: PolimecFunding Evaluations (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:256 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:9832 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 255]`. + /// The range of component `y` is `[1, 99]`. + /// The range of component `z` is `[1, 10000]`. + fn second_to_limit_contribution_ends_round(x: u32, y: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `75282 + x * (137 ±0) + y * (723 ±0) + z * (39 ±0)` + // Estimated: `17232 + x * (2839 ±0) + y * (115061 ±7_565) + z * (2358 ±74)` + // Minimum execution time: 1_097_000_000 picoseconds. + Weight::from_parts(554_228_738, 17232) + // Standard Error: 8_861_727 + .saturating_add(Weight::from_parts(133_771_367, 0).saturating_mul(y.into())) + // Standard Error: 86_849 + .saturating_add(Weight::from_parts(2_763_795, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(16_u64)) + .saturating_add(T::DbWeight::get().reads((37_u64).saturating_mul(y.into()))) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(z.into()))) + .saturating_add(T::DbWeight::get().writes(8_u64)) + .saturating_add(Weight::from_parts(0, 2839).saturating_mul(x.into())) + .saturating_add(Weight::from_parts(0, 115061).saturating_mul(y.into())) + .saturating_add(Weight::from_parts(0, 2358).saturating_mul(z.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:257 w:2) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + fn contribution_over_limit() -> Weight { + // Proof Size summary in bytes: + // Measured: `37440` + // Estimated: `730613` + // Minimum execution time: 1_103_000_000 picoseconds. + Weight::from_parts(1_165_000_000, 730613) + .saturating_add(T::DbWeight::get().reads(267_u64)) + .saturating_add(T::DbWeight::get().writes(8_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) fn evaluation_unbond_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1303` - // Estimated: `4768` - // Minimum execution time: 60_000_000 picoseconds. - Weight::from_parts(65_000_000, 4768) + // Measured: `1411` + // Estimated: `4614` + // Minimum execution time: 55_000_000 picoseconds. + Weight::from_parts(60_000_000, 4614) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Evaluations (r:2 w:1) - /// Proof Skipped: PolimecFunding Evaluations (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - fn evaluation_slash_for() -> Weight { + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn evaluation_reward_payout_for_with_ct_account_creation() -> Weight { // Proof Size summary in bytes: - // Measured: `1338` - // Estimated: `7278` - // Minimum execution time: 84_000_000 picoseconds. - Weight::from_parts(94_000_000, 7278) + // Measured: `1515` + // Estimated: `4614` + // Minimum execution time: 92_000_000 picoseconds. + Weight::from_parts(102_000_000, 4614) .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn evaluation_reward_payout_for_no_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1219` + // Estimated: `3814` + // Minimum execution time: 48_000_000 picoseconds. + Weight::from_parts(49_000_000, 3814) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Evaluations (r:1 w:1) - /// Proof Skipped: PolimecFunding Evaluations (max_values: None, max_size: None, mode: Measured) - /// Storage: LocalAssets Asset (r:1 w:1) - /// Proof: LocalAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: LocalAssets Account (r:1 w:1) - /// Proof: LocalAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - fn evaluation_reward_payout_for() -> Weight { - // Proof Size summary in bytes: - // Measured: `1245` - // Estimated: `4710` - // Minimum execution time: 63_000_000 picoseconds. - Weight::from_parts(71_000_000, 4710) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn evaluation_slash_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1419` + // Estimated: `4614` + // Minimum execution time: 68_000_000 picoseconds. + Weight::from_parts(71_000_000, 4614) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: PolimecFunding Bids (r:1 w:1) - /// Proof Skipped: PolimecFunding Bids (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: LocalAssets Asset (r:1 w:1) - /// Proof: LocalAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: LocalAssets Account (r:1 w:1) - /// Proof: LocalAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - fn bid_ct_mint_for() -> Weight { - // Proof Size summary in bytes: - // Measured: `1215` - // Estimated: `4680` - // Minimum execution time: 65_000_000 picoseconds. - Weight::from_parts(71_000_000, 4680) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn bid_ct_mint_for_with_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1629` + // Estimated: `4614` + // Minimum execution time: 96_000_000 picoseconds. + Weight::from_parts(99_000_000, 4614) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn bid_ct_mint_for_no_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1180` + // Estimated: `3883` + // Minimum execution time: 44_000_000 picoseconds. + Weight::from_parts(47_000_000, 3883) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: PolimecFunding Contributions (r:1 w:1) - /// Proof Skipped: PolimecFunding Contributions (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: LocalAssets Asset (r:1 w:1) - /// Proof: LocalAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: LocalAssets Account (r:1 w:1) - /// Proof: LocalAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - fn contribution_ct_mint_for() -> Weight { - // Proof Size summary in bytes: - // Measured: `1205` - // Estimated: `4670` - // Minimum execution time: 64_000_000 picoseconds. - Weight::from_parts(69_000_000, 4670) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn contribution_ct_mint_for_with_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1545` + // Estimated: `4614` + // Minimum execution time: 91_000_000 picoseconds. + Weight::from_parts(98_000_000, 4614) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn contribution_ct_mint_for_no_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1217` + // Estimated: `3829` + // Minimum execution time: 46_000_000 picoseconds. + Weight::from_parts(50_000_000, 3829) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Bids (r:1 w:1) - /// Proof Skipped: PolimecFunding Bids (max_values: None, max_size: None, mode: Measured) - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof Skipped: Vesting Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `LinearRelease::Vesting` (r:1 w:1) + /// Proof: `LinearRelease::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) fn start_bid_vesting_schedule_for() -> Weight { // Proof Size summary in bytes: - // Measured: `870` - // Estimated: `4335` - // Minimum execution time: 44_000_000 picoseconds. - Weight::from_parts(47_000_000, 4335) + // Measured: `818` + // Estimated: `4283` + // Minimum execution time: 29_000_000 picoseconds. + Weight::from_parts(31_000_000, 4283) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Contributions (r:1 w:1) - /// Proof Skipped: PolimecFunding Contributions (max_values: None, max_size: None, mode: Measured) - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof Skipped: Vesting Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `LinearRelease::Vesting` (r:1 w:1) + /// Proof: `LinearRelease::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) fn start_contribution_vesting_schedule_for() -> Weight { // Proof Size summary in bytes: - // Measured: `898` - // Estimated: `4363` - // Minimum execution time: 46_000_000 picoseconds. - Weight::from_parts(50_000_000, 4363) + // Measured: `847` + // Estimated: `4312` + // Minimum execution time: 30_000_000 picoseconds. + Weight::from_parts(32_000_000, 4312) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Bids (r:1 w:1) - /// Proof Skipped: PolimecFunding Bids (max_values: None, max_size: None, mode: Measured) - /// Storage: StatemintAssets Asset (r:1 w:1) - /// Proof: StatemintAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: StatemintAssets Account (r:2 w:2) - /// Proof: StatemintAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout_bid_funds_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1392` + // Measured: `1372` // Estimated: `6208` - // Minimum execution time: 81_000_000 picoseconds. - Weight::from_parts(89_000_000, 6208) + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(69_000_000, 6208) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Contributions (r:1 w:1) - /// Proof Skipped: PolimecFunding Contributions (max_values: None, max_size: None, mode: Measured) - /// Storage: StatemintAssets Asset (r:1 w:1) - /// Proof: StatemintAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: StatemintAssets Account (r:2 w:2) - /// Proof: StatemintAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout_contribution_funds_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1420` + // Measured: `1401` // Estimated: `6208` - // Minimum execution time: 81_000_000 picoseconds. - Weight::from_parts(89_000_000, 6208) + // Minimum execution time: 69_000_000 picoseconds. + Weight::from_parts(77_000_000, 6208) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding ProjectsToUpdate (r:3 w:2) - /// Proof Skipped: PolimecFunding ProjectsToUpdate (max_values: None, max_size: None, mode: Measured) - fn decide_project_outcome() -> Weight { + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:2980 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + /// The range of component `y` is `[1, 10000]`. + fn decide_project_outcome(x: u32, y: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `515` - // Estimated: `8930` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(31_000_000, 8930) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Measured: `10254 + x * (419 ±0) + y * (20 ±0)` + // Estimated: `35057 + x * (4876 ±4_177) + y * (1437 ±41)` + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(68_000_000, 35057) + // Standard Error: 4_809_624 + .saturating_add(Weight::from_parts(5_610_465, 0).saturating_mul(x.into())) + // Standard Error: 47_674 + .saturating_add(Weight::from_parts(1_647_468, 0).saturating_mul(y.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(Weight::from_parts(0, 4876).saturating_mul(x.into())) + .saturating_add(Weight::from_parts(0, 1437).saturating_mul(y.into())) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Bids (r:1 w:1) - /// Proof Skipped: PolimecFunding Bids (max_values: None, max_size: None, mode: Measured) - /// Storage: StatemintAssets Asset (r:1 w:1) - /// Proof: StatemintAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: StatemintAssets Account (r:2 w:2) - /// Proof: StatemintAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn release_bid_funds_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1461` + // Measured: `1481` // Estimated: `6208` - // Minimum execution time: 84_000_000 picoseconds. - Weight::from_parts(91_000_000, 6208) + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(71_000_000, 6208) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Bids (r:1 w:1) - /// Proof Skipped: PolimecFunding Bids (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn release_contribution_funds_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1474` + // Estimated: `6208` + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(70_000_000, 6208) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) fn bid_unbond_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1406` - // Estimated: `4871` - // Minimum execution time: 61_000_000 picoseconds. - Weight::from_parts(68_000_000, 4871) + // Measured: `1486` + // Estimated: `4614` + // Minimum execution time: 52_000_000 picoseconds. + Weight::from_parts(57_000_000, 4614) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn contribution_unbond_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1441` + // Estimated: `4614` + // Minimum execution time: 52_000_000 picoseconds. + Weight::from_parts(57_000_000, 4614) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Contributions (r:1 w:1) - /// Proof Skipped: PolimecFunding Contributions (max_values: None, max_size: None, mode: Measured) - /// Storage: StatemintAssets Asset (r:1 w:1) - /// Proof: StatemintAssets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: StatemintAssets Account (r:2 w:2) - /// Proof: StatemintAssets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `PolimecFunding::NextProjectId` (r:1 w:1) + /// Proof: `PolimecFunding::NextProjectId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Images` (r:1 w:1) + /// Proof: `PolimecFunding::Images` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Buckets` (r:0 w:1) + /// Proof: `PolimecFunding::Buckets` (`max_values`: None, `max_size`: Some(100), added: 2575, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:0 w:1) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:0 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `161` + // Estimated: `3593` + // Minimum execution time: 60_000_000 picoseconds. + Weight::from_parts(62_000_000, 3593) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Images` (r:1 w:0) + /// Proof: `PolimecFunding::Images` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + fn edit_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `609` + // Estimated: `3814` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 3814) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:100 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + fn start_evaluation(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `563 + x * (529 ±0)` + // Estimated: `4087 + x * (3097 ±0)` + // Minimum execution time: 22_000_000 picoseconds. + Weight::from_parts(19_253_978, 4087) + // Standard Error: 15_066 + .saturating_add(Weight::from_parts(2_633_080, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(Weight::from_parts(0, 3097).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:4558 w:2) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + /// The range of component `y` is `[1, 10000]`. + fn start_auction_manually(x: u32, y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + x * (1281 ±0) + y * (21 ±0)` + // Estimated: `268395 + x * (9966 ±8_383) + y * (1212 ±82)` + // Minimum execution time: 397_000_000 picoseconds. + Weight::from_parts(420_000_000, 268395) + // Standard Error: 4_704_303 + .saturating_add(Weight::from_parts(12_350_427, 0).saturating_mul(x.into())) + // Standard Error: 46_630 + .saturating_add(Weight::from_parts(1_402_043, 0).saturating_mul(y.into())) + .saturating_add(RocksDbWeight::get().reads(87_u64)) + .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(Weight::from_parts(0, 9966).saturating_mul(x.into())) + .saturating_add(Weight::from_parts(0, 1212).saturating_mul(y.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:100 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + fn start_auction_automatically(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `411 + x * (529 ±0)` + // Estimated: `4087 + x * (3097 ±0)` + // Minimum execution time: 20_000_000 picoseconds. + Weight::from_parts(20_242_112, 4087) + // Standard Error: 18_140 + .saturating_add(Weight::from_parts(2_666_357, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(Weight::from_parts(0, 3097).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextEvaluationId` (r:1 w:1) + /// Proof: `PolimecFunding::NextEvaluationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:1 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn first_evaluation() -> Weight { + // Proof Size summary in bytes: + // Measured: `676` + // Estimated: `4614` + // Minimum execution time: 92_000_000 picoseconds. + Weight::from_parts(94_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextEvaluationId` (r:1 w:1) + /// Proof: `PolimecFunding::NextEvaluationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:256 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:1 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 255]`. + fn second_to_limit_evaluation(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `893 + x * (137 ±0)` + // Estimated: `4614 + x * (2820 ±0)` + // Minimum execution time: 71_000_000 picoseconds. + Weight::from_parts(58_910_334, 4614) + // Standard Error: 11_575 + .saturating_add(Weight::from_parts(3_780_894, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 2820).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextEvaluationId` (r:1 w:1) + /// Proof: `PolimecFunding::NextEvaluationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:257 w:2) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:1 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn evaluation_over_limit() -> Weight { + // Proof Size summary in bytes: + // Measured: `36120` + // Estimated: `725730` + // Minimum execution time: 1_017_000_000 picoseconds. + Weight::from_parts(1_051_000_000, 725730) + .saturating_add(RocksDbWeight::get().reads(261_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:10) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Buckets` (r:1 w:1) + /// Proof: `PolimecFunding::Buckets` (`max_values`: None, `max_size`: Some(100), added: 2575, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextBidId` (r:1 w:1) + /// Proof: `PolimecFunding::NextBidId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `y` is `[0, 10]`. + fn bid_with_ct_deposit(y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2140` + // Estimated: `6208` + // Minimum execution time: 143_000_000 picoseconds. + Weight::from_parts(106_855_955, 6208) + // Standard Error: 319_819 + .saturating_add(Weight::from_parts(70_108_416, 0).saturating_mul(y.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(y.into()))) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:256 w:10) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Buckets` (r:1 w:1) + /// Proof: `PolimecFunding::Buckets` (`max_values`: None, `max_size`: Some(100), added: 2575, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextBidId` (r:1 w:1) + /// Proof: `PolimecFunding::NextBidId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// The range of component `x` is `[0, 255]`. + /// The range of component `y` is `[0, 10]`. + fn bid_no_ct_deposit(x: u32, y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2227 + x * (164 ±0)` + // Estimated: `6208 + x * (2893 ±0)` + // Minimum execution time: 760_000_000 picoseconds. + Weight::from_parts(69_652_890, 6208) + // Standard Error: 11_684 + .saturating_add(Weight::from_parts(4_020_612, 0).saturating_mul(x.into())) + // Standard Error: 283_589 + .saturating_add(Weight::from_parts(72_460_034, 0).saturating_mul(y.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(y.into()))) + .saturating_add(Weight::from_parts(0, 2893).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn first_contribution_with_ct_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `1996` + // Estimated: `6208` + // Minimum execution time: 147_000_000 picoseconds. + Weight::from_parts(155_000_000, 6208) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn first_contribution_no_ct_deposit() -> Weight { + // Proof Size summary in bytes: + // Measured: `2073` + // Estimated: `6208` + // Minimum execution time: 119_000_000 picoseconds. + Weight::from_parts(126_000_000, 6208) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:9832 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `y` is `[1, 99]`. + /// The range of component `z` is `[1, 10000]`. + fn first_contribution_ends_round_with_ct_deposit(y: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + y * (443 ±0) + z * (37 ±0)` + // Estimated: `78415 + y * (14240 ±4_378) + z * (1371 ±43)` + // Minimum execution time: 264_000_000 picoseconds. + Weight::from_parts(268_000_000, 78415) + // Standard Error: 5_143_014 + .saturating_add(Weight::from_parts(16_318_492, 0).saturating_mul(y.into())) + // Standard Error: 50_979 + .saturating_add(Weight::from_parts(1_601_983, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(36_u64)) + .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(y.into()))) + .saturating_add(RocksDbWeight::get().writes(8_u64)) + .saturating_add(Weight::from_parts(0, 14240).saturating_mul(y.into())) + .saturating_add(Weight::from_parts(0, 1371).saturating_mul(z.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:9832 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `y` is `[1, 99]`. + /// The range of component `z` is `[1, 10000]`. + fn first_contribution_ends_round_no_ct_deposit(y: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + y * (443 ±0) + z * (37 ±0)` + // Estimated: `78415 + y * (14240 ±4_378) + z * (1371 ±43)` + // Minimum execution time: 226_000_000 picoseconds. + Weight::from_parts(239_000_000, 78415) + // Standard Error: 5_135_841 + .saturating_add(Weight::from_parts(15_722_813, 0).saturating_mul(y.into())) + // Standard Error: 50_908 + .saturating_add(Weight::from_parts(1_606_667, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(36_u64)) + .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(y.into()))) + .saturating_add(RocksDbWeight::get().writes(8_u64)) + .saturating_add(Weight::from_parts(0, 14240).saturating_mul(y.into())) + .saturating_add(Weight::from_parts(0, 1371).saturating_mul(z.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:256 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 255]`. + fn second_to_limit_contribution(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `2213 + x * (137 ±0)` + // Estimated: `6208 + x * (2839 ±0)` + // Minimum execution time: 124_000_000 picoseconds. + Weight::from_parts(117_868_102, 6208) + // Standard Error: 10_026 + .saturating_add(Weight::from_parts(3_746_658, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(Weight::from_parts(0, 2839).saturating_mul(x.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:256 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:9832 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 255]`. + /// The range of component `y` is `[1, 99]`. + /// The range of component `z` is `[1, 10000]`. + fn second_to_limit_contribution_ends_round(x: u32, y: u32, z: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `75282 + x * (137 ±0) + y * (723 ±0) + z * (39 ±0)` + // Estimated: `17232 + x * (2839 ±0) + y * (115061 ±7_565) + z * (2358 ±74)` + // Minimum execution time: 1_097_000_000 picoseconds. + Weight::from_parts(554_228_738, 17232) + // Standard Error: 8_861_727 + .saturating_add(Weight::from_parts(133_771_367, 0).saturating_mul(y.into())) + // Standard Error: 86_849 + .saturating_add(Weight::from_parts(2_763_795, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(16_u64)) + .saturating_add(RocksDbWeight::get().reads((37_u64).saturating_mul(y.into()))) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(z.into()))) + .saturating_add(RocksDbWeight::get().writes(8_u64)) + .saturating_add(Weight::from_parts(0, 2839).saturating_mul(x.into())) + .saturating_add(Weight::from_parts(0, 115061).saturating_mul(y.into())) + .saturating_add(Weight::from_parts(0, 2358).saturating_mul(z.into())) + } + /// Storage: `PolimecFunding::ProjectsMetadata` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsMetadata` (`max_values`: None, `max_size`: Some(334), added: 2809, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:1) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:257 w:2) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Oracle::Values` (r:2 w:0) + /// Proof: `Oracle::Values` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::NextContributionId` (r:1 w:1) + /// Proof: `PolimecFunding::NextContributionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:0) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + fn contribution_over_limit() -> Weight { + // Proof Size summary in bytes: + // Measured: `37440` + // Estimated: `730613` + // Minimum execution time: 1_103_000_000 picoseconds. + Weight::from_parts(1_165_000_000, 730613) + .saturating_add(RocksDbWeight::get().reads(267_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn evaluation_unbond_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1411` + // Estimated: `4614` + // Minimum execution time: 55_000_000 picoseconds. + Weight::from_parts(60_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn evaluation_reward_payout_for_with_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1515` + // Estimated: `4614` + // Minimum execution time: 92_000_000 picoseconds. + Weight::from_parts(102_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn evaluation_reward_payout_for_no_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1219` + // Estimated: `3814` + // Minimum execution time: 48_000_000 picoseconds. + Weight::from_parts(49_000_000, 3814) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Evaluations` (r:1 w:1) + /// Proof: `PolimecFunding::Evaluations` (`max_values`: None, `max_size`: Some(345), added: 2820, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn evaluation_slash_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1419` + // Estimated: `4614` + // Minimum execution time: 68_000_000 picoseconds. + Weight::from_parts(71_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn bid_ct_mint_for_with_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1629` + // Estimated: `4614` + // Minimum execution time: 96_000_000 picoseconds. + Weight::from_parts(99_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn bid_ct_mint_for_no_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1180` + // Estimated: `3883` + // Minimum execution time: 44_000_000 picoseconds. + Weight::from_parts(47_000_000, 3883) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn contribution_ct_mint_for_with_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1545` + // Estimated: `4614` + // Minimum execution time: 91_000_000 picoseconds. + Weight::from_parts(98_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Asset` (r:1 w:1) + /// Proof: `LocalAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `LocalAssets::Account` (r:1 w:1) + /// Proof: `LocalAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn contribution_ct_mint_for_no_ct_account_creation() -> Weight { + // Proof Size summary in bytes: + // Measured: `1217` + // Estimated: `3829` + // Minimum execution time: 46_000_000 picoseconds. + Weight::from_parts(50_000_000, 3829) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `LinearRelease::Vesting` (r:1 w:1) + /// Proof: `LinearRelease::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn start_bid_vesting_schedule_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `818` + // Estimated: `4283` + // Minimum execution time: 29_000_000 picoseconds. + Weight::from_parts(31_000_000, 4283) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `LinearRelease::Vesting` (r:1 w:1) + /// Proof: `LinearRelease::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn start_contribution_vesting_schedule_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `847` + // Estimated: `4312` + // Minimum execution time: 30_000_000 picoseconds. + Weight::from_parts(32_000_000, 4312) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn payout_bid_funds_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1372` + // Estimated: `6208` + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(69_000_000, 6208) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn payout_contribution_funds_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1401` + // Estimated: `6208` + // Minimum execution time: 69_000_000 picoseconds. + Weight::from_parts(77_000_000, 6208) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::ProjectsToUpdate` (r:2980 w:1) + /// Proof: `PolimecFunding::ProjectsToUpdate` (`max_values`: None, `max_size`: Some(622), added: 3097, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 99]`. + /// The range of component `y` is `[1, 10000]`. + fn decide_project_outcome(x: u32, y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `10254 + x * (419 ±0) + y * (20 ±0)` + // Estimated: `35057 + x * (4876 ±4_177) + y * (1437 ±41)` + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(68_000_000, 35057) + // Standard Error: 4_809_624 + .saturating_add(Weight::from_parts(5_610_465, 0).saturating_mul(x.into())) + // Standard Error: 47_674 + .saturating_add(Weight::from_parts(1_647_468, 0).saturating_mul(y.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) + .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(Weight::from_parts(0, 4876).saturating_mul(x.into())) + .saturating_add(Weight::from_parts(0, 1437).saturating_mul(y.into())) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn release_bid_funds_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1481` + // Estimated: `6208` + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(71_000_000, 6208) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Asset` (r:1 w:1) + /// Proof: `StatemintAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `StatemintAssets::Account` (r:2 w:2) + /// Proof: `StatemintAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn release_contribution_funds_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1453` + // Measured: `1474` // Estimated: `6208` - // Minimum execution time: 83_000_000 picoseconds. - Weight::from_parts(89_000_000, 6208) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + // Minimum execution time: 64_000_000 picoseconds. + Weight::from_parts(70_000_000, 6208) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: PolimecFunding ProjectsDetails (r:1 w:0) - /// Proof Skipped: PolimecFunding ProjectsDetails (max_values: None, max_size: None, mode: Measured) - /// Storage: PolimecFunding Contributions (r:1 w:1) - /// Proof Skipped: PolimecFunding Contributions (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(1099), added: 3574, mode: MaxEncodedLen) + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Bids` (r:1 w:1) + /// Proof: `PolimecFunding::Bids` (`max_values`: None, `max_size`: Some(418), added: 2893, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) + fn bid_unbond_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `1486` + // Estimated: `4614` + // Minimum execution time: 52_000_000 picoseconds. + Weight::from_parts(57_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `PolimecFunding::ProjectsDetails` (r:1 w:0) + /// Proof: `PolimecFunding::ProjectsDetails` (`max_values`: None, `max_size`: Some(349), added: 2824, mode: `MaxEncodedLen`) + /// Storage: `PolimecFunding::Contributions` (r:1 w:1) + /// Proof: `PolimecFunding::Contributions` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(1149), added: 3624, mode: `MaxEncodedLen`) fn contribution_unbond_for() -> Weight { // Proof Size summary in bytes: - // Measured: `1397` - // Estimated: `4862` - // Minimum execution time: 60_000_000 picoseconds. - Weight::from_parts(66_000_000, 4862) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Measured: `1441` + // Estimated: `4614` + // Minimum execution time: 52_000_000 picoseconds. + Weight::from_parts(57_000_000, 4614) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } } \ No newline at end of file diff --git a/pallets/linear-release/src/benchmarking.rs b/pallets/linear-release/src/benchmarking.rs index 319425d2a..f31a9905e 100644 --- a/pallets/linear-release/src/benchmarking.rs +++ b/pallets/linear-release/src/benchmarking.rs @@ -29,7 +29,7 @@ use sp_runtime::traits::{CheckedDiv, CheckedMul}; const SEED: u32 = 0; fn add_holds(who: &T::AccountId, n: u32) { - for id in 0..n { + for _id in 0..n { let locked = 256u32; let reason: ReasonOf = T::BenchmarkReason::get(); let _ = T::Currency::hold(&reason, who, locked.into()); diff --git a/pallets/parachain-staking/src/benchmarks.rs b/pallets/parachain-staking/src/benchmarks.rs index 5da392aca..59fdc9106 100644 --- a/pallets/parachain-staking/src/benchmarks.rs +++ b/pallets/parachain-staking/src/benchmarks.rs @@ -23,12 +23,13 @@ use crate::{ AwardedPts, BalanceOf, Call, CandidateBondLessRequest, Config, DelegationAction, Pallet, ParachainBondConfig, ParachainBondInfo, Points, Range, RewardPayment, Round, ScheduledRequest, Staked, TopDelegations, }; -use frame_support::traits::fungible::{Inspect, Mutate}; - use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, vec}; -use frame_support::traits::{fungible::Balanced, Get, OnFinalize, OnInitialize}; +use frame_support::traits::{ + fungible::{Inspect, Mutate}, + Get, OnFinalize, OnInitialize, +}; use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; -#[cfg(feature = "std")] +#[cfg(test)] use sp_runtime::BuildStorage; use sp_runtime::{Perbill, Percent}; use sp_std::{default::Default, vec::Vec}; diff --git a/runtimes/testnet/src/lib.rs b/runtimes/testnet/src/lib.rs index a89731cc5..1038734fe 100644 --- a/runtimes/testnet/src/lib.rs +++ b/runtimes/testnet/src/lib.rs @@ -644,6 +644,7 @@ impl pallet_funding::Config for Runtime { type MaxContributionsPerUser = ConstU32<256>; type MaxEvaluationsPerUser = ConstU32<256>; type MaxMessageSizeThresholds = MaxMessageSizeThresholds; + type MaxProjectsToUpdateInsertionAttempts = ConstU32<100>; type MaxProjectsToUpdatePerBlock = ConstU32<100>; type Multiplier = pallet_funding::types::Multiplier; type NativeCurrency = Balances;