From f5549535d0dba7ac4bdacdae5bd3e04404345a56 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Rios <54085674+JuaniRios@users.noreply.github.com> Date: Fri, 9 Feb 2024 16:24:58 +0100 Subject: [PATCH] Feature/plmc 267 add complexity parameters to extrinsic benchmarks (#148) * feat(287): parachain information discovery and channel opening automatic hrmp connection working Genesis instantiator usage and first draft of HRMP connection formatting feature propagation cleanup new node functioning. genesis not yet sure if working new node functioning. genesis not yet sure if working somehow compiling and test passing save save save feat(287): para_id setting extrinsic implemented and tested save same log crate across workspace same log crate across workspace save save save feat(287): changed tight couple of pallet_xcm by extracting sender trait feat(287): first commit feat(285): POC Hrmp automatic acceptance * first commit * save * penpal local fork * save * save * save * HRMP establishment successfully mocked! * pallet-funding tests fixed * migration check working * fixes * add cargo lock * dmp fix * formatting * small fixed * fixes * save * compiling, unit converion to map * revert staking changes * saving now evaluation reward and move to u64 for migration * save * save * migration is successfully sent and reflected in the system * vesting scheduling working in polimec-receiver * save: starting to implement transact response, but we need to store a new map of query id -> unconfirmed transactions * save * Migration for a single user working fully and tested * Everything works! * pallet_funding test broken currently * bug found in evaluation unbonding by cleaner. Still an infinite loop bug remaining * all bugs squashed B) * need to find a way to generate function from a new macro * need to find a way to generate function from a new macro * e2e tests successfully adapted to the xcm emulator * Testnet now using Oracle, and e2e successfully passing. * not all xcmp messages being received * save * cleanup * fmt * fixes * save * limiting 5 migrations per block works * fmt * save * back to normal migration without bundling per block, now works for some reason * final commit * first commit * ct migration tests refactor * stable * using generate_accounts! macro in all integration tests * wip * big refactor * almost there * working * final changes * tests passing * multiple projects test passing. Big bug found with ever-increasing running times Failing test for release of ct deposit on failed project * state machine intergration for releasing deposit * starting to fix last tests * only evaluation automatic release working. `bids_and_community_and_remainder_contribution_plmc_bonded_is_returned_automatically_on_funding_fail` failing because of this * state machine fixed where it only worked on evaluations * broken tests * save * manual and automatic ct mint tests now passing. Removed the specific ones for just bids/evals/contr. and merged them all into 1 for manual and one for automatic * fixed most tests. Bid calculation function not working as intended now * benchmark tests passing * fmt. real benchmarks run successfully * save * fixes * remove unnecessary time advancement in project creation * MVP! * multiple community projects can be parallelized * all async creation functions working * bid refund test not passing * fixed * projects meeting together at the desired state (they start at different points automatically) * save * fixed tests. they were failing due to debug durations not disabled * traits broken :( * save * conditionally adding genesis config * Fixed the externalities issue by using the single threaded tokio runtime. added check for asking more remainder CT buys that are available * removed conditional instantiator fields and conditional genesis config on pallet-funding. * fixes * trying to remove Sync and Send traits * trying to have one genesis config * save Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * build-spec working but some logic in instantiator is failing bids Signed-off-by: Juan Ignacio Rios * node instantiation confirmed to be working, and a test was written in integration-tests Signed-off-by: Juan Ignacio Rios * fix: fmt Signed-off-by: Juan Ignacio Rios * fix tests Signed-off-by: Juan Ignacio Rios * merge fixes Signed-off-by: Juan Ignacio Rios * new test Signed-off-by: Juan Ignacio Rios * remove testing-node feature Signed-off-by: Juan Ignacio Rios * remove cargo-expand-visible feature and unused modular genesis_config.rs Signed-off-by: Juan Ignacio Rios * remove unused mut https://github.com/Polimec/polimec-node/pull/130#discussion_r1445793434 Signed-off-by: Juan Ignacio Rios * remove unused mut https://github.com/Polimec/polimec-node/pull/130#discussion_r1445795866 Signed-off-by: Juan Ignacio Rios * TODO added https://github.com/Polimec/polimec-node/pull/130#discussion_r1445838795 Signed-off-by: Juan Ignacio Rios * remove unused old genesis builder https://github.com/Polimec/polimec-node/pull/130#discussion_r1445855143 Signed-off-by: Juan Ignacio Rios * remove else statement https://github.com/Polimec/polimec-node/pull/130#discussion_r1445861196 Signed-off-by: Juan Ignacio Rios * remove commented out lines https://github.com/Polimec/polimec-node/pull/130#discussion_r1445888533 Signed-off-by: Juan Ignacio Rios * remove AccountList and use same pattern as other functions https://github.com/Polimec/polimec-node/pull/130#discussion_r1445890382. Signed-off-by: Juan Ignacio Rios * updated comment on Expendable reason https://github.com/Polimec/polimec-node/pull/130#discussion_r1445846983 Signed-off-by: Juan Ignacio Rios * fix: could not compile pallet-funding alone due to missing `default = ["std"]"` in Cargo.toml Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * fix linear-release benchmarks Signed-off-by: Juan Ignacio Rios * fix staking benchmarks and add optional compilation for externalities on instantiator Signed-off-by: Juan Ignacio Rios * pallet_funding benchmarks fixed. Signed-off-by: Juan Ignacio Rios * uncommented integration-tests. Had to do it to compile workspace with `runtime-benchmarks` Signed-off-by: Juan Ignacio Rios * all benchmarks running to completion Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * fix testnet runtime, bad merge with main Signed-off-by: Juan Ignacio Rios * fix import Signed-off-by: Juan Ignacio Rios * fixed staking benchmarks Signed-off-by: Juan Ignacio Rios * cleanup Signed-off-by: Juan Ignacio Rios * uncomment integration-tests Signed-off-by: Juan Ignacio Rios * remove pallet_funding dependency from linear-release Signed-off-by: Juan Ignacio Rios * write single test for each benchmark Signed-off-by: Juan Ignacio Rios * successfully added the async parallel instantiaton in a real benchmark :) Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * rename start_evaluation fn Signed-off-by: Juan Ignacio Rios * remove unnecessary parameters from `create` and `edit_metadata` Signed-off-by: Juan Ignacio Rios * fix testnet pallet config Signed-off-by: Juan Ignacio Rios * changed add_to_update_store Signed-off-by: Juan Ignacio Rios * check tests pass, add new draft tests Signed-off-by: Juan Ignacio Rios * add_to_update_store benchmark in start_evaluation Signed-off-by: Juan Ignacio Rios * new pr template Signed-off-by: Juan Ignacio Rios * only one pr template Signed-off-by: Juan Ignacio Rios * new ProjectToUpdate functions that return parameters for weight functions. Benchmark functions broken Signed-off-by: Juan Ignacio Rios * fixed eval start bench Signed-off-by: Juan Ignacio Rios * fix manual auction benchmark Signed-off-by: Juan Ignacio Rios * english_start benchmarked Signed-off-by: Juan Ignacio Rios * trying to remove `z` and add automatic auction bench Signed-off-by: Juan Ignacio Rios * finished automatic auction benchmark, now running it for real Signed-off-by: Juan Ignacio Rios * new weight gen Signed-off-by: Juan Ignacio Rios * evaluation benchmarks. fix auction round extrinsic Signed-off-by: Juan Ignacio Rios * save contributions extrinsic Signed-off-by: Juan Ignacio Rios * contribution logic split into separate functions Signed-off-by: Juan Ignacio Rios * all contribution bench branches coded. Missing single tests and using those weights in the contribute extrinsic Signed-off-by: Juan Ignacio Rios * contribute benches tested and passing. Missing real benchmarking and adding the correct weights on the extrinsic Signed-off-by: Juan Ignacio Rios * contribution_over_limit_ends_round removed since that case never happens Signed-off-by: Juan Ignacio Rios * abstracted away `ProjectsToUpdate` filling Signed-off-by: Juan Ignacio Rios * weight gen v2 Signed-off-by: Juan Ignacio Rios * added weight returns on contribute() Signed-off-by: Juan Ignacio Rios * all tests for benches rewritten so far are passing Signed-off-by: Juan Ignacio Rios * added ct_deposit difference benchmarks for first contribution. Bench running atm. Onward to bids Signed-off-by: Juan Ignacio Rios * weight generated. Seems off Signed-off-by: Juan Ignacio Rios * rename benches Signed-off-by: Juan Ignacio Rios * modify contribution function to return new bench fns Signed-off-by: Juan Ignacio Rios * removed chance to bid over the limit by removing the lowest bid. Signed-off-by: Juan Ignacio Rios * bid benchmark abstracted for future complexity parametrization Signed-off-by: Juan Ignacio Rios * complexity parameter `x` working (existing bids). Missing `y` for times "perform_bid" is called Signed-off-by: Juan Ignacio Rios * new parameter "y" for amount of perform_bid calls on one extrinsic Signed-off-by: Juan Ignacio Rios * remove unused bucket helper function Signed-off-by: Juan Ignacio Rios * ct deposit bid benchmark difference Signed-off-by: Juan Ignacio Rios * real weight returns added for bid extrinsic. Trying to update now price calculation test Signed-off-by: Juan Ignacio Rios * updated test, but still inaccurate. 11.1818 vs 11 Signed-off-by: Juan Ignacio Rios * evaluation_unbond_for does not need complexity parameters Signed-off-by: Juan Ignacio Rios * bug fixed in instantiator where multiple evaluations by same account didnt get the correct assertion. Bench written for reward to evaluators. Two branches: ct account created, and not Signed-off-by: Juan Ignacio Rios * real weight returns on evaluation reward payouts Signed-off-by: Juan Ignacio Rios * default weight on fn Signed-off-by: Juan Ignacio Rios * evaluation slash does not need complexity parameters or logic branches Signed-off-by: Juan Ignacio Rios * test for bench now passing. had to modify the state machine, but we will revise that code later Signed-off-by: Juan Ignacio Rios * bid_ct_mint_for done Signed-off-by: Juan Ignacio Rios * contribution_ct_mint_for done Signed-off-by: Juan Ignacio Rios * contribution_ct_mint_for done Signed-off-by: Juan Ignacio Rios * vesting schedule benchmarks (minimal changes) Signed-off-by: Juan Ignacio Rios * payouts benchmarks (minimal changes) Signed-off-by: Juan Ignacio Rios * all benchmarks passing Signed-off-by: Juan Ignacio Rios * price test was correct, fixed the expectation Signed-off-by: Juan Ignacio Rios * save Signed-off-by: Juan Ignacio Rios * fix evaluator rewards test Signed-off-by: Juan Ignacio Rios * fmt, remove draft tests Signed-off-by: Juan Ignacio Rios * remove unused tests. Add real weights on pallet-funding Signed-off-by: Juan Ignacio Rios * delete commented out code Signed-off-by: Juan Ignacio Rios * weight returns testing possible :) `start_evaluation` test done Signed-off-by: Juan Ignacio Rios * removed benchmark tests. we think they are not necessary Signed-off-by: Juan Ignacio Rios * add constant annotations to Config types https://github.com/Polimec/polimec-node/pull/148#discussion_r1482623902 Signed-off-by: Juan Ignacio Rios * rename benchmark variables to weight return variables https://github.com/Polimec/polimec-node/pull/148#discussion_r1482703661 Signed-off-by: Juan Ignacio Rios * is_empty() Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com> * is_zero() Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com> * fix post merge Signed-off-by: Juan Ignacio Rios * push lock Signed-off-by: Juan Ignacio Rios * fix syntax Signed-off-by: Juan Ignacio Rios * fmt Signed-off-by: Juan Ignacio Rios * fmt Signed-off-by: Juan Ignacio Rios --------- Signed-off-by: Juan Ignacio Rios Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com> --- .github/PULL_REQUEST_TEMPLATE.md | 11 + .github/workflows/pull_request_template.md | 10 - Cargo.lock | 864 +------- Cargo.toml | 4 +- nodes/parachain/src/chain_spec/testnet.rs | 3 +- pallets/funding/Cargo.toml | 1 + pallets/funding/src/benchmarking.rs | 2069 ++++++++++++++++--- pallets/funding/src/functions.rs | 581 ++++-- pallets/funding/src/impls.rs | 163 +- pallets/funding/src/instantiator.rs | 234 ++- pallets/funding/src/lib.rs | 108 +- pallets/funding/src/mock.rs | 4 +- pallets/funding/src/tests.rs | 346 ++-- pallets/funding/src/weights.rs | 1751 +++++++++++++--- pallets/linear-release/src/benchmarking.rs | 2 +- pallets/parachain-staking/src/benchmarks.rs | 9 +- runtimes/testnet/src/lib.rs | 1 + 17 files changed, 4223 insertions(+), 1938 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/workflows/pull_request_template.md 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;