From 50562c0bef0e0705608778d8e99d2629de630690 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 20 Oct 2022 14:33:22 -0400 Subject: [PATCH 01/52] stash precompile changes in other branch and push pallet changes leaking std librar --- Cargo.lock | 11 ++ Cargo.toml | 1 + pallets/governance-origins/Cargo.toml | 21 +++ pallets/governance-origins/src/lib.rs | 139 +++++++++++++++++++ runtime/moonbase/Cargo.toml | 3 + runtime/moonbase/src/governance/mod.rs | 5 +- runtime/moonbase/src/governance/referenda.rs | 11 +- runtime/moonbase/src/lib.rs | 4 +- 8 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 pallets/governance-origins/Cargo.toml create mode 100644 pallets/governance-origins/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8ffacc1022..a49a4ccafa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5080,6 +5080,7 @@ dependencies = [ "pallet-evm-precompile-xcm-utils", "pallet-evm-precompile-xtokens", "pallet-evm-precompileset-assets-erc20", + "pallet-governance-origins", "pallet-identity", "pallet-maintenance-mode", "pallet-migrations", @@ -7480,6 +7481,16 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-governance-origins" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "pallet-grandpa" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 5f5aa0936a..444c1e443e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "node", "node/cli", "node/service", + "pallets/governance-origins", "pallets/maintenance-mode", "pallets/migrations", "pallets/moonbeam-orbiters", diff --git a/pallets/governance-origins/Cargo.toml b/pallets/governance-origins/Cargo.toml new file mode 100644 index 0000000000..82207d7fcc --- /dev/null +++ b/pallets/governance-origins/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "pallet-governance-origins" +authors = [ "PureStake" ] +description = "Custom origins for governance interventions" +edition = "2021" +version = "0.1.0" + +[dependencies] +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +parity-scale-codec = { version = "3.0.0", default-features = false } +scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } + +[features] +default = [ "std" ] +std = [ + "frame-support/std", + "frame-system/std", + "scale-info/std", +] +runtime-benchmarks = [] diff --git a/pallets/governance-origins/src/lib.rs b/pallets/governance-origins/src/lib.rs new file mode 100644 index 0000000000..5be9706916 --- /dev/null +++ b/pallets/governance-origins/src/lib.rs @@ -0,0 +1,139 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +//! Custom origins for governance interventions. + +pub use governance_origins::*; + +#[frame_support::pallet] +pub mod governance_origins { + use frame_support::{pallet_prelude::*, traits::Currency}; + + type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// Currency type to limit spends per spend origin + type Currency: Currency; + /// Maximum amount able to be spent by SmallSpender origin from treasury at once + #[pallet::constant] + type MaxSmallSpenderSpend: Get>; + /// Maximum amount able to be spent by MediumSpender origin from treasury at once + #[pallet::constant] + type MaxMediumSpenderSpend: Get>; + /// Maximum amount able to be spent by BigSpender origin from treasury at once + #[pallet::constant] + type MaxBigSpenderSpend: Get>; + /// Maximum amount able to be spent by Treasurer origin from treasury at once + #[pallet::constant] + type MaxTreasurerSpend: Get>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] + #[pallet::origin] + pub enum Origin { + /// Origin able to spend up to MaxTreasurerSpend from the treasury at once. + Treasurer, + /// Origin able to cancel referenda. + ReferendumCanceller, + /// Origin able to kill referenda. + ReferendumKiller, + /// Origin able to spend up to MaxSmallSpenderSpend from the treasury at once. + SmallSpender, + /// Origin able to spend up to MaxMediumSpenderSpend from the treasury at once. + MediumSpender, + /// Origin able to spend up to MaxBigSpenderSpend from the treasury at once. + BigSpender, + /// Origin able to dispatch a whitelisted call. + WhitelistedCaller, + } + + macro_rules! decl_unit_ensures { + ( $name:ident: $success_type:ty = $success:expr ) => { + pub struct $name; + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + Origin::$name => Ok($success), + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::$name)) + } + } + }; + ( $name:ident ) => { decl_unit_ensures! { $name : () = () } }; + ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => { + decl_unit_ensures! { $name: $success_type = $success } + decl_unit_ensures! { $( $rest )* } + }; + ( $name:ident, $( $rest:tt )* ) => { + decl_unit_ensures! { $name } + decl_unit_ensures! { $( $rest )* } + }; + () => {} + } + decl_unit_ensures!(ReferendumCanceller, ReferendumKiller, WhitelistedCaller,); + + macro_rules! decl_ensure { + ( + $vis:vis type $name:ident: EnsureOrigin { + $( $item:ident = $success:expr, )* + } + ) => { + $vis struct $name(PhantomData); + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + $( + Origin::$item => Ok($success), + )* + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + // By convention the more privileged origins go later, so for greatest chance + // of success, we want the last one. + let _result: Result = Err(()); + $( + let _result: Result = Ok(O::from(Origin::$item)); + )* + _result + } + } + } + } + + // Origins able to spend up = $AMOUNT from the treasury at once + decl_ensure! { + pub type Spender: EnsureOrigin> { + SmallSpender = T::MaxSmallSpenderSpend::get(), + MediumSpender = T::MaxMediumSpenderSpend::get(), + BigSpender = T::MaxBigSpenderSpend::get(), + Treasurer = T::MaxTreasurerSpend::get(), + } + } +} diff --git a/runtime/moonbase/Cargo.toml b/runtime/moonbase/Cargo.toml index a87293b148..5f9a0b4f4b 100644 --- a/runtime/moonbase/Cargo.toml +++ b/runtime/moonbase/Cargo.toml @@ -32,6 +32,7 @@ pallet-author-mapping = { path = "../../pallets/author-mapping", default-feature pallet-crowdloan-rewards = { git = "https://github.com/purestake/crowdloan-rewards", branch = "moonbeam-polkadot-v0.9.29", default-features = false } pallet-ethereum-chain-id = { path = "../../pallets/ethereum-chain-id", default-features = false } pallet-ethereum-xcm = { path = "../../pallets/ethereum-xcm", default-features = false } +pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } pallet-maintenance-mode = { path = "../../pallets/maintenance-mode", default-features = false, features = [ "xcm-support" ] } pallet-migrations = { path = "../../pallets/migrations", default-features = false } pallet-moonbeam-orbiters = { path = "../../pallets/moonbeam-orbiters", default-features = false } @@ -216,6 +217,7 @@ std = [ "pallet-evm-precompileset-assets-erc20/std", "pallet-evm/std", "pallet-identity/std", + "pallet-governance-origins/std", "pallet-maintenance-mode/std", "pallet-migrations/std", "pallet-moonbeam-orbiters/std", @@ -292,6 +294,7 @@ runtime-benchmarks = [ "pallet-crowdloan-rewards/runtime-benchmarks", "pallet-ethereum-xcm/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", + "pallet-governance-origins/runtime-benchmarks", "pallet-moonbeam-orbiters/runtime-benchmarks", "pallet-parachain-staking/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", diff --git a/runtime/moonbase/src/governance/mod.rs b/runtime/moonbase/src/governance/mod.rs index 4832e518c1..831d624ece 100644 --- a/runtime/moonbase/src/governance/mod.rs +++ b/runtime/moonbase/src/governance/mod.rs @@ -22,9 +22,8 @@ pub mod referenda; use super::*; -mod origins; -pub use origins::{ - pallet_custom_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, +pub use pallet_governance_origins::{ + governance_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, }; mod tracks; pub use tracks::TracksInfo; diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index a91f8edaf9..19200af426 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -49,9 +49,16 @@ parameter_types! { parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); } -pub type TreasurySpender = EitherOf, Spender>; +pub type TreasurySpender = + EitherOf, pallet_governance_origins::Spender>; -impl origins::pallet_custom_origins::Config for Runtime {} +impl pallet_governance_origins::Config for Runtime { + type Currency = Balance; + type MaxSmallSpenderSpend = ConstU128<{ 200 * UNIT * SUPPLY_FACTOR }>; + type MaxMediumSpenderSpend = ConstU128<{ 2000 * UNIT * SUPPLY_FACTOR }>; + type MaxBigSpenderSpend = ConstU128<{ 10000 * UNIT * SUPPLY_FACTOR }>; + type MaxTreasurerSpend = MaxBalance; +} // purpose of this pallet is to queue calls to be dispatched as by root for later impl pallet_whitelist::Config for Runtime { diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index 796a6992df..af8f762334 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -113,7 +113,7 @@ pub type Precompiles = MoonbasePrecompiles; pub mod asset_config; pub mod governance; pub mod xcm_config; -use governance::{councils::*, pallet_custom_origins, referenda::*}; +use governance::{councils::*, referenda::*}; /// UNIT, the native token, uses 18 decimals of precision. pub mod currency { @@ -1194,7 +1194,7 @@ construct_runtime! { pallet_collective::::{Pallet, Call, Storage, Event, Origin, Config} = 40, ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 41, Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 42, - Origins: pallet_custom_origins::{Origin} = 43, + Origins: pallet_governance_origins::{Origin} = 43, Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 44, Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 45, } From 9395e664cf2e5321f8ac705349b845902d2f1865 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 20 Oct 2022 14:49:44 -0400 Subject: [PATCH 02/52] still leaking std --- pallets/governance-origins/Cargo.toml | 3 ++- pallets/governance-origins/src/lib.rs | 4 ++-- runtime/moonbase/src/governance/referenda.rs | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pallets/governance-origins/Cargo.toml b/pallets/governance-origins/Cargo.toml index 82207d7fcc..bcbcefb5b4 100644 --- a/pallets/governance-origins/Cargo.toml +++ b/pallets/governance-origins/Cargo.toml @@ -8,7 +8,7 @@ version = "0.1.0" [dependencies] frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -parity-scale-codec = { version = "3.0.0", default-features = false } +parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } [features] @@ -16,6 +16,7 @@ default = [ "std" ] std = [ "frame-support/std", "frame-system/std", + "parity-scale-codec/std", "scale-info/std", ] runtime-benchmarks = [] diff --git a/pallets/governance-origins/src/lib.rs b/pallets/governance-origins/src/lib.rs index 5be9706916..1ef92383ad 100644 --- a/pallets/governance-origins/src/lib.rs +++ b/pallets/governance-origins/src/lib.rs @@ -13,10 +13,10 @@ //! Custom origins for governance interventions. -pub use governance_origins::*; +pub use pallet_governance_origins::*; #[frame_support::pallet] -pub mod governance_origins { +pub mod pallet_governance_origins { use frame_support::{pallet_prelude::*, traits::Currency}; type BalanceOf = diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index 19200af426..664c8521ad 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -49,8 +49,10 @@ parameter_types! { parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); } -pub type TreasurySpender = - EitherOf, pallet_governance_origins::Spender>; +pub type TreasurySpender = EitherOf< + EnsureRootWithSuccess, + pallet_governance_origins::Spender, +>; impl pallet_governance_origins::Config for Runtime { type Currency = Balance; From 8ed14e7146aaed7cfdd041d65d3322a877b61141 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Fri, 21 Oct 2022 11:13:38 -0400 Subject: [PATCH 03/52] using sp std phantomdata did not fix --- Cargo.lock | 1 + pallets/governance-origins/Cargo.toml | 2 ++ pallets/governance-origins/src/lib.rs | 6 +++--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a49a4ccafa..ebb61407d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7489,6 +7489,7 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", + "sp-std", ] [[package]] diff --git a/pallets/governance-origins/Cargo.toml b/pallets/governance-origins/Cargo.toml index bcbcefb5b4..62300d5f70 100644 --- a/pallets/governance-origins/Cargo.toml +++ b/pallets/governance-origins/Cargo.toml @@ -10,6 +10,7 @@ frame-support = { git = "https://github.com/purestake/substrate", branch = "moon frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } [features] default = [ "std" ] @@ -18,5 +19,6 @@ std = [ "frame-system/std", "parity-scale-codec/std", "scale-info/std", + "sp-std/std", ] runtime-benchmarks = [] diff --git a/pallets/governance-origins/src/lib.rs b/pallets/governance-origins/src/lib.rs index 1ef92383ad..9651c6794d 100644 --- a/pallets/governance-origins/src/lib.rs +++ b/pallets/governance-origins/src/lib.rs @@ -13,10 +13,10 @@ //! Custom origins for governance interventions. -pub use pallet_governance_origins::*; +pub use governance_origins::*; #[frame_support::pallet] -pub mod pallet_governance_origins { +pub mod governance_origins { use frame_support::{pallet_prelude::*, traits::Currency}; type BalanceOf = @@ -100,7 +100,7 @@ pub mod pallet_governance_origins { $( $item:ident = $success:expr, )* } ) => { - $vis struct $name(PhantomData); + $vis struct $name(sp_std::marker::PhantomData); impl> + From> EnsureOrigin for $name { From 315116ab9ec69b17d80b2678b914692a7a607b3c Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Fri, 21 Oct 2022 11:32:12 -0400 Subject: [PATCH 04/52] ty @nanocryk for std leak fix --- pallets/governance-origins/src/lib.rs | 1 + runtime/moonbase/src/governance/origins.rs | 125 ------------------- runtime/moonbase/src/governance/referenda.rs | 2 +- runtime/moonbase/src/governance/tracks.rs | 16 +-- 4 files changed, 10 insertions(+), 134 deletions(-) delete mode 100644 runtime/moonbase/src/governance/origins.rs diff --git a/pallets/governance-origins/src/lib.rs b/pallets/governance-origins/src/lib.rs index 9651c6794d..d85e48fd79 100644 --- a/pallets/governance-origins/src/lib.rs +++ b/pallets/governance-origins/src/lib.rs @@ -12,6 +12,7 @@ // GNU General Public License for more details. //! Custom origins for governance interventions. +#![cfg_attr(not(feature = "std"), no_std)] pub use governance_origins::*; diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs deleted file mode 100644 index 821504db9d..0000000000 --- a/runtime/moonbase/src/governance/origins.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -//! Custom origins for governance interventions. - -pub use pallet_custom_origins::*; - -#[frame_support::pallet] -pub mod pallet_custom_origins { - use crate::{ - currency::{SUPPLY_FACTOR, UNIT}, - Balance, - }; - use frame_support::pallet_prelude::*; - - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::pallet] - pub struct Pallet(_); - - #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] - #[pallet::origin] - pub enum Origin { - /// Origin for spending (any amount of) funds. - Treasurer, - /// Origin able to cancel referenda. - ReferendumCanceller, - /// Origin able to kill referenda. - ReferendumKiller, - /// Origin able to spend up to 10,000 UNIT from the treasury at once. - SmallSpender, - /// Origin able to spend up to 100,000 UNIT from the treasury at once. - MediumSpender, - /// Origin able to spend up to 1,000,000 UNIT from the treasury at once. - BigSpender, - /// Origin able to dispatch a whitelisted call. - WhitelistedCaller, - } - - macro_rules! decl_unit_ensures { - ( $name:ident: $success_type:ty = $success:expr ) => { - pub struct $name; - impl> + From> - EnsureOrigin for $name - { - type Success = $success_type; - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - Origin::$name => Ok($success), - r => Err(O::from(r)), - }) - } - #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin() -> Result { - Ok(O::from(Origin::$name)) - } - } - }; - ( $name:ident ) => { decl_unit_ensures! { $name : () = () } }; - ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => { - decl_unit_ensures! { $name: $success_type = $success } - decl_unit_ensures! { $( $rest )* } - }; - ( $name:ident, $( $rest:tt )* ) => { - decl_unit_ensures! { $name } - decl_unit_ensures! { $( $rest )* } - }; - () => {} - } - decl_unit_ensures!(ReferendumCanceller, ReferendumKiller, WhitelistedCaller,); - - macro_rules! decl_ensure { - ( - $vis:vis type $name:ident: EnsureOrigin { - $( $item:ident = $success:expr, )* - } - ) => { - $vis struct $name; - impl> + From> - EnsureOrigin for $name - { - type Success = $success_type; - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - $( - Origin::$item => Ok($success), - )* - r => Err(O::from(r)), - }) - } - #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin() -> Result { - // By convention the more privileged origins go later, so for greatest chance - // of success, we want the last one. - let _result: Result = Err(()); - $( - let _result: Result = Ok(O::from(Origin::$item)); - )* - _result - } - } - } - } - - // Origins able to spend up to $AMOUNT from the treasury at once - decl_ensure! { - pub type Spender: EnsureOrigin { - SmallSpender = 200 * UNIT * SUPPLY_FACTOR, - MediumSpender = 2000 * UNIT * SUPPLY_FACTOR, - BigSpender = 10000 * UNIT * SUPPLY_FACTOR, - Treasurer = Balance::max_value(), - } - } -} diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index 664c8521ad..a8f934f545 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -55,7 +55,7 @@ pub type TreasurySpender = EitherOf< >; impl pallet_governance_origins::Config for Runtime { - type Currency = Balance; + type Currency = Balances; type MaxSmallSpenderSpend = ConstU128<{ 200 * UNIT * SUPPLY_FACTOR }>; type MaxMediumSpenderSpend = ConstU128<{ 2000 * UNIT * SUPPLY_FACTOR }>; type MaxBigSpenderSpend = ConstU128<{ 10000 * UNIT * SUPPLY_FACTOR }>; diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index a553dfbf43..bb67a5131a 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -169,18 +169,18 @@ impl pallet_referenda::TracksInfo for TracksInfo { frame_system::RawOrigin::Root => Ok(0), _ => Err(()), } - } else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) { + } else if let Ok(custom_origin) = governance_origins::Origin::try_from(id.clone()) { match custom_origin { - origins::Origin::WhitelistedCaller => Ok(1), + governance_origins::Origin::WhitelistedCaller => Ok(1), // Unlimited spender - origins::Origin::Treasurer => Ok(10), + governance_origins::Origin::Treasurer => Ok(10), // Referendum admins - origins::Origin::ReferendumCanceller => Ok(11), - origins::Origin::ReferendumKiller => Ok(12), + governance_origins::Origin::ReferendumCanceller => Ok(11), + governance_origins::Origin::ReferendumKiller => Ok(12), // Limited spenders - origins::Origin::SmallSpender => Ok(13), - origins::Origin::MediumSpender => Ok(14), - origins::Origin::BigSpender => Ok(15), + governance_origins::Origin::SmallSpender => Ok(13), + governance_origins::Origin::MediumSpender => Ok(14), + governance_origins::Origin::BigSpender => Ok(15), } } else { Err(()) From 8f24362294fb2053454f5c544eb4b74216dd1986 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Sat, 22 Oct 2022 21:34:34 -0400 Subject: [PATCH 05/52] init referenda precompile needs tryfrom u8 for origins --- Cargo.lock | 28 ++++++++ Cargo.toml | 1 + precompiles/referenda/Cargo.toml | 60 +++++++++++++++++ precompiles/referenda/src/lib.rs | 110 +++++++++++++++++++++++++++++++ runtime/moonbase/Cargo.toml | 2 +- 5 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 precompiles/referenda/Cargo.toml create mode 100644 precompiles/referenda/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ebb61407d5..720c27f114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7292,6 +7292,34 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-evm-precompile-referenda" +version = "0.1.0" +dependencies = [ + "derive_more", + "fp-evm", + "frame-support", + "frame-system", + "hex-literal", + "log", + "num_enum", + "pallet-balances", + "pallet-evm", + "pallet-governance-origins", + "pallet-referenda", + "pallet-timestamp", + "parity-scale-codec", + "precompile-utils", + "rustc-hex", + "scale-info", + "serde", + "sha3 0.9.1", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-evm-precompile-relay-encoder" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 444c1e443e..5277e3b992 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = [ "precompiles/parachain-staking", "precompiles/proxy", "precompiles/randomness", + "precompiles/referenda", "precompiles/relay-encoder", "precompiles/utils", "precompiles/utils/macro", diff --git a/precompiles/referenda/Cargo.toml b/precompiles/referenda/Cargo.toml new file mode 100644 index 0000000000..e8d65b49d0 --- /dev/null +++ b/precompiles/referenda/Cargo.toml @@ -0,0 +1,60 @@ +[package] +name = "pallet-evm-precompile-referenda" +authors = [ "PureStake" ] +description = "A Precompile to make pallet-referenda calls encoding accessible to pallet-evm" +edition = "2021" +version = "0.1.0" + +[dependencies] +log = "0.4" +num_enum = { version = "0.5.3", default-features = false } +rustc-hex = { version = "2.0.1", default-features = false } + +# Moonbeam +precompile-utils = { path = "../utils", default-features = false } +pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } + +# Substrate +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +pallet-referenda = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } +sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } + +# Frontier +fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false, features = [ "forbid-evm-reentrancy" ] } + +[dev-dependencies] +derive_more = "0.99" +hex-literal = "0.3.3" +serde = "1.0.100" +sha3 = "0.9" + +# Moonbeam +precompile-utils = { path = "../utils", features = [ "testing" ] } +# add pallet-governance-origins + +# Substrate +pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } +sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } + +[features] +default = [ "std" ] +std = [ + "fp-evm/std", + "frame-support/std", + "frame-system/std", + "pallet-evm/std", + "pallet-governance-origins/std", + "pallet-referenda/std", + "parity-scale-codec/std", + "parity-scale-codec/std", + "precompile-utils/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs new file mode 100644 index 0000000000..c8d27eaa4a --- /dev/null +++ b/precompiles/referenda/src/lib.rs @@ -0,0 +1,110 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![feature(assert_matches)] + +use fp_evm::PrecompileHandle; +use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::{schedule::DispatchTime, OriginTrait}; +use pallet_evm::AddressMapping; +use pallet_referenda::Call as ReferendaCall; +use pallet_referenda::Pallet as ReferendaPallet; +use precompile_utils::data::Address; +use precompile_utils::prelude::*; +use sp_core::H256; +use sp_std::marker::PhantomData; + +// #[cfg(test)] +// mod mock; +// #[cfg(test)] +// mod tests; + +/// A precompile to wrap the functionality from pallet-referenda. +pub struct ReferendaPrecompile(PhantomData); + +#[precompile_utils::precompile] +impl ReferendaPrecompile +where + Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, + <::Call as Dispatchable>::Origin: + From>, + <::Origin as OriginTrait>::PalletsOrigin: + From, + ::Hash: TryFrom, + ::Call: + Dispatchable + GetDispatchInfo, + <::Call as Dispatchable>::Origin: + From>, + ::Call: From>, +{ + #[precompile::pre_check] + fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let caller_code = pallet_evm::Pallet::::account_codes(handle.context().caller); + // Check that caller is not a smart contract s.t. no code is inserted into + // pallet_evm::AccountCodes except if the caller is another precompile i.e. CallPermit + // TODO: review if this is necessary + if !(caller_code.is_empty() || &caller_code == &[0x60, 0x00, 0x60, 0x00, 0xfd]) { + Err(revert("Referenda not callable by smart contracts")) + } else { + Ok(()) + } + } + + /// Propose a referendum on a privileged action. + /// + /// Parameters: + /// * proposal_origin: The origin from which the proposal should be executed. + /// * proposal_hash: Hash of the proposal preimage. + /// * at: If true then AT block_number, else AFTER block_number + /// * block_number: Inner block number for DispatchTime + #[precompile::public("submit(uint8,bytes32,bool,uint32)")] + fn submit( + handle: &mut impl PrecompileHandle, + proposal_origin: u8, + proposal_hash: H256, + at: bool, + block_number: u32, + ) -> EvmResult { + // need to expose Origin type here? + // <::Origin as OriginTrait>::PalletsOrigin + // make governance_utils crate with origins so can use in precompile + let proposal_origin: pallet_governance_origins::Origin = + proposal_origin.try_into().expect("track dne for origin"); + // consider trying to convert into RawOrigin first, or directly + let proposal_origin: <::Origin as OriginTrait>::PalletsOrigin = proposal_origin.into(); + let proposal_hash: Runtime::Hash = proposal_hash.try_into().expect("Hash"); + let enactment_moment = if at { + DispatchTime::At(block_number) + } else { + DispatchTime::After(block_number) + }; + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let call = ReferendaCall::::submit { + proposal_origin: Box::new(proposal_origin.into()), + proposal_hash, + enactment_moment, + } + .into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } +} diff --git a/runtime/moonbase/Cargo.toml b/runtime/moonbase/Cargo.toml index 5f9a0b4f4b..157b10104f 100644 --- a/runtime/moonbase/Cargo.toml +++ b/runtime/moonbase/Cargo.toml @@ -216,8 +216,8 @@ std = [ "pallet-evm-precompile-xtokens/std", "pallet-evm-precompileset-assets-erc20/std", "pallet-evm/std", - "pallet-identity/std", "pallet-governance-origins/std", + "pallet-identity/std", "pallet-maintenance-mode/std", "pallet-migrations/std", "pallet-moonbeam-orbiters/std", From d83be8e41b43ad78e210bdb4a450bb72609252b0 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Sun, 23 Oct 2022 15:55:45 -0400 Subject: [PATCH 06/52] referenda submit precompile fn --- pallets/governance-origins/src/lib.rs | 17 +++++++++++++++++ precompiles/referenda/src/lib.rs | 17 ++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/pallets/governance-origins/src/lib.rs b/pallets/governance-origins/src/lib.rs index d85e48fd79..991269df89 100644 --- a/pallets/governance-origins/src/lib.rs +++ b/pallets/governance-origins/src/lib.rs @@ -63,6 +63,23 @@ pub mod governance_origins { WhitelistedCaller, } + // Should match track data in runtime (TODO: add test to verify this in runtime, for the precompile) + impl TryFrom for Origin { + type Error = (); + fn try_from(value: u8) -> Result { + match value { + 1 => Ok(Origin::WhitelistedCaller), + 10 => Ok(Origin::Treasurer), + 11 => Ok(Origin::ReferendumCanceller), + 12 => Ok(Origin::ReferendumKiller), + 13 => Ok(Origin::SmallSpender), + 14 => Ok(Origin::MediumSpender), + 15 => Ok(Origin::BigSpender), + _ => Err(()), + } + } + } + macro_rules! decl_unit_ensures { ( $name:ident: $success_type:ty = $success:expr ) => { pub struct $name; diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index c8d27eaa4a..d60e02c9b3 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -22,8 +22,6 @@ use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; use frame_support::traits::{schedule::DispatchTime, OriginTrait}; use pallet_evm::AddressMapping; use pallet_referenda::Call as ReferendaCall; -use pallet_referenda::Pallet as ReferendaPallet; -use precompile_utils::data::Address; use precompile_utils::prelude::*; use sp_core::H256; use sp_std::marker::PhantomData; @@ -80,18 +78,15 @@ where at: bool, block_number: u32, ) -> EvmResult { - // need to expose Origin type here? - // <::Origin as OriginTrait>::PalletsOrigin - // make governance_utils crate with origins so can use in precompile let proposal_origin: pallet_governance_origins::Origin = proposal_origin.try_into().expect("track dne for origin"); - // consider trying to convert into RawOrigin first, or directly - let proposal_origin: <::Origin as OriginTrait>::PalletsOrigin = proposal_origin.into(); - let proposal_hash: Runtime::Hash = proposal_hash.try_into().expect("Hash"); - let enactment_moment = if at { - DispatchTime::At(block_number) + let proposal_hash: Runtime::Hash = proposal_hash + .try_into() + .map_err(|_| revert("Proposal hash input not H256"))?; + let enactment_moment: DispatchTime = if at { + DispatchTime::At(block_number.into()) } else { - DispatchTime::After(block_number) + DispatchTime::After(block_number.into()) }; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); From 21ffc60b6aa2aec4391393e4e81f4d7e24f18c33 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Sun, 23 Oct 2022 16:34:37 -0400 Subject: [PATCH 07/52] signed extrinsics for referenda precompile --- precompiles/referenda/Cargo.toml | 1 - precompiles/referenda/src/lib.rs | 35 +++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/precompiles/referenda/Cargo.toml b/precompiles/referenda/Cargo.toml index e8d65b49d0..1f25ff237a 100644 --- a/precompiles/referenda/Cargo.toml +++ b/precompiles/referenda/Cargo.toml @@ -35,7 +35,6 @@ sha3 = "0.9" # Moonbeam precompile-utils = { path = "../utils", features = [ "testing" ] } -# add pallet-governance-origins # Substrate pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index d60e02c9b3..54c4df9314 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -78,11 +78,12 @@ where at: bool, block_number: u32, ) -> EvmResult { - let proposal_origin: pallet_governance_origins::Origin = - proposal_origin.try_into().expect("track dne for origin"); + let proposal_origin: pallet_governance_origins::Origin = proposal_origin + .try_into() + .map_err(|_| revert("Origin does not exist for u8"))?; let proposal_hash: Runtime::Hash = proposal_hash .try_into() - .map_err(|_| revert("Proposal hash input not H256"))?; + .map_err(|_| revert("Proposal hash input is not H256"))?; let enactment_moment: DispatchTime = if at { DispatchTime::At(block_number.into()) } else { @@ -102,4 +103,32 @@ where Ok(()) } + + /// Post the Decision Deposit for a referendum. + /// + /// Parameters: + /// * index: The index of the submitted referendum whose Decision Deposit is yet to be posted. + #[precompile::public("placeDecisionDeposit(uint32)")] + fn place_decision_deposit(handle: &mut impl PrecompileHandle, index: u32) -> EvmResult { + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let call = ReferendaCall::::place_decision_deposit { index }.into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + Ok(()) + } + + /// Refund the Decision Deposit for a closed referendum back to the depositor. + /// + /// Parameters: + /// * index: The index of a closed referendum whose Decision Deposit has not yet been refunded. + #[precompile::public("refundDecisionDeposit(uint32)")] + fn refund_decision_deposit(handle: &mut impl PrecompileHandle, index: u32) -> EvmResult { + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let call = ReferendaCall::::refund_decision_deposit { index }.into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + Ok(()) + } } From 0eb6dc3bdebad36fcf97f0f97a5a8b2f523d24c0 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Sun, 23 Oct 2022 21:15:12 -0400 Subject: [PATCH 08/52] preimage precompile --- Cargo.lock | 28 ++++++++++ Cargo.toml | 1 + precompiles/preimage/Cargo.toml | 59 ++++++++++++++++++++ precompiles/preimage/src/lib.rs | 98 +++++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 precompiles/preimage/Cargo.toml create mode 100644 precompiles/preimage/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 720c27f114..78e1392424 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7235,6 +7235,34 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-evm-precompile-preimage" +version = "0.1.0" +dependencies = [ + "derive_more", + "fp-evm", + "frame-support", + "frame-system", + "hex-literal", + "log", + "num_enum", + "pallet-balances", + "pallet-evm", + "pallet-governance-origins", + "pallet-preimage", + "pallet-timestamp", + "parity-scale-codec", + "precompile-utils", + "rustc-hex", + "scale-info", + "serde", + "sha3 0.9.1", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-evm-precompile-proxy" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 5277e3b992..ad8e6df34d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ members = [ "precompiles/crowdloan-rewards", "precompiles/pallet-democracy", "precompiles/parachain-staking", + "precompiles/preimage", "precompiles/proxy", "precompiles/randomness", "precompiles/referenda", diff --git a/precompiles/preimage/Cargo.toml b/precompiles/preimage/Cargo.toml new file mode 100644 index 0000000000..803733457d --- /dev/null +++ b/precompiles/preimage/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "pallet-evm-precompile-preimage" +authors = [ "PureStake" ] +description = "A Precompile to make pallet-preimage calls encoding accessible to pallet-evm" +edition = "2021" +version = "0.1.0" + +[dependencies] +log = "0.4" +num_enum = { version = "0.5.3", default-features = false } +rustc-hex = { version = "2.0.1", default-features = false } + +# Moonbeam +precompile-utils = { path = "../utils", default-features = false } +pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } + +# Substrate +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } +sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } + +# Frontier +fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false, features = [ "forbid-evm-reentrancy" ] } + +[dev-dependencies] +derive_more = "0.99" +hex-literal = "0.3.3" +serde = "1.0.100" +sha3 = "0.9" + +# Moonbeam +precompile-utils = { path = "../utils", features = [ "testing" ] } + +# Substrate +pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } +sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } + +[features] +default = [ "std" ] +std = [ + "fp-evm/std", + "frame-support/std", + "frame-system/std", + "pallet-evm/std", + "pallet-governance-origins/std", + "pallet-preimage/std", + "parity-scale-codec/std", + "parity-scale-codec/std", + "precompile-utils/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs new file mode 100644 index 0000000000..c92146b2e9 --- /dev/null +++ b/precompiles/preimage/src/lib.rs @@ -0,0 +1,98 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![feature(assert_matches)] + +use fp_evm::PrecompileHandle; +use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; +use pallet_evm::AddressMapping; +use pallet_preimage::Call as PreimageCall; +use precompile_utils::prelude::*; +use sp_core::H256; +use sp_std::marker::PhantomData; + +// #[cfg(test)] +// mod mock; +// #[cfg(test)] +// mod tests; + +/// A precompile to wrap the functionality from pallet-preimage. +pub struct PreimagePrecompile(PhantomData); + +#[precompile_utils::precompile] +impl PreimagePrecompile +where + Runtime: pallet_preimage::Config + pallet_evm::Config + frame_system::Config, + ::Hash: TryFrom, + ::Call: + Dispatchable + GetDispatchInfo, + <::Call as Dispatchable>::Origin: + From>, + ::Call: From>, +{ + #[precompile::pre_check] + fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let caller_code = pallet_evm::Pallet::::account_codes(handle.context().caller); + // Check that caller is not a smart contract s.t. no code is inserted into + // pallet_evm::AccountCodes except if the caller is another precompile i.e. CallPermit + // TODO: review if this is necessary + if !(caller_code.is_empty() || &caller_code == &[0x60, 0x00, 0x60, 0x00, 0xfd]) { + Err(revert("Preimage not callable by smart contracts")) + } else { + Ok(()) + } + } + + /// Register a preimage on-chain. + /// + /// Parameters: + /// * bytes: The preimage registered on-chain + #[precompile::public("notePreimage(bytes32)")] + fn note_preimage(handle: &mut impl PrecompileHandle, bytes: H256) -> EvmResult { + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let call = PreimageCall::::note_preimage { + bytes: bytes.0.to_vec(), + } + .into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + /// Clear an unrequested preimage from the runtime storage. + /// + /// Parameters: + /// * hash: The preimage cleared from the runtime storage + #[precompile::public("unnotePreimage(bytes32)")] + fn unnote_preimage(handle: &mut impl PrecompileHandle, hash: H256) -> EvmResult { + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let call = PreimageCall::::unnote_preimage { + hash: hash + .try_into() + .map_err(|_| revert("H256 is Runtime::Hash"))?, + } + .into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } +} From 09e90dbc537dd23080d844407696eae129e1a1f5 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Mon, 24 Oct 2022 14:11:32 -0400 Subject: [PATCH 09/52] init conviction voting precompile --- Cargo.lock | 28 ++++++ Cargo.toml | 1 + precompiles/conviction-voting/Cargo.toml | 59 +++++++++++ precompiles/conviction-voting/src/lib.rs | 120 +++++++++++++++++++++++ precompiles/preimage/src/lib.rs | 14 --- precompiles/referenda/src/lib.rs | 14 --- 6 files changed, 208 insertions(+), 28 deletions(-) create mode 100644 precompiles/conviction-voting/Cargo.toml create mode 100644 precompiles/conviction-voting/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 78e1392424..ebf963ad5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7133,6 +7133,34 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-evm-precompile-conviction-voting" +version = "0.1.0" +dependencies = [ + "derive_more", + "fp-evm", + "frame-support", + "frame-system", + "hex-literal", + "log", + "num_enum", + "pallet-balances", + "pallet-conviction-voting", + "pallet-evm", + "pallet-governance-origins", + "pallet-timestamp", + "parity-scale-codec", + "precompile-utils", + "rustc-hex", + "scale-info", + "serde", + "sha3 0.9.1", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-evm-precompile-crowdloan-rewards" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index ad8e6df34d..1a54d23e4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ "precompiles/batch", "precompiles/call-permit", "precompiles/collective", + "precompiles/conviction-voting", "precompiles/crowdloan-rewards", "precompiles/pallet-democracy", "precompiles/parachain-staking", diff --git a/precompiles/conviction-voting/Cargo.toml b/precompiles/conviction-voting/Cargo.toml new file mode 100644 index 0000000000..ee8b084647 --- /dev/null +++ b/precompiles/conviction-voting/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "pallet-evm-precompile-conviction-voting" +authors = [ "PureStake" ] +description = "A Precompile to make pallet-conviction-voting calls encoding accessible to pallet-evm" +edition = "2021" +version = "0.1.0" + +[dependencies] +log = "0.4" +num_enum = { version = "0.5.3", default-features = false } +rustc-hex = { version = "2.0.1", default-features = false } + +# Moonbeam +precompile-utils = { path = "../utils", default-features = false } +pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } + +# Substrate +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +pallet-conviction-voting = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } +sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } + +# Frontier +fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false, features = [ "forbid-evm-reentrancy" ] } + +[dev-dependencies] +derive_more = "0.99" +hex-literal = "0.3.3" +serde = "1.0.100" +sha3 = "0.9" + +# Moonbeam +precompile-utils = { path = "../utils", features = [ "testing" ] } + +# Substrate +pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } +sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } + +[features] +default = [ "std" ] +std = [ + "fp-evm/std", + "frame-support/std", + "frame-system/std", + "pallet-evm/std", + "pallet-governance-origins/std", + "pallet-conviction-voting/std", + "parity-scale-codec/std", + "parity-scale-codec/std", + "precompile-utils/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs new file mode 100644 index 0000000000..930f5a5340 --- /dev/null +++ b/precompiles/conviction-voting/src/lib.rs @@ -0,0 +1,120 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] +#![feature(assert_matches)] + +use fp_evm::PrecompileHandle; +use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::{Currency, Polling}; +use pallet_conviction_voting::Call as ConvictionVotingCall; +use pallet_conviction_voting::{AccountVote, Conviction, Tally, Vote}; +use pallet_evm::AddressMapping; +use precompile_utils::prelude::*; +use sp_core::{H256, U256}; +use sp_std::marker::PhantomData; + +// #[cfg(test)] +// mod mock; +// #[cfg(test)] +// mod tests; + +type BalanceOf = <::Currency as Currency< + ::AccountId, +>>::Balance; + +/// A precompile to wrap the functionality from pallet-conviction-voting. +pub struct ConvictionVotingPrecompile(PhantomData); + +#[precompile_utils::precompile] +impl ConvictionVotingPrecompile +where + Runtime: pallet_conviction_voting::Config + pallet_evm::Config + frame_system::Config, + BalanceOf: TryFrom, + ::Hash: TryFrom, + ::Call: + Dispatchable + GetDispatchInfo, + <::Call as Dispatchable>::Origin: + From>, + ::Call: From>, + <::Polls as Polling< + Tally< + <::Currency as Currency< + ::AccountId, + >>::Balance, + ::MaxTurnout, + >, + >>::Index: TryFrom, +{ + /// Vote in a poll. + /// + /// Parameters: + /// * poll_index: Index of poll + /// * aye: Yes or no vote + /// * vote_amount: Balance locked for vote + /// * conviction: Conviction multiplier for length of vote lock + #[precompile::public("standardVote(uint256,bool,uint256,uint256)")] + fn standard_vote( + handle: &mut impl PrecompileHandle, + poll_index: SolidityConvert, + aye: bool, + vote_amount: U256, + conviction: SolidityConvert, + ) -> EvmResult { + let poll_index = poll_index.converted(); + let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; + + let conviction: Conviction = conviction.converted().try_into().map_err(|_| { + RevertReason::custom("Must be an integer between 0 and 6 included") + .in_field("conviction") + })?; + + let vote = AccountVote::Standard { + vote: Vote { aye, conviction }, + balance: vote_amount, + }; + + log::trace!(target: "conviction-voting-precompile", + "Voting {:?} on poll #{:?}, with conviction {:?}", + aye, poll_index, conviction + ); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::vote { + poll_index: poll_index + .try_into() + .map_err(|_| revert("Poll index does not match type"))?, + vote, + } + .into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + // TODO + // * delegate + // * undelegate + // * unlock + // * remove_vote + // * remove_other_vote + + fn u256_to_amount(value: U256) -> MayRevert> { + value + .try_into() + .map_err(|_| RevertReason::value_is_too_large("balance type").into()) + } +} diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index c92146b2e9..5ccd0f41fb 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -44,20 +44,6 @@ where From>, ::Call: From>, { - #[precompile::pre_check] - fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let caller_code = pallet_evm::Pallet::::account_codes(handle.context().caller); - // Check that caller is not a smart contract s.t. no code is inserted into - // pallet_evm::AccountCodes except if the caller is another precompile i.e. CallPermit - // TODO: review if this is necessary - if !(caller_code.is_empty() || &caller_code == &[0x60, 0x00, 0x60, 0x00, 0xfd]) { - Err(revert("Preimage not callable by smart contracts")) - } else { - Ok(()) - } - } - /// Register a preimage on-chain. /// /// Parameters: diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 54c4df9314..152bb24ee7 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -49,20 +49,6 @@ where From>, ::Call: From>, { - #[precompile::pre_check] - fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { - handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let caller_code = pallet_evm::Pallet::::account_codes(handle.context().caller); - // Check that caller is not a smart contract s.t. no code is inserted into - // pallet_evm::AccountCodes except if the caller is another precompile i.e. CallPermit - // TODO: review if this is necessary - if !(caller_code.is_empty() || &caller_code == &[0x60, 0x00, 0x60, 0x00, 0xfd]) { - Err(revert("Referenda not callable by smart contracts")) - } else { - Ok(()) - } - } - /// Propose a referendum on a privileged action. /// /// Parameters: From 138a8484d5e9e11c028f895e367815a1ed040f3f Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 25 Oct 2022 14:33:55 -0400 Subject: [PATCH 10/52] referenda delegate undelegate unlock --- precompiles/conviction-voting/Cargo.toml | 6 +- precompiles/conviction-voting/src/lib.rs | 195 ++++++++++++++++++++++- precompiles/preimage/Cargo.toml | 4 +- precompiles/referenda/Cargo.toml | 4 +- 4 files changed, 194 insertions(+), 15 deletions(-) diff --git a/precompiles/conviction-voting/Cargo.toml b/precompiles/conviction-voting/Cargo.toml index ee8b084647..5f8f1540c1 100644 --- a/precompiles/conviction-voting/Cargo.toml +++ b/precompiles/conviction-voting/Cargo.toml @@ -11,8 +11,8 @@ num_enum = { version = "0.5.3", default-features = false } rustc-hex = { version = "2.0.1", default-features = false } # Moonbeam -precompile-utils = { path = "../utils", default-features = false } pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } +precompile-utils = { path = "../utils", default-features = false } # Substrate frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } @@ -48,9 +48,9 @@ std = [ "fp-evm/std", "frame-support/std", "frame-system/std", - "pallet-evm/std", - "pallet-governance-origins/std", "pallet-conviction-voting/std", + "pallet-evm/std", + "pallet-governance-origins/std", "parity-scale-codec/std", "parity-scale-codec/std", "precompile-utils/std", diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 930f5a5340..9408732818 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -24,7 +24,8 @@ use pallet_conviction_voting::Call as ConvictionVotingCall; use pallet_conviction_voting::{AccountVote, Conviction, Tally, Vote}; use pallet_evm::AddressMapping; use precompile_utils::prelude::*; -use sp_core::{H256, U256}; +use sp_core::{H160, H256, U256}; +use sp_runtime::traits::StaticLookup; use sp_std::marker::PhantomData; // #[cfg(test)] @@ -58,6 +59,14 @@ where ::MaxTurnout, >, >>::Index: TryFrom, + <::Polls as Polling< + Tally< + <::Currency as Currency< + ::AccountId, + >>::Balance, + ::MaxTurnout, + >, + >>::Class: TryFrom, { /// Vote in a poll. /// @@ -88,7 +97,7 @@ where }; log::trace!(target: "conviction-voting-precompile", - "Voting {:?} on poll #{:?}, with conviction {:?}", + "Voting {:?} on poll {:?}, with conviction {:?}", aye, poll_index, conviction ); @@ -105,13 +114,183 @@ where Ok(()) } - // TODO - // * delegate - // * undelegate - // * unlock - // * remove_vote - // * remove_other_vote + #[precompile::public("removeVote(uint256)")] + fn remove_vote( + handle: &mut impl PrecompileHandle, + poll_index: SolidityConvert, + ) -> EvmResult { + let poll_index: u32 = poll_index.converted(); + + log::trace!( + target: "conviction-voting-precompile", + "Removing vote from poll {:?}", + poll_index + ); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::remove_vote { + class: None, + index: poll_index + .try_into() + .map_err(|_| revert("Poll index does not match type"))?, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + #[precompile::public("removeVoteForClass(uint256,uint256)")] + fn remove_vote_for_class( + handle: &mut impl PrecompileHandle, + class: SolidityConvert, + poll_index: SolidityConvert, + ) -> EvmResult { + let class: u16 = class.converted(); + let poll_index: u32 = poll_index.converted(); + + log::trace!( + target: "conviction-voting-precompile", + "Removing vote from poll {:?}", + poll_index + ); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::remove_vote { + class: Some( + class + .try_into() + .map_err(|_| revert("Class does not match type"))?, + ), + index: poll_index + .try_into() + .map_err(|_| revert("Poll index does not match type"))?, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + #[precompile::public("removeOtherVote(address,uint256,uint256)")] + fn remove_other_vote( + handle: &mut impl PrecompileHandle, + target: Address, + class: SolidityConvert, + poll_index: SolidityConvert, + ) -> EvmResult { + let class: u16 = class.converted(); + let poll_index: u32 = poll_index.converted(); + + let target = Runtime::AddressMapping::into_account_id(target.into()); + let target: ::Source = + Runtime::Lookup::unlookup(target.clone()); + + log::trace!( + target: "conviction-voting-precompile", + "Removing other vote from poll {:?}", + poll_index + ); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::remove_other_vote { + target, + class: class + .try_into() + .map_err(|_| revert("Class does not match type"))?, + index: poll_index + .try_into() + .map_err(|_| revert("Poll index does not match type"))?, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + #[precompile::public("delegate(uint256,address,uint256,uint256)")] + fn delegate( + handle: &mut impl PrecompileHandle, + class: SolidityConvert, + representative: Address, + conviction: SolidityConvert, + amount: U256, + ) -> EvmResult { + let class = class.converted(); + let amount = Self::u256_to_amount(amount).in_field("amount")?; + + let conviction: Conviction = conviction.converted().try_into().map_err(|_| { + RevertReason::custom("Must be an integer between 0 and 6 included") + .in_field("conviction") + })?; + + log::trace!(target: "conviction-voting-precompile", + "Delegating vote to {:?} with balance {:?} and {:?}", + representative, conviction, amount + ); + + let representative = Runtime::AddressMapping::into_account_id(representative.into()); + let to: ::Source = + Runtime::Lookup::unlookup(representative.clone()); + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::delegate { + class: class + .try_into() + .map_err(|_| revert("Class does not match type"))?, + to, + conviction, + balance: amount, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + #[precompile::public("unDelegate(uint256)")] + fn undelegate( + handle: &mut impl PrecompileHandle, + class: SolidityConvert, + ) -> EvmResult { + let class = class.converted(); + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::undelegate { + class: class + .try_into() + .map_err(|_| revert("Class does not match type"))?, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + #[precompile::public("unlock(uint256,address)")] + fn unlock( + handle: &mut impl PrecompileHandle, + class: SolidityConvert, + target: Address, + ) -> EvmResult { + let class = class.converted(); + let target: H160 = target.into(); + let target = Runtime::AddressMapping::into_account_id(target); + let target: ::Source = + Runtime::Lookup::unlookup(target.clone()); + + log::trace!( + target: "democracy-precompile", + "Unlocking democracy tokens for {:?}", target + ); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::unlock { + class: class + .try_into() + .map_err(|_| revert("Class does not match type"))?, + target, + }; + + RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } fn u256_to_amount(value: U256) -> MayRevert> { value .try_into() diff --git a/precompiles/preimage/Cargo.toml b/precompiles/preimage/Cargo.toml index 803733457d..f848f3448e 100644 --- a/precompiles/preimage/Cargo.toml +++ b/precompiles/preimage/Cargo.toml @@ -11,8 +11,8 @@ num_enum = { version = "0.5.3", default-features = false } rustc-hex = { version = "2.0.1", default-features = false } # Moonbeam -precompile-utils = { path = "../utils", default-features = false } pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } +precompile-utils = { path = "../utils", default-features = false } # Substrate frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } @@ -49,7 +49,7 @@ std = [ "frame-support/std", "frame-system/std", "pallet-evm/std", - "pallet-governance-origins/std", + "pallet-governance-origins/std", "pallet-preimage/std", "parity-scale-codec/std", "parity-scale-codec/std", diff --git a/precompiles/referenda/Cargo.toml b/precompiles/referenda/Cargo.toml index 1f25ff237a..f49b9e2cf0 100644 --- a/precompiles/referenda/Cargo.toml +++ b/precompiles/referenda/Cargo.toml @@ -11,8 +11,8 @@ num_enum = { version = "0.5.3", default-features = false } rustc-hex = { version = "2.0.1", default-features = false } # Moonbeam -precompile-utils = { path = "../utils", default-features = false } pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } +precompile-utils = { path = "../utils", default-features = false } # Substrate frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } @@ -49,7 +49,7 @@ std = [ "frame-support/std", "frame-system/std", "pallet-evm/std", - "pallet-governance-origins/std", + "pallet-governance-origins/std", "pallet-referenda/std", "parity-scale-codec/std", "parity-scale-codec/std", From 8e1a7097fcc5fc96a349fff37747b3a69511b7e5 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 26 Oct 2022 10:17:11 -0400 Subject: [PATCH 11/52] fixes --- precompiles/conviction-voting/src/lib.rs | 34 +++++++++++++----------- precompiles/preimage/src/lib.rs | 15 +++++++---- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 9408732818..7bc7a651f7 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -36,6 +36,22 @@ use sp_std::marker::PhantomData; type BalanceOf = <::Currency as Currency< ::AccountId, >>::Balance; +type IndexOf = <::Polls as Polling< + Tally< + <::Currency as Currency< + ::AccountId, + >>::Balance, + ::MaxTurnout, + >, +>>::Index; +type ClassOf = <::Polls as Polling< + Tally< + <::Currency as Currency< + ::AccountId, + >>::Balance, + ::MaxTurnout, + >, +>>::Class; /// A precompile to wrap the functionality from pallet-conviction-voting. pub struct ConvictionVotingPrecompile(PhantomData); @@ -51,22 +67,8 @@ where <::Call as Dispatchable>::Origin: From>, ::Call: From>, - <::Polls as Polling< - Tally< - <::Currency as Currency< - ::AccountId, - >>::Balance, - ::MaxTurnout, - >, - >>::Index: TryFrom, - <::Polls as Polling< - Tally< - <::Currency as Currency< - ::AccountId, - >>::Balance, - ::MaxTurnout, - >, - >>::Class: TryFrom, + IndexOf: TryFrom, + ClassOf: TryFrom, { /// Vote in a poll. /// diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index 5ccd0f41fb..0f53b3cb28 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -19,6 +19,7 @@ use fp_evm::PrecompileHandle; use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::ConstU32; use pallet_evm::AddressMapping; use pallet_preimage::Call as PreimageCall; use precompile_utils::prelude::*; @@ -30,6 +31,9 @@ use sp_std::marker::PhantomData; // #[cfg(test)] // mod tests; +pub const ENCODED_PROPOSAL_SIZE_LIMIT: u32 = 2u32.pow(16); +type GetEncodedProposalSizeLimit = ConstU32; + /// A precompile to wrap the functionality from pallet-preimage. pub struct PreimagePrecompile(PhantomData); @@ -49,13 +53,14 @@ where /// Parameters: /// * bytes: The preimage registered on-chain #[precompile::public("notePreimage(bytes32)")] - fn note_preimage(handle: &mut impl PrecompileHandle, bytes: H256) -> EvmResult { + fn note_preimage( + handle: &mut impl PrecompileHandle, + encoded_proposal: BoundedBytes, + ) -> EvmResult { + let bytes = encoded_proposal.into(); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = PreimageCall::::note_preimage { - bytes: bytes.0.to_vec(), - } - .into(); + let call = PreimageCall::::note_preimage { bytes }.into(); >::try_dispatch(handle, Some(origin).into(), call)?; From 276d8a47716b0630c4755cb435d71f5a692e9d51 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 26 Oct 2022 10:59:26 -0400 Subject: [PATCH 12/52] fix --- precompiles/preimage/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index 0f53b3cb28..457e87aed1 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -52,7 +52,7 @@ where /// /// Parameters: /// * bytes: The preimage registered on-chain - #[precompile::public("notePreimage(bytes32)")] + #[precompile::public("notePreimage(bytes)")] fn note_preimage( handle: &mut impl PrecompileHandle, encoded_proposal: BoundedBytes, From a940199cd35391c8c70badf6f477ca6cdfa888ff Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 26 Oct 2022 11:17:48 -0400 Subject: [PATCH 13/52] clean --- precompiles/conviction-voting/src/lib.rs | 104 +++++++++++------------ precompiles/preimage/src/lib.rs | 10 +-- precompiles/referenda/src/lib.rs | 10 ++- 3 files changed, 59 insertions(+), 65 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 7bc7a651f7..1a9e56a6d5 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -85,7 +85,10 @@ where vote_amount: U256, conviction: SolidityConvert, ) -> EvmResult { - let poll_index = poll_index.converted(); + let poll_index: IndexOf = poll_index + .converted() + .try_into() + .map_err(|_| revert("Poll index does not match type"))?; let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; let conviction: Conviction = conviction.converted().try_into().map_err(|_| { @@ -104,13 +107,7 @@ where ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::vote { - poll_index: poll_index - .try_into() - .map_err(|_| revert("Poll index does not match type"))?, - vote, - } - .into(); + let call = ConvictionVotingCall::::vote { poll_index, vote }.into(); >::try_dispatch(handle, Some(origin).into(), call)?; @@ -122,21 +119,19 @@ where handle: &mut impl PrecompileHandle, poll_index: SolidityConvert, ) -> EvmResult { - let poll_index: u32 = poll_index.converted(); + let index: IndexOf = poll_index + .converted() + .try_into() + .map_err(|_| revert("Poll index does not match type"))?; log::trace!( target: "conviction-voting-precompile", "Removing vote from poll {:?}", - poll_index + index ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::remove_vote { - class: None, - index: poll_index - .try_into() - .map_err(|_| revert("Poll index does not match type"))?, - }; + let call = ConvictionVotingCall::::remove_vote { class: None, index }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -149,26 +144,25 @@ where class: SolidityConvert, poll_index: SolidityConvert, ) -> EvmResult { - let class: u16 = class.converted(); - let poll_index: u32 = poll_index.converted(); + let class: Option> = Some( + class + .converted() + .try_into() + .map_err(|_| revert("Class does not match type"))?, + ); + let index: IndexOf = poll_index + .converted() + .try_into() + .map_err(|_| revert("Poll index does not match type"))?; log::trace!( target: "conviction-voting-precompile", "Removing vote from poll {:?}", - poll_index + index ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::remove_vote { - class: Some( - class - .try_into() - .map_err(|_| revert("Class does not match type"))?, - ), - index: poll_index - .try_into() - .map_err(|_| revert("Poll index does not match type"))?, - }; + let call = ConvictionVotingCall::::remove_vote { class, index }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -181,8 +175,14 @@ where class: SolidityConvert, poll_index: SolidityConvert, ) -> EvmResult { - let class: u16 = class.converted(); - let poll_index: u32 = poll_index.converted(); + let class: ClassOf = class + .converted() + .try_into() + .map_err(|_| revert("Class does not match type"))?; + let index: IndexOf = poll_index + .converted() + .try_into() + .map_err(|_| revert("Poll index does not match type"))?; let target = Runtime::AddressMapping::into_account_id(target.into()); let target: ::Source = @@ -191,18 +191,14 @@ where log::trace!( target: "conviction-voting-precompile", "Removing other vote from poll {:?}", - poll_index + index ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ConvictionVotingCall::::remove_other_vote { target, - class: class - .try_into() - .map_err(|_| revert("Class does not match type"))?, - index: poll_index - .try_into() - .map_err(|_| revert("Poll index does not match type"))?, + class, + index, }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -217,7 +213,10 @@ where conviction: SolidityConvert, amount: U256, ) -> EvmResult { - let class = class.converted(); + let class: ClassOf = class + .converted() + .try_into() + .map_err(|_| revert("Class does not match type"))?; let amount = Self::u256_to_amount(amount).in_field("amount")?; let conviction: Conviction = conviction.converted().try_into().map_err(|_| { @@ -235,9 +234,7 @@ where Runtime::Lookup::unlookup(representative.clone()); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ConvictionVotingCall::::delegate { - class: class - .try_into() - .map_err(|_| revert("Class does not match type"))?, + class, to, conviction, balance: amount, @@ -252,13 +249,12 @@ where handle: &mut impl PrecompileHandle, class: SolidityConvert, ) -> EvmResult { - let class = class.converted(); + let class: ClassOf = class + .converted() + .try_into() + .map_err(|_| revert("Class does not match type"))?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::undelegate { - class: class - .try_into() - .map_err(|_| revert("Class does not match type"))?, - }; + let call = ConvictionVotingCall::::undelegate { class }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; @@ -270,7 +266,10 @@ where class: SolidityConvert, target: Address, ) -> EvmResult { - let class = class.converted(); + let class: ClassOf = class + .converted() + .try_into() + .map_err(|_| revert("Class does not match type"))?; let target: H160 = target.into(); let target = Runtime::AddressMapping::into_account_id(target); let target: ::Source = @@ -282,12 +281,7 @@ where ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::unlock { - class: class - .try_into() - .map_err(|_| revert("Class does not match type"))?, - target, - }; + let call = ConvictionVotingCall::::unlock { class, target }; RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index 457e87aed1..34a9fb16e6 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -73,14 +73,12 @@ where /// * hash: The preimage cleared from the runtime storage #[precompile::public("unnotePreimage(bytes32)")] fn unnote_preimage(handle: &mut impl PrecompileHandle, hash: H256) -> EvmResult { + let hash: Runtime::Hash = hash + .try_into() + .map_err(|_| revert("H256 is Runtime::Hash"))?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = PreimageCall::::unnote_preimage { - hash: hash - .try_into() - .map_err(|_| revert("H256 is Runtime::Hash"))?, - } - .into(); + let call = PreimageCall::::unnote_preimage { hash }.into(); >::try_dispatch(handle, Some(origin).into(), call)?; diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 152bb24ee7..071ebdfaae 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -31,6 +31,8 @@ use sp_std::marker::PhantomData; // #[cfg(test)] // mod tests; +type OriginOf = <::Origin as OriginTrait>::PalletsOrigin; + /// A precompile to wrap the functionality from pallet-referenda. pub struct ReferendaPrecompile(PhantomData); @@ -40,8 +42,7 @@ where Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, <::Call as Dispatchable>::Origin: From>, - <::Origin as OriginTrait>::PalletsOrigin: - From, + OriginOf: From, ::Hash: TryFrom, ::Call: Dispatchable + GetDispatchInfo, @@ -64,9 +65,10 @@ where at: bool, block_number: u32, ) -> EvmResult { - let proposal_origin: pallet_governance_origins::Origin = proposal_origin + let gov_origin: pallet_governance_origins::Origin = proposal_origin .try_into() .map_err(|_| revert("Origin does not exist for u8"))?; + let proposal_origin: Box> = Box::new(gov_origin.into()); let proposal_hash: Runtime::Hash = proposal_hash .try_into() .map_err(|_| revert("Proposal hash input is not H256"))?; @@ -79,7 +81,7 @@ where let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ReferendaCall::::submit { - proposal_origin: Box::new(proposal_origin.into()), + proposal_origin, proposal_hash, enactment_moment, } From a9ab0e3745c24b02c7e16872bc74aa75f02685ab Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 26 Oct 2022 12:04:37 -0400 Subject: [PATCH 14/52] improve revert reasons for class and index inputs --- precompiles/conviction-voting/src/lib.rs | 46 +++++++++++------------- precompiles/preimage/src/lib.rs | 2 +- precompiles/referenda/src/lib.rs | 13 +++---- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 1a9e56a6d5..79baed0e82 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -85,10 +85,9 @@ where vote_amount: U256, conviction: SolidityConvert, ) -> EvmResult { - let poll_index: IndexOf = poll_index - .converted() - .try_into() - .map_err(|_| revert("Poll index does not match type"))?; + let poll_index: IndexOf = poll_index.converted().try_into().map_err(|_| { + RevertReason::custom("Poll index does not match type").in_field("poll_index") + })?; let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; let conviction: Conviction = conviction.converted().try_into().map_err(|_| { @@ -119,10 +118,9 @@ where handle: &mut impl PrecompileHandle, poll_index: SolidityConvert, ) -> EvmResult { - let index: IndexOf = poll_index - .converted() - .try_into() - .map_err(|_| revert("Poll index does not match type"))?; + let index: IndexOf = poll_index.converted().try_into().map_err(|_| { + RevertReason::custom("Poll index does not match type").in_field("index") + })?; log::trace!( target: "conviction-voting-precompile", @@ -144,16 +142,13 @@ where class: SolidityConvert, poll_index: SolidityConvert, ) -> EvmResult { - let class: Option> = Some( - class - .converted() - .try_into() - .map_err(|_| revert("Class does not match type"))?, - ); - let index: IndexOf = poll_index - .converted() - .try_into() - .map_err(|_| revert("Poll index does not match type"))?; + let class: Option> = + Some(class.converted().try_into().map_err(|_| { + RevertReason::custom("Class does not match type").in_field("class") + })?); + let index: IndexOf = poll_index.converted().try_into().map_err(|_| { + RevertReason::custom("Poll index does not match type").in_field("index") + })?; log::trace!( target: "conviction-voting-precompile", @@ -178,11 +173,10 @@ where let class: ClassOf = class .converted() .try_into() - .map_err(|_| revert("Class does not match type"))?; - let index: IndexOf = poll_index - .converted() - .try_into() - .map_err(|_| revert("Poll index does not match type"))?; + .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; + let index: IndexOf = poll_index.converted().try_into().map_err(|_| { + RevertReason::custom("Poll index does not match type").in_field("index") + })?; let target = Runtime::AddressMapping::into_account_id(target.into()); let target: ::Source = @@ -216,7 +210,7 @@ where let class: ClassOf = class .converted() .try_into() - .map_err(|_| revert("Class does not match type"))?; + .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; let amount = Self::u256_to_amount(amount).in_field("amount")?; let conviction: Conviction = conviction.converted().try_into().map_err(|_| { @@ -252,7 +246,7 @@ where let class: ClassOf = class .converted() .try_into() - .map_err(|_| revert("Class does not match type"))?; + .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ConvictionVotingCall::::undelegate { class }; @@ -269,7 +263,7 @@ where let class: ClassOf = class .converted() .try_into() - .map_err(|_| revert("Class does not match type"))?; + .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; let target: H160 = target.into(); let target = Runtime::AddressMapping::into_account_id(target); let target: ::Source = diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index 34a9fb16e6..b7b9a66831 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -75,7 +75,7 @@ where fn unnote_preimage(handle: &mut impl PrecompileHandle, hash: H256) -> EvmResult { let hash: Runtime::Hash = hash .try_into() - .map_err(|_| revert("H256 is Runtime::Hash"))?; + .map_err(|_| RevertReason::custom("H256 is Runtime::Hash").in_field("hash"))?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = PreimageCall::::unnote_preimage { hash }.into(); diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 071ebdfaae..73f949911a 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -65,13 +65,14 @@ where at: bool, block_number: u32, ) -> EvmResult { - let gov_origin: pallet_governance_origins::Origin = proposal_origin - .try_into() - .map_err(|_| revert("Origin does not exist for u8"))?; + let gov_origin: pallet_governance_origins::Origin = + proposal_origin.try_into().map_err(|_| { + RevertReason::custom("Origin does not exist for u8").in_field("proposal_origin") + })?; let proposal_origin: Box> = Box::new(gov_origin.into()); - let proposal_hash: Runtime::Hash = proposal_hash - .try_into() - .map_err(|_| revert("Proposal hash input is not H256"))?; + let proposal_hash: Runtime::Hash = proposal_hash.try_into().map_err(|_| { + RevertReason::custom("Proposal hash input is not H256").in_field("proposal_hash") + })?; let enactment_moment: DispatchTime = if at { DispatchTime::At(block_number.into()) } else { From 9067ba05e2afe53a1eaf68ba72a1bc759879b238 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 26 Oct 2022 14:36:13 -0400 Subject: [PATCH 15/52] clean --- precompiles/conviction-voting/src/lib.rs | 58 ++++++++++-------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 79baed0e82..d998813d44 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -85,9 +85,7 @@ where vote_amount: U256, conviction: SolidityConvert, ) -> EvmResult { - let poll_index: IndexOf = poll_index.converted().try_into().map_err(|_| { - RevertReason::custom("Poll index does not match type").in_field("poll_index") - })?; + let poll_index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; let conviction: Conviction = conviction.converted().try_into().map_err(|_| { @@ -118,9 +116,7 @@ where handle: &mut impl PrecompileHandle, poll_index: SolidityConvert, ) -> EvmResult { - let index: IndexOf = poll_index.converted().try_into().map_err(|_| { - RevertReason::custom("Poll index does not match type").in_field("index") - })?; + let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; log::trace!( target: "conviction-voting-precompile", @@ -143,12 +139,8 @@ where poll_index: SolidityConvert, ) -> EvmResult { let class: Option> = - Some(class.converted().try_into().map_err(|_| { - RevertReason::custom("Class does not match type").in_field("class") - })?); - let index: IndexOf = poll_index.converted().try_into().map_err(|_| { - RevertReason::custom("Poll index does not match type").in_field("index") - })?; + Some(Self::u16_to_class(class.converted()).in_field("class")?); + let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; log::trace!( target: "conviction-voting-precompile", @@ -170,13 +162,8 @@ where class: SolidityConvert, poll_index: SolidityConvert, ) -> EvmResult { - let class: ClassOf = class - .converted() - .try_into() - .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; - let index: IndexOf = poll_index.converted().try_into().map_err(|_| { - RevertReason::custom("Poll index does not match type").in_field("index") - })?; + let class = Self::u16_to_class(class.converted()).in_field("class")?; + let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; let target = Runtime::AddressMapping::into_account_id(target.into()); let target: ::Source = @@ -207,10 +194,7 @@ where conviction: SolidityConvert, amount: U256, ) -> EvmResult { - let class: ClassOf = class - .converted() - .try_into() - .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; + let class = Self::u16_to_class(class.converted()).in_field("class")?; let amount = Self::u256_to_amount(amount).in_field("amount")?; let conviction: Conviction = conviction.converted().try_into().map_err(|_| { @@ -219,8 +203,8 @@ where })?; log::trace!(target: "conviction-voting-precompile", - "Delegating vote to {:?} with balance {:?} and {:?}", - representative, conviction, amount + "Delegating vote to {:?} with balance {:?} and conviction {:?}", + representative, amount, conviction ); let representative = Runtime::AddressMapping::into_account_id(representative.into()); @@ -243,10 +227,7 @@ where handle: &mut impl PrecompileHandle, class: SolidityConvert, ) -> EvmResult { - let class: ClassOf = class - .converted() - .try_into() - .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; + let class = Self::u16_to_class(class.converted()).in_field("class")?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ConvictionVotingCall::::undelegate { class }; @@ -260,18 +241,15 @@ where class: SolidityConvert, target: Address, ) -> EvmResult { - let class: ClassOf = class - .converted() - .try_into() - .map_err(|_| RevertReason::custom("Class does not match type").in_field("class"))?; + let class: ClassOf = Self::u16_to_class(class.converted()).in_field("class")?; let target: H160 = target.into(); let target = Runtime::AddressMapping::into_account_id(target); let target: ::Source = Runtime::Lookup::unlookup(target.clone()); log::trace!( - target: "democracy-precompile", - "Unlocking democracy tokens for {:?}", target + target: "conviction-voting-precompile", + "Unlocking conviction-voting tokens for {:?}", target ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -281,6 +259,16 @@ where Ok(()) } + fn u32_to_index(index: u32) -> MayRevert> { + index + .try_into() + .map_err(|_| RevertReason::value_is_too_large("index type").into()) + } + fn u16_to_class(class: u16) -> MayRevert> { + class + .try_into() + .map_err(|_| RevertReason::value_is_too_large("class type").into()) + } fn u256_to_amount(value: U256) -> MayRevert> { value .try_into() From 467e845e74e025e9a70c6e29099fe44bad0bbf65 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 3 Nov 2022 10:53:19 -0400 Subject: [PATCH 16/52] init accessors and clean --- precompiles/conviction-voting/src/lib.rs | 22 +++--- precompiles/referenda/src/lib.rs | 92 +++++++++++++++++++++++- 2 files changed, 98 insertions(+), 16 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index d998813d44..ca35887eb3 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -87,11 +87,7 @@ where ) -> EvmResult { let poll_index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; - - let conviction: Conviction = conviction.converted().try_into().map_err(|_| { - RevertReason::custom("Must be an integer between 0 and 6 included") - .in_field("conviction") - })?; + let conviction = Self::u8_to_conviction(conviction.converted()).in_field("conviction")?; let vote = AccountVote::Standard { vote: Vote { aye, conviction }, @@ -138,8 +134,7 @@ where class: SolidityConvert, poll_index: SolidityConvert, ) -> EvmResult { - let class: Option> = - Some(Self::u16_to_class(class.converted()).in_field("class")?); + let class = Some(Self::u16_to_class(class.converted()).in_field("class")?); let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; log::trace!( @@ -196,11 +191,7 @@ where ) -> EvmResult { let class = Self::u16_to_class(class.converted()).in_field("class")?; let amount = Self::u256_to_amount(amount).in_field("amount")?; - - let conviction: Conviction = conviction.converted().try_into().map_err(|_| { - RevertReason::custom("Must be an integer between 0 and 6 included") - .in_field("conviction") - })?; + let conviction = Self::u8_to_conviction(conviction.converted()).in_field("conviction")?; log::trace!(target: "conviction-voting-precompile", "Delegating vote to {:?} with balance {:?} and conviction {:?}", @@ -241,7 +232,7 @@ where class: SolidityConvert, target: Address, ) -> EvmResult { - let class: ClassOf = Self::u16_to_class(class.converted()).in_field("class")?; + let class = Self::u16_to_class(class.converted()).in_field("class")?; let target: H160 = target.into(); let target = Runtime::AddressMapping::into_account_id(target); let target: ::Source = @@ -259,6 +250,11 @@ where Ok(()) } + fn u8_to_conviction(conviction: u8) -> MayRevert { + conviction + .try_into() + .map_err(|_| RevertReason::custom("Must be an integer between 0 and 6 included").into()) + } fn u32_to_index(index: u32) -> MayRevert> { index .try_into() diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 73f949911a..227e8ff5e4 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -19,11 +19,13 @@ use fp_evm::PrecompileHandle; use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; -use frame_support::traits::{schedule::DispatchTime, OriginTrait}; +use frame_support::traits::{schedule::DispatchTime, Currency, OriginTrait}; use pallet_evm::AddressMapping; -use pallet_referenda::Call as ReferendaCall; +use pallet_referenda::{ + Call as ReferendaCall, DecidingCount, ReferendumCount, ReferendumInfoFor, TracksInfo, +}; use precompile_utils::prelude::*; -use sp_core::H256; +use sp_core::{H256, U256}; use sp_std::marker::PhantomData; // #[cfg(test)] @@ -31,6 +33,14 @@ use sp_std::marker::PhantomData; // #[cfg(test)] // mod tests; +type BalanceOf = <::Currency as Currency< + ::AccountId, +>>::Balance; +type TrackIdOf = <::Tracks as TracksInfo< + BalanceOf, + ::BlockNumber, +>>::Id; + type OriginOf = <::Origin as OriginTrait>::PalletsOrigin; /// A precompile to wrap the functionality from pallet-referenda. @@ -49,7 +59,83 @@ where <::Call as Dispatchable>::Origin: From>, ::Call: From>, + TrackIdOf: TryFrom, { + // The accessors are first. They directly return their result. + #[precompile::public("referendumCount()")] + #[precompile::view] + fn referendum_count(handle: &mut impl PrecompileHandle) -> EvmResult { + // Fetch data from pallet + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let ref_count = ReferendumCount::::get(); + log::trace!(target: "referendum-precompile", "Referendum count from pallet is {:?}", ref_count); + + Ok(ref_count.into()) + } + + #[precompile::public("decidingCount(uint256)")] + #[precompile::view] + fn deciding_count( + handle: &mut impl PrecompileHandle, + track_id: SolidityConvert, + ) -> EvmResult { + // Fetch data from pallet + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let track_id: TrackIdOf = track_id + .converted() + .try_into() + .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) + .in_field("track")?; + let deciding_count = DecidingCount::::get(track_id); + log::trace!( + target: "referendum-precompile", "Track {:?} deciding count is {:?}", + track_id, + deciding_count + ); + + Ok(deciding_count.into()) + } + + // #[precompile::public("referendumStatus(uint256)")] + // #[precompile::view] + // fn referendum_status( + // handle: &mut impl PrecompileHandle, + // ref_index: SolidityConvert, + // ) -> EvmResult { + // // Fetch data from pallet + // handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + // let referendum_info = ReferendumInfoFor::::get(ref_index.converted()); + // // log::trace!( + // // target: "referendum-precompile", "Track {:?} deciding count is {:?}", + // // track_id, + // // deciding_count + // // ); + + // // TODO: + // Ok(ref_index.into()) + // } + + // TODO: function per status variant + + #[precompile::public("ongoingReferendumInfoFor(uint256)")] + #[precompile::view] + fn ongoing_referendum_info( + handle: &mut impl PrecompileHandle, + ref_index: SolidityConvert, + ) -> EvmResult { + // Fetch data from pallet + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let referendum_info = ReferendumInfoFor::::get(ref_index.converted()); + // log::trace!( + // target: "referendum-precompile", "Track {:?} deciding count is {:?}", + // track_id, + // deciding_count + // ); + + // TODO: + Ok(ref_index.into()) + } + /// Propose a referendum on a privileged action. /// /// Parameters: From 4d8f70a6e8e5d2687bd70080957151a695ce6719 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 15 Nov 2022 22:09:31 -0500 Subject: [PATCH 17/52] referenda precompile --- precompiles/referenda/src/lib.rs | 78 ++++++++++++++++---------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 227e8ff5e4..e539f4310b 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -19,11 +19,9 @@ use fp_evm::PrecompileHandle; use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; -use frame_support::traits::{schedule::DispatchTime, Currency, OriginTrait}; +use frame_support::traits::{schedule::DispatchTime, Currency, Get, OriginTrait}; use pallet_evm::AddressMapping; -use pallet_referenda::{ - Call as ReferendaCall, DecidingCount, ReferendumCount, ReferendumInfoFor, TracksInfo, -}; +use pallet_referenda::{Call as ReferendaCall, DecidingCount, ReferendumCount, TracksInfo}; use precompile_utils::prelude::*; use sp_core::{H256, U256}; use sp_std::marker::PhantomData; @@ -59,7 +57,9 @@ where <::Call as Dispatchable>::Origin: From>, ::Call: From>, + Runtime::BlockNumber: Into, TrackIdOf: TryFrom, + BalanceOf: Into, { // The accessors are first. They directly return their result. #[precompile::public("referendumCount()")] @@ -68,11 +68,22 @@ where // Fetch data from pallet handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; let ref_count = ReferendumCount::::get(); - log::trace!(target: "referendum-precompile", "Referendum count from pallet is {:?}", ref_count); + log::trace!(target: "referendum-precompile", "Referendum count is {:?}", ref_count); Ok(ref_count.into()) } + #[precompile::public("submissionDeposit()")] + #[precompile::view] + fn submission_deposit(handle: &mut impl PrecompileHandle) -> EvmResult { + // Fetch data from pallet + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let submission_deposit = Runtime::SubmissionDeposit::get(); + log::trace!(target: "referendum-precompile", "Submission deposit is {:?}", submission_deposit); + + Ok(submission_deposit.into()) + } + #[precompile::public("decidingCount(uint256)")] #[precompile::view] fn deciding_count( @@ -96,44 +107,33 @@ where Ok(deciding_count.into()) } - // #[precompile::public("referendumStatus(uint256)")] - // #[precompile::view] - // fn referendum_status( - // handle: &mut impl PrecompileHandle, - // ref_index: SolidityConvert, - // ) -> EvmResult { - // // Fetch data from pallet - // handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - // let referendum_info = ReferendumInfoFor::::get(ref_index.converted()); - // // log::trace!( - // // target: "referendum-precompile", "Track {:?} deciding count is {:?}", - // // track_id, - // // deciding_count - // // ); - - // // TODO: - // Ok(ref_index.into()) - // } - - // TODO: function per status variant - - #[precompile::public("ongoingReferendumInfoFor(uint256)")] + #[precompile::public("trackInfo(uint256)")] #[precompile::view] - fn ongoing_referendum_info( + fn track_info( handle: &mut impl PrecompileHandle, - ref_index: SolidityConvert, - ) -> EvmResult { + track_id: SolidityConvert, + ) -> EvmResult<(U256, U256, U256, U256, U256, U256)> { // Fetch data from pallet handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; - let referendum_info = ReferendumInfoFor::::get(ref_index.converted()); - // log::trace!( - // target: "referendum-precompile", "Track {:?} deciding count is {:?}", - // track_id, - // deciding_count - // ); - - // TODO: - Ok(ref_index.into()) + let track_id: TrackIdOf = track_id + .converted() + .try_into() + .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) + .in_field("track")?; + let tracks = Runtime::Tracks::tracks(); + let index = tracks + .binary_search_by_key(&track_id, |x| x.0) + .unwrap_or_else(|x| x); + let track_info = &tracks[index].1; + + Ok(( + track_info.max_deciding.into(), + track_info.decision_deposit.into(), + track_info.prepare_period.into(), + track_info.decision_period.into(), + track_info.confirm_period.into(), + track_info.min_enactment_period.into(), + )) } /// Propose a referendum on a privileged action. From a234655624029e3cb0da89e4853d30ff05372548 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 16 Nov 2022 10:33:06 -0500 Subject: [PATCH 18/52] clean --- runtime/moonbase/src/governance/referenda.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index a8f934f545..3873c1035a 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -34,10 +34,16 @@ impl pallet_conviction_voting::Config for Runtime { type WeightInfo = pallet_conviction_voting::weights::SubstrateWeight; type Event = Event; type Currency = Balances; - type VoteLockingPeriod = VoteLockingPeriod; - type MaxVotes = ConstU32<512>; - type MaxTurnout = frame_support::traits::TotalIssuanceOf; type Polls = Referenda; + // TODO: reduce this by funds in system that cannot vote i.e. + // parachain auction deposit but would this require runtime upgrade every time this changes? + type MaxTurnout = frame_support::traits::TotalIssuanceOf; + // Maximum number of concurrent votes an account may have + type MaxVotes = ConstU32<512>; + // Minimum period of vote locking + // TODO: add test that this is always greater than the Enactment period so successful voters are + // locked into consequences of vote + type VoteLockingPeriod = VoteLockingPeriod; } parameter_types! { @@ -62,7 +68,8 @@ impl pallet_governance_origins::Config for Runtime { type MaxTreasurerSpend = MaxBalance; } -// purpose of this pallet is to queue calls to be dispatched as by root for later +// The purpose of this pallet is to queue calls to be dispatched as by root later => the Dispatch +// origin corresponds to the Gov2 Whitelist track. impl pallet_whitelist::Config for Runtime { type WeightInfo = pallet_whitelist::weights::SubstrateWeight; type Event = Event; From e86512cbc18fcddc6e69379901be0af680c145d7 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Sun, 20 Nov 2022 22:38:27 -0500 Subject: [PATCH 19/52] clean and init referenda precompile interface --- pallets/governance-origins/src/lib.rs | 40 +++++++++++++++++++++-- precompiles/referenda/Referenda.sol | 32 ++++++++++++++++++ runtime/moonbase/src/governance/tracks.rs | 14 ++------ 3 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 precompiles/referenda/Referenda.sol diff --git a/pallets/governance-origins/src/lib.rs b/pallets/governance-origins/src/lib.rs index 991269df89..8dfa1a6d8c 100644 --- a/pallets/governance-origins/src/lib.rs +++ b/pallets/governance-origins/src/lib.rs @@ -47,6 +47,8 @@ pub mod governance_origins { #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] #[pallet::origin] pub enum Origin { + /// Origin able to dispatch a whitelisted call. + WhitelistedCaller, /// Origin able to spend up to MaxTreasurerSpend from the treasury at once. Treasurer, /// Origin able to cancel referenda. @@ -59,13 +61,11 @@ pub mod governance_origins { MediumSpender, /// Origin able to spend up to MaxBigSpenderSpend from the treasury at once. BigSpender, - /// Origin able to dispatch a whitelisted call. - WhitelistedCaller, } - // Should match track data in runtime (TODO: add test to verify this in runtime, for the precompile) impl TryFrom for Origin { type Error = (); + /// TrackId => Origin fn try_from(value: u8) -> Result { match value { 1 => Ok(Origin::WhitelistedCaller), @@ -80,6 +80,40 @@ pub mod governance_origins { } } + impl Into for Origin { + /// Origin => TrackId + fn into(self) -> u16 { + match self { + Origin::WhitelistedCaller => 1, + Origin::Treasurer => 10, + Origin::ReferendumCanceller => 11, + Origin::ReferendumKiller => 12, + Origin::SmallSpender => 13, + Origin::MediumSpender => 14, + Origin::BigSpender => 15, + } + } + } + + #[test] + fn origin_track_conversion_is_consistent() { + macro_rules! has_consistent_conversions { + ( $o:expr ) => { + let origin_as_u16 = >::into($o); + let u16_as_u8: u8 = origin_as_u16.try_into().unwrap(); + let u8_as_origin: Origin = u16_as_u8.try_into().unwrap(); + assert_eq!($o, u8_as_origin); + }; + } + has_consistent_conversions!(Origin::WhitelistedCaller); + has_consistent_conversions!(Origin::Treasurer); + has_consistent_conversions!(Origin::ReferendumCanceller); + has_consistent_conversions!(Origin::ReferendumKiller); + has_consistent_conversions!(Origin::SmallSpender); + has_consistent_conversions!(Origin::MediumSpender); + has_consistent_conversions!(Origin::BigSpender); + } + macro_rules! decl_unit_ensures { ( $name:ident: $success_type:ty = $success:expr ) => { pub struct $name; diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol new file mode 100644 index 0000000000..f00270e666 --- /dev/null +++ b/precompiles/referenda/Referenda.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @dev The Referenda contract's address. TODO: UPDATE ADDRESS +address constant REFERENDA_ADDRESS = 0x000000000000000000000000000000000000080b; + +/// @dev The Referenda contract's instance. +Referenda constant REFERENDA_CONTRACT = Referenda(REFERENDA_ADDRESS); + +/// @author The Moonbeam Team +/// @title Pallet Referenda Interface +/// @title The interface through which solidity contracts will interact with the Referenda pallet +/// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS +interface Referenda { + /// @dev Defines the referenda origins that have tracks corresponding to uint8 representation + /// The uint8 representation is defined in pallet-governance-origins Into for Origin + /// From top to bottom: 1, 10, 11, 12, 13, 14, 15 + enum Origin { + WhitelistedCaller, + Treasurer, + ReferendumCanceller, + ReferendumKiller, + SmallSpender, + MediumSpender, + BigSpender + } + + /// @dev Submit a referenda + /// @custom:selector 74a34dd3 + /// @param origin The origin from which the proposed referenda would be dispatched + function submit(Origin origin) external; +} diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index bb67a5131a..1733be9d1e 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -170,18 +170,8 @@ impl pallet_referenda::TracksInfo for TracksInfo { _ => Err(()), } } else if let Ok(custom_origin) = governance_origins::Origin::try_from(id.clone()) { - match custom_origin { - governance_origins::Origin::WhitelistedCaller => Ok(1), - // Unlimited spender - governance_origins::Origin::Treasurer => Ok(10), - // Referendum admins - governance_origins::Origin::ReferendumCanceller => Ok(11), - governance_origins::Origin::ReferendumKiller => Ok(12), - // Limited spenders - governance_origins::Origin::SmallSpender => Ok(13), - governance_origins::Origin::MediumSpender => Ok(14), - governance_origins::Origin::BigSpender => Ok(15), - } + // Origins => TrackId defined in Into for Origin (in pallet-governance-origins) + Ok(custom_origin.into()) } else { Err(()) } From c389722b96364d8ffb80e9719893b8455793352d Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 4 Jan 2023 09:35:13 -0500 Subject: [PATCH 20/52] fix merge --- Cargo.lock | 79 ++++-- pallets/governance-origins/Cargo.toml | 6 +- precompiles/conviction-voting/Cargo.toml | 22 +- precompiles/conviction-voting/src/lib.rs | 6 +- precompiles/preimage/Cargo.toml | 22 +- precompiles/referenda/Cargo.toml | 24 +- precompiles/referenda/Referenda.sol | 48 +++- precompiles/referenda/src/lib.rs | 24 +- precompiles/referenda/src/mock.rs | 324 +++++++++++++++++++++++ 9 files changed, 475 insertions(+), 80 deletions(-) create mode 100644 precompiles/referenda/src/mock.rs diff --git a/Cargo.lock b/Cargo.lock index 53944f0362..3d2b12b459 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,7 +24,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -690,7 +690,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding", + "block-padding 0.1.5", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -702,6 +702,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ + "block-padding 0.2.1", "generic-array 0.14.6", ] @@ -723,6 +724,12 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "blocking" version = "1.2.0" @@ -2260,7 +2267,7 @@ dependencies = [ "rlp", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "triehash", ] @@ -2304,7 +2311,7 @@ dependencies = [ "rlp", "scale-info", "serde", - "sha3", + "sha3 0.10.6", ] [[package]] @@ -2341,7 +2348,7 @@ dependencies = [ "environmental", "evm-core", "primitive-types", - "sha3", + "sha3 0.10.6", ] [[package]] @@ -4927,7 +4934,7 @@ dependencies = [ "scale-info", "serde", "session-keys-primitives", - "sha3", + "sha3 0.10.6", "smallvec", "sp-api", "sp-block-builder", @@ -5007,7 +5014,7 @@ dependencies = [ "clap", "libsecp256k1", "primitive-types", - "sha3", + "sha3 0.10.6", "sp-runtime", "tiny-bip39", "url", @@ -5231,7 +5238,7 @@ dependencies = [ "sc-network", "sc-utils", "serde", - "sha3", + "sha3 0.10.6", "sp-api", "sp-block-builder", "sp-blockchain", @@ -5257,7 +5264,7 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "serde", - "sha3", + "sha3 0.10.6", "sp-api", "sp-blockchain", "sp-io", @@ -5369,7 +5376,7 @@ dependencies = [ "scale-info", "serde", "session-keys-primitives", - "sha3", + "sha3 0.10.6", "smallvec", "sp-api", "sp-block-builder", @@ -5516,7 +5523,7 @@ dependencies = [ "serde", "serde_json", "session-keys-primitives", - "sha3", + "sha3 0.10.6", "sp-api", "sp-block-builder", "sp-blockchain", @@ -5695,7 +5702,7 @@ dependencies = [ "scale-info", "serde", "session-keys-primitives", - "sha3", + "sha3 0.10.6", "smallvec", "sp-api", "sp-block-builder", @@ -5759,7 +5766,7 @@ dependencies = [ "digest 0.10.5", "multihash-derive", "sha2 0.10.6", - "sha3", + "sha3 0.10.6", "unsigned-varint", ] @@ -6844,7 +6851,7 @@ dependencies = [ "precompile-utils", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "slices", "sp-core", "sp-io", @@ -6872,7 +6879,7 @@ dependencies = [ "precompile-utils", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "slices", "sp-core", "sp-io", @@ -6919,7 +6926,7 @@ dependencies = [ "precompile-utils", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "slices", "sp-core", "sp-io", @@ -6949,7 +6956,7 @@ dependencies = [ "precompile-utils", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "similar-asserts", "slices", "sp-core", @@ -7010,7 +7017,7 @@ dependencies = [ "rustc-hex", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7082,7 +7089,7 @@ dependencies = [ "rustc-hex", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7137,7 +7144,7 @@ dependencies = [ "rustc-hex", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7187,7 +7194,9 @@ dependencies = [ "pallet-balances", "pallet-evm", "pallet-governance-origins", + "pallet-preimage", "pallet-referenda", + "pallet-scheduler", "pallet-timestamp", "parity-scale-codec", "precompile-utils", @@ -7223,7 +7232,7 @@ dependencies = [ "rustc-hex", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7272,7 +7281,7 @@ dependencies = [ "rustc-hex", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7302,7 +7311,7 @@ dependencies = [ "precompile-utils", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7335,7 +7344,7 @@ dependencies = [ "rustc-hex", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-core", "sp-io", "sp-runtime", @@ -7367,7 +7376,7 @@ dependencies = [ "precompile-utils", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "slices", "sp-core", "sp-io", @@ -9736,7 +9745,7 @@ dependencies = [ "precompile-utils-macro", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "similar-asserts", "sp-core", "sp-io", @@ -9757,7 +9766,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "sha3", + "sha3 0.10.6", "sp-core", "sp-std", "syn", @@ -12009,6 +12018,18 @@ dependencies = [ "digest 0.10.5", ] +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug 0.3.0", +] + [[package]] name = "sha3" version = "0.10.6" @@ -12453,7 +12474,7 @@ dependencies = [ "byteorder", "digest 0.10.5", "sha2 0.10.6", - "sha3", + "sha3 0.10.6", "sp-std", "twox-hash", ] @@ -14812,7 +14833,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sha3", + "sha3 0.10.6", "sp-io", "sp-runtime", "sp-std", diff --git a/pallets/governance-origins/Cargo.toml b/pallets/governance-origins/Cargo.toml index 62300d5f70..71d0d28af2 100644 --- a/pallets/governance-origins/Cargo.toml +++ b/pallets/governance-origins/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" version = "0.1.0" [dependencies] -frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } -sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } [features] default = [ "std" ] diff --git a/precompiles/conviction-voting/Cargo.toml b/precompiles/conviction-voting/Cargo.toml index 5f8f1540c1..57edc607ae 100644 --- a/precompiles/conviction-voting/Cargo.toml +++ b/precompiles/conviction-voting/Cargo.toml @@ -15,17 +15,17 @@ pallet-governance-origins = { path = "../../pallets/governance-origins", default precompile-utils = { path = "../utils", default-features = false } # Substrate -frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -pallet-conviction-voting = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-conviction-voting = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } -sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } # Frontier -fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false, features = [ "forbid-evm-reentrancy" ] } +fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.32", default-features = false, features = [ "forbid-evm-reentrancy" ] } [dev-dependencies] derive_more = "0.99" @@ -37,10 +37,10 @@ sha3 = "0.9" precompile-utils = { path = "../utils", features = [ "testing" ] } # Substrate -pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } -pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } +pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } -sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } [features] default = [ "std" ] diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index ca35887eb3..44eaba6e53 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -62,11 +62,11 @@ where Runtime: pallet_conviction_voting::Config + pallet_evm::Config + frame_system::Config, BalanceOf: TryFrom, ::Hash: TryFrom, - ::Call: + ::RuntimeCall: Dispatchable + GetDispatchInfo, - <::Call as Dispatchable>::Origin: + <::RuntimeCall as Dispatchable>::RuntimeOrigin: From>, - ::Call: From>, + ::RuntimeCall: From>, IndexOf: TryFrom, ClassOf: TryFrom, { diff --git a/precompiles/preimage/Cargo.toml b/precompiles/preimage/Cargo.toml index f848f3448e..04d86dbb94 100644 --- a/precompiles/preimage/Cargo.toml +++ b/precompiles/preimage/Cargo.toml @@ -15,17 +15,17 @@ pallet-governance-origins = { path = "../../pallets/governance-origins", default precompile-utils = { path = "../utils", default-features = false } # Substrate -frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } -sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } # Frontier -fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false, features = [ "forbid-evm-reentrancy" ] } +fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.32", default-features = false, features = [ "forbid-evm-reentrancy" ] } [dev-dependencies] derive_more = "0.99" @@ -37,10 +37,10 @@ sha3 = "0.9" precompile-utils = { path = "../utils", features = [ "testing" ] } # Substrate -pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } -pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } +pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } -sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } [features] default = [ "std" ] diff --git a/precompiles/referenda/Cargo.toml b/precompiles/referenda/Cargo.toml index f49b9e2cf0..58f6f85033 100644 --- a/precompiles/referenda/Cargo.toml +++ b/precompiles/referenda/Cargo.toml @@ -15,32 +15,34 @@ pallet-governance-origins = { path = "../../pallets/governance-origins", default precompile-utils = { path = "../utils", default-features = false } # Substrate -frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -pallet-referenda = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-referenda = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } -sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-core = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +sp-runtime = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } # Frontier -fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false } -pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.29", default-features = false, features = [ "forbid-evm-reentrancy" ] } +fp-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam-polkadot-v0.9.32", default-features = false, features = [ "forbid-evm-reentrancy" ] } [dev-dependencies] derive_more = "0.99" hex-literal = "0.3.3" serde = "1.0.100" sha3 = "0.9" +pallet-scheduler = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } +pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } # Moonbeam precompile-utils = { path = "../utils", features = [ "testing" ] } # Substrate -pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } -pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29" } +pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } +pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } -sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false } +sp-io = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } [features] default = [ "std" ] diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index f00270e666..ed7d6d3748 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -25,8 +25,54 @@ interface Referenda { BigSpender } + /// Return the total referendum count + /// @custom:selector 81797566 + function referendumCount() external view returns (uint256); + + /// Return the submission deposit for all referenda + /// @custom:selector 81797566 + function submissionDeposit() external view returns (uint256); + + /// Return the total count of deciding referenda per track + /// @param trackId The track identifier + /// @custom:selector 81797566 + function decidingCount(uint256 trackId) external view returns (uint256); + + /// Return the total count of deciding referenda per track + /// @param trackId The track identifier + /// @custom:selector 81797566 + function trackInfo(uint256 trackId) + external + view + returns ( + uint256, + uint256, + uint256, + uint256, + uint256, + uint256 + ); + /// @dev Submit a referenda /// @custom:selector 74a34dd3 /// @param origin The origin from which the proposed referenda would be dispatched - function submit(Origin origin) external; + /// @param hash Hash of the proposal preimage + /// @param at If true then AT block_number, else AFTER block_number + /// @param block Inner block number for DispatchTime + function submit( + Origin origin, + bytes memory hash, + bool at, + uint32 block + ) external; + + /// @dev Post the Decision Deposit for a referendum + /// @custom:selector 74a34dd3 + /// @param index The index of the ongoing referendum that is not yet deciding + function place_decision_deposit(uint32 index) external; + + /// @dev Refund the Decision Deposit for a closed referendum back to the depositor + /// @custom:selector 74a34dd3 + /// @param index The index of a closed referendum with decision deposit still locked + function refund_decision_deposit(uint32 index) external; } diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index e539f4310b..a32149146f 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -19,15 +19,15 @@ use fp_evm::PrecompileHandle; use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; -use frame_support::traits::{schedule::DispatchTime, Currency, Get, OriginTrait}; +use frame_support::traits::{schedule::DispatchTime, Bounded, Currency, Get, OriginTrait}; use pallet_evm::AddressMapping; use pallet_referenda::{Call as ReferendaCall, DecidingCount, ReferendumCount, TracksInfo}; use precompile_utils::prelude::*; use sp_core::{H256, U256}; use sp_std::marker::PhantomData; -// #[cfg(test)] -// mod mock; +#[cfg(test)] +mod mock; // #[cfg(test)] // mod tests; @@ -38,8 +38,10 @@ type TrackIdOf = <::Tracks as Trac BalanceOf, ::BlockNumber, >>::Id; +type BoundedCallOf = Bounded<::RuntimeCall>; -type OriginOf = <::Origin as OriginTrait>::PalletsOrigin; +type OriginOf = + <::RuntimeOrigin as OriginTrait>::PalletsOrigin; /// A precompile to wrap the functionality from pallet-referenda. pub struct ReferendaPrecompile(PhantomData); @@ -48,15 +50,15 @@ pub struct ReferendaPrecompile(PhantomData); impl ReferendaPrecompile where Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, - <::Call as Dispatchable>::Origin: + <::RuntimeCall as Dispatchable>::RuntimeOrigin: From>, OriginOf: From, - ::Hash: TryFrom, - ::Call: + BoundedCallOf: TryFrom, + ::RuntimeCall: Dispatchable + GetDispatchInfo, - <::Call as Dispatchable>::Origin: + <::RuntimeCall as Dispatchable>::RuntimeOrigin: From>, - ::Call: From>, + ::RuntimeCall: From>, Runtime::BlockNumber: Into, TrackIdOf: TryFrom, BalanceOf: Into, @@ -156,7 +158,7 @@ where RevertReason::custom("Origin does not exist for u8").in_field("proposal_origin") })?; let proposal_origin: Box> = Box::new(gov_origin.into()); - let proposal_hash: Runtime::Hash = proposal_hash.try_into().map_err(|_| { + let proposal: BoundedCallOf = proposal_hash.try_into().map_err(|_| { RevertReason::custom("Proposal hash input is not H256").in_field("proposal_hash") })?; let enactment_moment: DispatchTime = if at { @@ -169,7 +171,7 @@ where let call = ReferendaCall::::submit { proposal_origin, - proposal_hash, + proposal, enactment_moment, } .into(); diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs new file mode 100644 index 0000000000..226cec1d4a --- /dev/null +++ b/precompiles/referenda/src/mock.rs @@ -0,0 +1,324 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! A minimal precompile runtime including the pallet-randomness pallet +use super::*; +use frame_support::{ + construct_runtime, parameter_types, + traits::{Everything, GenesisBuild}, + weights::Weight, +}; +use nimbus_primitives::NimbusId; +use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; +use precompile_utils::{precompile_set::*, testing::MockAccount}; +use session_keys_primitives::VrfId; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + Perbill, +}; +use sp_std::convert::{TryFrom, TryInto}; + +pub type AccountId = MockAccount; +pub type Balance = u128; +pub type BlockNumber = u32; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Evm: pallet_evm::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Preimage: pallet_preimage, + Scheduler: pallet_scheduler, + Referenda: pallet_referenda, + } +); + +parameter_types! { + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: Weight = Weight::from_ref_time(1024); + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const SS58Prefix: u8 = 42; +} +impl frame_system::Config for Runtime { + type BaseCallFilter = Everything; + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = BlockNumber; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = sp_runtime::generic::Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type BlockWeights = (); + type BlockLength = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 0; +} +impl pallet_balances::Config for Runtime { + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} + +pub type TestPrecompiles = PrecompileSetBuilder< + R, + ( + PrecompileAt, RandomnessPrecompile, LimitRecursionTo<1>>, + RevertPrecompile>, + ), +>; + +pub type PCall = RandomnessPrecompileCall; + +parameter_types! { + pub PrecompilesValue: TestPrecompiles = TestPrecompiles::new(); + pub const WeightPerGas: Weight = Weight::from_ref_time(1); +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = (); + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = AccountId; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type Runner = pallet_evm::runner::stack::Runner; + type PrecompilesType = TestPrecompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = (); + type OnChargeTransaction = (); + type BlockGasLimit = (); + type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping; + type FindAuthor = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +impl pallet_preimage::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type BaseDeposit = (); + type ByteDeposit = (); +} +impl pallet_scheduler::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaxWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = ConstU32<100>; + type WeightInfo = (); + type OriginPrivilegeCmp = EqualPrivilegeOnly; + type Preimages = Preimage; +} + +parameter_types! { + pub static AlarmInterval: u64 = 1; +} +ord_parameter_types! { + pub const One: u64 = 1; + pub const Two: u64 = 2; + pub const Three: u64 = 3; + pub const Four: u64 = 4; + pub const Five: u64 = 5; + pub const Six: u64 = 6; +} +pub struct OneToFive; +impl SortedMembers for OneToFive { + fn sorted_members() -> Vec { + vec![1, 2, 3, 4, 5] + } + #[cfg(feature = "runtime-benchmarks")] + fn add(_m: &u64) {} +} + +pub struct TestTracksInfo; +impl TracksInfo for TestTracksInfo { + type Id = u8; + type RuntimeOrigin = ::PalletsOrigin; + fn tracks() -> &'static [(Self::Id, TrackInfo)] { + static DATA: [(u8, TrackInfo); 2] = [ + ( + 0u8, + TrackInfo { + name: "root", + max_deciding: 1, + decision_deposit: 10, + prepare_period: 4, + decision_period: 4, + confirm_period: 2, + min_enactment_period: 4, + min_approval: Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(100), + }, + }, + ), + ( + 1u8, + TrackInfo { + name: "none", + max_deciding: 3, + decision_deposit: 1, + prepare_period: 2, + decision_period: 2, + confirm_period: 1, + min_enactment_period: 2, + min_approval: Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(95), + ceil: Perbill::from_percent(100), + }, + min_support: Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(90), + ceil: Perbill::from_percent(100), + }, + }, + ), + ]; + &DATA[..] + } + fn track_for(id: &Self::RuntimeOrigin) -> Result { + if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) { + match system_origin { + frame_system::RawOrigin::Root => Ok(0), + frame_system::RawOrigin::None => Ok(1), + _ => Err(()), + } + } else { + Err(()) + } + } +} +impl_tracksinfo_get!(TestTracksInfo, u64, u64); + +impl pallet_referenda::Config for Runtime { + type WeightInfo = (); + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = pallet_balances::Pallet; + type SubmitOrigin = frame_system::EnsureSigned; + type CancelOrigin = EnsureSignedBy; + type KillOrigin = EnsureRoot; + type Slash = (); + type Votes = u32; + type Tally = Tally; + type SubmissionDeposit = ConstU64<2>; + type MaxQueued = ConstU32<3>; + type UndecidingTimeout = ConstU64<20>; + type AlarmInterval = AlarmInterval; + type Tracks = TestTracksInfo; + type Preimages = Preimage; +} + +/// Externality builder for pallet referenda mock runtime +pub(crate) struct ExtBuilder { + /// Balance amounts per AccountId + balances: Vec<(AccountId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> ExtBuilder { + ExtBuilder { + balances: Vec::new(), + } + } +} + +impl ExtBuilder { + #[allow(dead_code)] + pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { + self.balances = balances; + self + } + + #[allow(dead_code)] + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +pub(crate) fn events() -> Vec { + System::events() + .into_iter() + .map(|r| r.event) + .collect::>() +} From 5bb16736dfae9b899f6daadbc6acac04fd0aaf28 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 4 Jan 2023 18:10:39 -0500 Subject: [PATCH 21/52] try mock referenda precompile but did not succeed --- precompiles/preimage/src/lib.rs | 6 +- precompiles/referenda/Cargo.toml | 4 +- precompiles/referenda/src/mock.rs | 114 +++++++++++++++++++++-------- precompiles/referenda/src/tests.rs | 42 +++++++++++ 4 files changed, 129 insertions(+), 37 deletions(-) create mode 100644 precompiles/referenda/src/tests.rs diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index b7b9a66831..22bccab371 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -42,11 +42,11 @@ impl PreimagePrecompile where Runtime: pallet_preimage::Config + pallet_evm::Config + frame_system::Config, ::Hash: TryFrom, - ::Call: + ::RuntimeCall: Dispatchable + GetDispatchInfo, - <::Call as Dispatchable>::Origin: + <::RuntimeCall as Dispatchable>::RuntimeOrigin: From>, - ::Call: From>, + ::RuntimeCall: From>, { /// Register a preimage on-chain. /// diff --git a/precompiles/referenda/Cargo.toml b/precompiles/referenda/Cargo.toml index 58f6f85033..3cf87ed05d 100644 --- a/precompiles/referenda/Cargo.toml +++ b/precompiles/referenda/Cargo.toml @@ -30,10 +30,10 @@ pallet-evm = { git = "https://github.com/purestake/frontier", branch = "moonbeam [dev-dependencies] derive_more = "0.99" hex-literal = "0.3.3" +pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } +pallet-scheduler = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } serde = "1.0.100" sha3 = "0.9" -pallet-scheduler = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } -pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32" } # Moonbeam precompile-utils = { path = "../utils", features = [ "testing" ] } diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs index 226cec1d4a..8791b9f8b1 100644 --- a/precompiles/referenda/src/mock.rs +++ b/precompiles/referenda/src/mock.rs @@ -17,14 +17,16 @@ //! A minimal precompile runtime including the pallet-randomness pallet use super::*; use frame_support::{ - construct_runtime, parameter_types, - traits::{Everything, GenesisBuild}, + construct_runtime, ord_parameter_types, parameter_types, + traits::{ConstU32, ConstU64, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally}, weights::Weight, }; -use nimbus_primitives::NimbusId; +use frame_system::{EnsureRoot, EnsureSigned, EnsureSignedBy}; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; -use precompile_utils::{precompile_set::*, testing::MockAccount}; -use session_keys_primitives::VrfId; +use pallet_referenda::{impl_tracksinfo_get, Curve, TrackInfo}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use precompile_utils::{precompile_set::*, testing::*}; +use scale_info::TypeInfo; use sp_core::H256; use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, @@ -108,12 +110,12 @@ impl pallet_balances::Config for Runtime { pub type TestPrecompiles = PrecompileSetBuilder< R, ( - PrecompileAt, RandomnessPrecompile, LimitRecursionTo<1>>, + PrecompileAt, ReferendaPrecompile, LimitRecursionTo<1>>, RevertPrecompile>, ), >; -pub type PCall = RandomnessPrecompileCall; +pub type PCall = ReferendaPrecompileCall; parameter_types! { pub PrecompilesValue: TestPrecompiles = TestPrecompiles::new(); @@ -153,7 +155,7 @@ impl pallet_preimage::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); type Currency = Balances; - type ManagerOrigin = EnsureRoot; + type ManagerOrigin = EnsureRoot; type BaseDeposit = (); type ByteDeposit = (); } @@ -162,8 +164,8 @@ impl pallet_scheduler::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; type PalletsOrigin = OriginCaller; type RuntimeCall = RuntimeCall; - type MaximumWeight = MaxWeight; - type ScheduleOrigin = EnsureRoot; + type MaximumWeight = MaximumBlockWeight; + type ScheduleOrigin = EnsureRoot; type MaxScheduledPerBlock = ConstU32<100>; type WeightInfo = (); type OriginPrivilegeCmp = EqualPrivilegeOnly; @@ -171,31 +173,29 @@ impl pallet_scheduler::Config for Runtime { } parameter_types! { - pub static AlarmInterval: u64 = 1; -} -ord_parameter_types! { - pub const One: u64 = 1; - pub const Two: u64 = 2; - pub const Three: u64 = 3; - pub const Four: u64 = 4; - pub const Five: u64 = 5; - pub const Six: u64 = 6; + pub static AlarmInterval: u32 = 1; } pub struct OneToFive; -impl SortedMembers for OneToFive { - fn sorted_members() -> Vec { - vec![1, 2, 3, 4, 5] +impl SortedMembers for OneToFive { + fn sorted_members() -> Vec { + vec![ + Alice.into(), + Bob.into(), + Charlie.into(), + David.into(), + Zero.into(), + ] } #[cfg(feature = "runtime-benchmarks")] - fn add(_m: &u64) {} + fn add(_m: &AccountId) {} } pub struct TestTracksInfo; -impl TracksInfo for TestTracksInfo { +impl TracksInfo for TestTracksInfo { type Id = u8; type RuntimeOrigin = ::PalletsOrigin; - fn tracks() -> &'static [(Self::Id, TrackInfo)] { - static DATA: [(u8, TrackInfo); 2] = [ + fn tracks() -> &'static [(Self::Id, TrackInfo)] { + static DATA: [(u8, TrackInfo); 2] = [ ( 0u8, TrackInfo { @@ -255,23 +255,73 @@ impl TracksInfo for TestTracksInfo { } } } -impl_tracksinfo_get!(TestTracksInfo, u64, u64); +impl_tracksinfo_get!(TestTracksInfo, u128, u32); + +#[derive(Encode, Debug, Decode, TypeInfo, Eq, PartialEq, Clone, MaxEncodedLen)] +pub struct Tally { + pub ayes: u32, + pub nays: u32, +} + +impl VoteTally for Tally { + fn new(_: Class) -> Self { + Self { ayes: 0, nays: 0 } + } + + fn ayes(&self, _: Class) -> u32 { + self.ayes + } + + fn support(&self, _: Class) -> Perbill { + Perbill::from_percent(self.ayes) + } + + fn approval(&self, _: Class) -> Perbill { + if self.ayes + self.nays > 0 { + Perbill::from_rational(self.ayes, self.ayes + self.nays) + } else { + Perbill::zero() + } + } + #[cfg(feature = "runtime-benchmarks")] + fn unanimity(_: Class) -> Self { + Self { ayes: 100, nays: 0 } + } + + #[cfg(feature = "runtime-benchmarks")] + fn rejection(_: Class) -> Self { + Self { ayes: 0, nays: 100 } + } + + #[cfg(feature = "runtime-benchmarks")] + fn from_requirements(support: Perbill, approval: Perbill, _: Class) -> Self { + let ayes = support.mul_ceil(100u32); + let nays = ((ayes as u64) * 1_000_000_000u64 / approval.deconstruct() as u64) as u32 - ayes; + Self { ayes, nays } + } + + #[cfg(feature = "runtime-benchmarks")] + fn setup(_: Class, _: Perbill) {} +} +parameter_types! { + pub const SubmissionDeposit: u128 = 10; +} impl pallet_referenda::Config for Runtime { type WeightInfo = (); type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type Scheduler = Scheduler; type Currency = pallet_balances::Pallet; - type SubmitOrigin = frame_system::EnsureSigned; - type CancelOrigin = EnsureSignedBy; - type KillOrigin = EnsureRoot; + type SubmitOrigin = EnsureSigned; + type CancelOrigin = EnsureSignedBy; + type KillOrigin = EnsureRoot; type Slash = (); type Votes = u32; type Tally = Tally; - type SubmissionDeposit = ConstU64<2>; + type SubmissionDeposit = SubmissionDeposit; type MaxQueued = ConstU32<3>; - type UndecidingTimeout = ConstU64<20>; + type UndecidingTimeout = ConstU32<20>; type AlarmInterval = AlarmInterval; type Tracks = TestTracksInfo; type Preimages = Preimage; diff --git a/precompiles/referenda/src/tests.rs b/precompiles/referenda/src/tests.rs new file mode 100644 index 0000000000..7dea840ef6 --- /dev/null +++ b/precompiles/referenda/src/tests.rs @@ -0,0 +1,42 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +use precompile_utils::testing::*; + +#[test] +fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() { + for file in ["Referenda.sol"] { + for solidity_fn in solidity::get_selectors(file) { + assert_eq!( + solidity_fn.compute_selector_hex(), + solidity_fn.docs_selector, + "documented selector for '{}' did not match for file '{}'", + solidity_fn.signature(), + file, + ); + + let selector = solidity_fn.compute_selector(); + if !PCall::supports_selector(selector) { + panic!( + "failed decoding selector 0x{:x} => '{}' as Action for file '{}'", + selector, + solidity_fn.signature(), + file, + ) + } + } + } +} \ No newline at end of file From e7c765b71e4b58f8421683a03b021f86f4d7bd0c Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Fri, 6 Jan 2023 10:42:30 -0500 Subject: [PATCH 22/52] save --- precompiles/referenda/src/lib.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index a32149146f..c7843d78ef 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -19,11 +19,13 @@ use fp_evm::PrecompileHandle; use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; -use frame_support::traits::{schedule::DispatchTime, Bounded, Currency, Get, OriginTrait}; +use frame_support::traits::{ + schedule::DispatchTime, Bounded, ConstU32, Currency, Get, OriginTrait, +}; use pallet_evm::AddressMapping; use pallet_referenda::{Call as ReferendaCall, DecidingCount, ReferendumCount, TracksInfo}; use precompile_utils::prelude::*; -use sp_core::{H256, U256}; +use sp_core::U256; use sp_std::marker::PhantomData; #[cfg(test)] @@ -31,6 +33,9 @@ mod mock; // #[cfg(test)] // mod tests; +pub const CALL_DATA_LIMIT: u32 = 2u32.pow(16); + +type GetCallDataLimit = ConstU32; type BalanceOf = <::Currency as Currency< ::AccountId, >>::Balance; @@ -50,10 +55,7 @@ pub struct ReferendaPrecompile(PhantomData); impl ReferendaPrecompile where Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, - <::RuntimeCall as Dispatchable>::RuntimeOrigin: - From>, OriginOf: From, - BoundedCallOf: TryFrom, ::RuntimeCall: Dispatchable + GetDispatchInfo, <::RuntimeCall as Dispatchable>::RuntimeOrigin: @@ -142,14 +144,14 @@ where /// /// Parameters: /// * proposal_origin: The origin from which the proposal should be executed. - /// * proposal_hash: Hash of the proposal preimage. + /// * proposal: The proposed runtime call. /// * at: If true then AT block_number, else AFTER block_number /// * block_number: Inner block number for DispatchTime #[precompile::public("submit(uint8,bytes32,bool,uint32)")] fn submit( handle: &mut impl PrecompileHandle, proposal_origin: u8, - proposal_hash: H256, + proposal: BoundedBytes, at: bool, block_number: u32, ) -> EvmResult { @@ -158,9 +160,11 @@ where RevertReason::custom("Origin does not exist for u8").in_field("proposal_origin") })?; let proposal_origin: Box> = Box::new(gov_origin.into()); - let proposal: BoundedCallOf = proposal_hash.try_into().map_err(|_| { - RevertReason::custom("Proposal hash input is not H256").in_field("proposal_hash") - })?; + let proposal: BoundedCallOf = Bounded::Inline( + frame_support::BoundedVec::try_from(proposal.as_bytes().to_vec()).map_err(|_| { + RevertReason::custom("Proposal input is not a runtime call").in_field("proposal") + })?, + ); let enactment_moment: DispatchTime = if at { DispatchTime::At(block_number.into()) } else { From c5e2220f0c0e89ff4e84448a2ea4af7c860d7617 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Mon, 9 Jan 2023 10:23:05 +0000 Subject: [PATCH 23/52] fix referenda mock --- precompiles/referenda/src/lib.rs | 7 +++++-- precompiles/referenda/src/mock.rs | 13 ++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index c7843d78ef..3703018539 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -54,7 +54,10 @@ pub struct ReferendaPrecompile(PhantomData); #[precompile_utils::precompile] impl ReferendaPrecompile where - Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, + Runtime: pallet_referenda::Config + + pallet_evm::Config + + frame_system::Config + + pallet_governance_origins::Config, OriginOf: From, ::RuntimeCall: Dispatchable + GetDispatchInfo, @@ -147,7 +150,7 @@ where /// * proposal: The proposed runtime call. /// * at: If true then AT block_number, else AFTER block_number /// * block_number: Inner block number for DispatchTime - #[precompile::public("submit(uint8,bytes32,bool,uint32)")] + #[precompile::public("submit(uint8,bytes,bool,uint32)")] fn submit( handle: &mut impl PrecompileHandle, proposal_origin: u8, diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs index 8791b9f8b1..a707f02300 100644 --- a/precompiles/referenda/src/mock.rs +++ b/precompiles/referenda/src/mock.rs @@ -18,7 +18,9 @@ use super::*; use frame_support::{ construct_runtime, ord_parameter_types, parameter_types, - traits::{ConstU32, ConstU64, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally}, + traits::{ + ConstU128, ConstU32, ConstU64, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally, + }, weights::Weight, }; use frame_system::{EnsureRoot, EnsureSigned, EnsureSignedBy}; @@ -55,6 +57,7 @@ construct_runtime!( Preimage: pallet_preimage, Scheduler: pallet_scheduler, Referenda: pallet_referenda, + GovernanceOrigins: pallet_governance_origins::{Pallet, Origin}, } ); @@ -327,6 +330,14 @@ impl pallet_referenda::Config for Runtime { type Preimages = Preimage; } +impl pallet_governance_origins::Config for Runtime { + type Currency = pallet_balances::Pallet; + type MaxSmallSpenderSpend = ConstU128<1>; + type MaxMediumSpenderSpend = ConstU128<1>; + type MaxBigSpenderSpend = ConstU128<1>; + type MaxTreasurerSpend = ConstU128<1>; +} + /// Externality builder for pallet referenda mock runtime pub(crate) struct ExtBuilder { /// Balance amounts per AccountId From d05803f7ed66aba50694d823559a9cd7f2378724 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Mon, 9 Jan 2023 12:59:52 -0500 Subject: [PATCH 24/52] add dot sol files for preimage and voting --- .../conviction-voting/ConvictionVoting.sol | 64 +++++ precompiles/conviction-voting/src/lib.rs | 23 +- precompiles/conviction-voting/src/mock.rs | 250 ++++++++++++++++++ precompiles/conviction-voting/src/tests.rs | 42 +++ precompiles/preimage/Preimage.sol | 26 ++ precompiles/preimage/src/lib.rs | 4 +- precompiles/preimage/src/mock.rs | 156 +++++++++++ precompiles/preimage/src/tests.rs | 42 +++ precompiles/referenda/src/tests.rs | 2 +- 9 files changed, 584 insertions(+), 25 deletions(-) create mode 100644 precompiles/conviction-voting/ConvictionVoting.sol create mode 100644 precompiles/conviction-voting/src/mock.rs create mode 100644 precompiles/conviction-voting/src/tests.rs create mode 100644 precompiles/preimage/Preimage.sol create mode 100644 precompiles/preimage/src/mock.rs create mode 100644 precompiles/preimage/src/tests.rs diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol new file mode 100644 index 0000000000..4547c419b0 --- /dev/null +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @dev The Conviction Voting contract's address. TODO: UPDATE ADDRESS +address constant Conviction_Voting_ADDRESS = 0x000000000000000000000000000000000000080b; + +/// @dev The Conviction Voting contract's instance. +ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( + Conviction_Voting_ADDRESS +); + +/// @author The Moonbeam Team +/// @title Pallet Conviction Voting Interface +/// @title The interface through which solidity contracts will interact with the Conviction Voting pallet +/// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS +interface ConvictionVoting { + /// @dev Vote in a poll. + /// @custom:selector 74a34dd3 + /// @param pollIndex Index of poll + /// @param aye Yes or no vote + /// @param voteAmount Balance locked for vote + /// @param conviction Conviction multiplier for length of vote lock + function standard_vote( + uint256 pollIndex, + bool aye, + uint256 voteAmount, + uint256 conviction + ) external; + + /// @dev Remove vote in poll + /// @custom:selector 74a34dd3 + /// @param pollIndex Index of the poll + function remove_vote(uint256 pollIndex) external; + + /// @dev Remove vote in poll for other voter + /// @custom:selector 74a34dd3 + /// @param class The class + /// @param pollIndex the poll index + function remove_other_vote(uint256 class, uint256 pollIndex) external; + + /// @dev Delegate to a representative for the vote class + /// @custom:selector 74a34dd3 + /// @param class The class + /// @param representative The representative for the class + /// @param conviction The conviction multiplier + /// @param amount delegated to representative for this vote class + function delegate( + uint256 class, + address representative, + uint256 conviction, + uint256 amount + ) external; + + /// @dev Undelegate for the vote class + /// @custom:selector 74a34dd3 + /// @param class The class + function undelegate(uint256 class) external; + + /// @dev Unlock tokens locked for vote class + /// @custom:selector 74a34dd3 + /// @param class The class + /// @param target The target address + function unlock(uint256 class, address target) external; +} diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 44eaba6e53..01927fd5fd 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -128,28 +128,6 @@ where Ok(()) } - #[precompile::public("removeVoteForClass(uint256,uint256)")] - fn remove_vote_for_class( - handle: &mut impl PrecompileHandle, - class: SolidityConvert, - poll_index: SolidityConvert, - ) -> EvmResult { - let class = Some(Self::u16_to_class(class.converted()).in_field("class")?); - let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; - - log::trace!( - target: "conviction-voting-precompile", - "Removing vote from poll {:?}", - index - ); - - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::remove_vote { class, index }; - - RuntimeHelper::::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) - } #[precompile::public("removeOtherVote(address,uint256,uint256)")] fn remove_other_vote( handle: &mut impl PrecompileHandle, @@ -181,6 +159,7 @@ where Ok(()) } + #[precompile::public("delegate(uint256,address,uint256,uint256)")] fn delegate( handle: &mut impl PrecompileHandle, diff --git a/precompiles/conviction-voting/src/mock.rs b/precompiles/conviction-voting/src/mock.rs new file mode 100644 index 0000000000..f181cb7c68 --- /dev/null +++ b/precompiles/conviction-voting/src/mock.rs @@ -0,0 +1,250 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Test utilities +use super::*; +use frame_support::{ + construct_runtime, parameter_types, + traits::{ + Everything, GenesisBuild, OnFinalize, OnInitialize, PollStatus, Polling, TotalIssuanceOf, + }, + weights::Weight, +}; +use frame_system::EnsureRoot; +use pallet_conviction_voting::TallyOf; +use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; +use precompile_utils::{ + precompile_set::*, + testing::{Alice, MockAccount}, +}; +use sp_core::{H256, U256}; +use sp_io; +use sp_runtime::{ + traits::{BlakeTwo256, ConstU32, ConstU64, IdentityLookup}, + DispatchError, Perbill, Percent, +}; +use sp_std::collections::btree_map::BTreeMap; + +pub type AccountId = MockAccount; +pub type Balance = u128; +pub type BlockNumber = u32; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Evm: pallet_evm::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + ConvictionVoting: pallet_conviction_voting, + } +); + +parameter_types! { + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: Weight = Weight::from_ref_time(1024); + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const SS58Prefix: u8 = 42; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = Everything; + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = BlockNumber; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = sp_runtime::generic::Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type BlockWeights = (); + type BlockLength = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} +parameter_types! { + pub const ExistentialDeposit: u128 = 1; +} +impl pallet_balances::Config for Runtime { + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} + +parameter_types! { + pub BlockGasLimit: U256 = U256::max_value(); + pub PrecompilesValue: Precompiles = Precompiles::new(); + pub const WeightPerGas: Weight = Weight::from_ref_time(1); +} + +pub type Precompiles = + PrecompileSetBuilder, ConvictionVotingPrecompile>,)>; + +pub type PCall = ConvictionVotingPrecompileCall; + +impl pallet_evm::Config for Runtime { + type FeeCalculator = (); + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = AccountId; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type Runner = pallet_evm::runner::stack::Runner; + type PrecompilesType = Precompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = (); + type OnChargeTransaction = (); + type BlockGasLimit = BlockGasLimit; + type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping; + type FindAuthor = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum TestPollState { + Ongoing(TallyOf, u8), + Completed(u64, bool), +} +use TestPollState::*; + +parameter_types! { + pub static Polls: BTreeMap = vec![ + (1, Completed(1, true)), + (2, Completed(2, false)), + (3, Ongoing(Tally::from_parts(0, 0, 0), 0)), + ].into_iter().collect(); +} + +pub struct TestPolls; +impl Polling> for TestPolls { + type Index = u8; + type Votes = u128; + type Moment = u32; + type Class = u8; + fn classes() -> Vec { + vec![0, 1, 2] + } + fn as_ongoing(index: u8) -> Option<(TallyOf, Self::Class)> { + Polls::get().remove(&index).and_then(|x| { + if let TestPollState::Ongoing(t, c) = x { + Some((t, c)) + } else { + None + } + }) + } + fn access_poll( + index: Self::Index, + f: impl FnOnce(PollStatus<&mut TallyOf, u64, u8>) -> R, + ) -> R { + let mut polls = Polls::get(); + let entry = polls.get_mut(&index); + let r = match entry { + Some(Ongoing(ref mut tally_mut_ref, class)) => { + f(PollStatus::Ongoing(tally_mut_ref, *class)) + } + Some(Completed(when, succeeded)) => f(PollStatus::Completed(*when, *succeeded)), + None => f(PollStatus::None), + }; + Polls::set(polls); + r + } + fn try_access_poll( + index: Self::Index, + f: impl FnOnce(PollStatus<&mut TallyOf, u64, u8>) -> Result, + ) -> Result { + let mut polls = Polls::get(); + let entry = polls.get_mut(&index); + let r = match entry { + Some(Ongoing(ref mut tally_mut_ref, class)) => { + f(PollStatus::Ongoing(tally_mut_ref, *class)) + } + Some(Completed(when, succeeded)) => f(PollStatus::Completed(*when, *succeeded)), + None => f(PollStatus::None), + }?; + Polls::set(polls); + Ok(r) + } + + #[cfg(feature = "runtime-benchmarks")] + fn create_ongoing(class: Self::Class) -> Result { + let mut polls = Polls::get(); + let i = polls.keys().rev().next().map_or(0, |x| x + 1); + polls.insert(i, Ongoing(Tally::new(0), class)); + Polls::set(polls); + Ok(i) + } + + #[cfg(feature = "runtime-benchmarks")] + fn end_ongoing(index: Self::Index, approved: bool) -> Result<(), ()> { + let mut polls = Polls::get(); + match polls.get(&index) { + Some(Ongoing(..)) => {} + _ => return Err(()), + } + let now = frame_system::Pallet::::block_number(); + polls.insert(index, Completed(now, approved)); + Polls::set(polls); + Ok(()) + } +} + +impl pallet_conviction_voting::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = pallet_balances::Pallet; + type VoteLockingPeriod = ConstU32<3>; + type MaxVotes = ConstU32<3>; + type WeightInfo = (); + type MaxTurnout = TotalIssuanceOf; + type Polls = TestPolls; +} + +// genesis builder TODO diff --git a/precompiles/conviction-voting/src/tests.rs b/precompiles/conviction-voting/src/tests.rs new file mode 100644 index 0000000000..72306d4311 --- /dev/null +++ b/precompiles/conviction-voting/src/tests.rs @@ -0,0 +1,42 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . +use crate::mock::*; +use precompile_utils::testing::*; + +#[test] +fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() { + for file in ["Preimage.sol"] { + for solidity_fn in solidity::get_selectors(file) { + assert_eq!( + solidity_fn.compute_selector_hex(), + solidity_fn.docs_selector, + "documented selector for '{}' did not match for file '{}'", + solidity_fn.signature(), + file, + ); + + let selector = solidity_fn.compute_selector(); + if !PCall::supports_selector(selector) { + panic!( + "failed decoding selector 0x{:x} => '{}' as Action for file '{}'", + selector, + solidity_fn.signature(), + file, + ) + } + } + } +} \ No newline at end of file diff --git a/precompiles/preimage/Preimage.sol b/precompiles/preimage/Preimage.sol new file mode 100644 index 0000000000..23468918f7 --- /dev/null +++ b/precompiles/preimage/Preimage.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity >=0.8.3; + +/// @dev The Preimage contract's address. TODO: UPDATE ADDRESS +address constant Preimage_ADDRESS = 0x000000000000000000000000000000000000080b; + +/// @dev The Preimage contract's instance. +Preimage constant Preimage_CONTRACT = Preimage(Preimage_ADDRESS); + +/// @author The Moonbeam Team +/// @title Pallet Preimage Interface +/// @title The interface through which solidity contracts will interact with the Preimage pallet +/// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS +interface Preimage { + /// @dev Register a Preimage on-chain. + /// @custom:selector 74a34dd3 + /// @param encodedProposal + function note_preimage( + bytes memory encodedProposal, + ) external; + + /// @dev Clear an unrequested preimage from storage. + /// @custom:selector 74a34dd3 + /// @param hash The preimage to be cleared from storage + function unnote_preimage(bytes32 hash) external; +} diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index 22bccab371..c0714b409e 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -51,7 +51,7 @@ where /// Register a preimage on-chain. /// /// Parameters: - /// * bytes: The preimage registered on-chain + /// * encoded_proposal: The preimage registered on-chain #[precompile::public("notePreimage(bytes)")] fn note_preimage( handle: &mut impl PrecompileHandle, @@ -70,7 +70,7 @@ where /// Clear an unrequested preimage from the runtime storage. /// /// Parameters: - /// * hash: The preimage cleared from the runtime storage + /// * hash: The preimage cleared from storage #[precompile::public("unnotePreimage(bytes32)")] fn unnote_preimage(handle: &mut impl PrecompileHandle, hash: H256) -> EvmResult { let hash: Runtime::Hash = hash diff --git a/precompiles/preimage/src/mock.rs b/precompiles/preimage/src/mock.rs new file mode 100644 index 0000000000..ff8a59200e --- /dev/null +++ b/precompiles/preimage/src/mock.rs @@ -0,0 +1,156 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Test utilities +use super::*; +use frame_support::{ + construct_runtime, parameter_types, + traits::{Everything, GenesisBuild, OnFinalize, OnInitialize}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; +use precompile_utils::{ + precompile_set::*, + testing::{Alice, MockAccount}, +}; +use sp_core::{H256, U256}; +use sp_io; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + Perbill, Percent, +}; + +pub type AccountId = MockAccount; +pub type Balance = u128; +pub type BlockNumber = u32; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Evm: pallet_evm::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Preimage: pallet_preimage, + } +); + +parameter_types! { + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: Weight = Weight::from_ref_time(1024); + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const SS58Prefix: u8 = 42; +} + +impl frame_system::Config for Runtime { + type BaseCallFilter = Everything; + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = BlockNumber; + type RuntimeCall = RuntimeCall; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = sp_runtime::generic::Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type BlockWeights = (); + type BlockLength = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} +parameter_types! { + pub const ExistentialDeposit: u128 = 1; +} +impl pallet_balances::Config for Runtime { + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} + +parameter_types! { + pub BlockGasLimit: U256 = U256::max_value(); + pub PrecompilesValue: Precompiles = Precompiles::new(); + pub const WeightPerGas: Weight = Weight::from_ref_time(1); +} + +pub type Precompiles = + PrecompileSetBuilder, PreimagePrecompile>,)>; + +pub type PCall = PreimagePrecompileCall; + +impl pallet_evm::Config for Runtime { + type FeeCalculator = (); + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = AccountId; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type Runner = pallet_evm::runner::stack::Runner; + type PrecompilesType = Precompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = (); + type OnChargeTransaction = (); + type BlockGasLimit = BlockGasLimit; + type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping; + type FindAuthor = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +impl pallet_preimage::Config for Runtime { + type WeightInfo = (); + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type BaseDeposit = ExistentialDeposit; + type ByteDeposit = ExistentialDeposit; +} + +// genesis builder TODO diff --git a/precompiles/preimage/src/tests.rs b/precompiles/preimage/src/tests.rs new file mode 100644 index 0000000000..72306d4311 --- /dev/null +++ b/precompiles/preimage/src/tests.rs @@ -0,0 +1,42 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . +use crate::mock::*; +use precompile_utils::testing::*; + +#[test] +fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() { + for file in ["Preimage.sol"] { + for solidity_fn in solidity::get_selectors(file) { + assert_eq!( + solidity_fn.compute_selector_hex(), + solidity_fn.docs_selector, + "documented selector for '{}' did not match for file '{}'", + solidity_fn.signature(), + file, + ); + + let selector = solidity_fn.compute_selector(); + if !PCall::supports_selector(selector) { + panic!( + "failed decoding selector 0x{:x} => '{}' as Action for file '{}'", + selector, + solidity_fn.signature(), + file, + ) + } + } + } +} \ No newline at end of file diff --git a/precompiles/referenda/src/tests.rs b/precompiles/referenda/src/tests.rs index 7dea840ef6..6692c739dc 100644 --- a/precompiles/referenda/src/tests.rs +++ b/precompiles/referenda/src/tests.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . - +use crate::mock::*; use precompile_utils::testing::*; #[test] From b784acacf58e5ea5f2eea944a03e680be821fcfd Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Mon, 9 Jan 2023 13:58:22 -0500 Subject: [PATCH 25/52] add to moonbase precompiles --- Cargo.lock | 3 +++ precompiles/referenda/src/lib.rs | 2 +- runtime/moonbase/Cargo.toml | 6 ++++++ runtime/moonbase/src/precompiles.rs | 6 ++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 3d2b12b459..ae0bd0db01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4886,13 +4886,16 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-call-permit", "pallet-evm-precompile-collective", + "pallet-evm-precompile-conviction-voting", "pallet-evm-precompile-crowdloan-rewards", "pallet-evm-precompile-democracy", "pallet-evm-precompile-dispatch", "pallet-evm-precompile-modexp", "pallet-evm-precompile-parachain-staking", + "pallet-evm-precompile-preimage", "pallet-evm-precompile-proxy", "pallet-evm-precompile-randomness", + "pallet-evm-precompile-referenda", "pallet-evm-precompile-relay-encoder", "pallet-evm-precompile-sha3fips", "pallet-evm-precompile-simple", diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 3703018539..145af120dc 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -26,7 +26,7 @@ use pallet_evm::AddressMapping; use pallet_referenda::{Call as ReferendaCall, DecidingCount, ReferendumCount, TracksInfo}; use precompile_utils::prelude::*; use sp_core::U256; -use sp_std::marker::PhantomData; +use sp_std::{boxed::Box, marker::PhantomData}; #[cfg(test)] mod mock; diff --git a/runtime/moonbase/Cargo.toml b/runtime/moonbase/Cargo.toml index 5141726014..a2217cbb27 100644 --- a/runtime/moonbase/Cargo.toml +++ b/runtime/moonbase/Cargo.toml @@ -47,11 +47,14 @@ pallet-evm-precompile-balances-erc20 = { path = "../../precompiles/balances-erc2 pallet-evm-precompile-batch = { path = "../../precompiles/batch", default-features = false } pallet-evm-precompile-call-permit = { path = "../../precompiles/call-permit", default-features = false } pallet-evm-precompile-collective = { path = "../../precompiles/collective", default-features = false } +pallet-evm-precompile-conviction-voting = { path = "../../precompiles/conviction-voting", default-features = false } pallet-evm-precompile-crowdloan-rewards = { path = "../../precompiles/crowdloan-rewards", default-features = false } pallet-evm-precompile-democracy = { path = "../../precompiles/pallet-democracy", default-features = false } pallet-evm-precompile-parachain-staking = { path = "../../precompiles/parachain-staking", default-features = false } +pallet-evm-precompile-preimage = { path = "../../precompiles/preimage", default-features = false } pallet-evm-precompile-proxy = { path = "../../precompiles/proxy", default-features = false } pallet-evm-precompile-randomness = { path = "../../precompiles/randomness", default-features = false } +pallet-evm-precompile-referenda = { path = "../../precompiles/referenda", default-features = false } pallet-evm-precompile-relay-encoder = { path = "../../precompiles/relay-encoder", default-features = false } pallet-evm-precompile-xcm-transactor = { path = "../../precompiles/xcm-transactor", default-features = false } pallet-evm-precompile-xcm-utils = { path = "../../precompiles/xcm-utils", default-features = false } @@ -208,9 +211,12 @@ std = [ "pallet-evm-precompile-batch/std", "pallet-evm-precompile-call-permit/std", "pallet-evm-precompile-collective/std", + "pallet-evm-precompile-conviction-voting/std", "pallet-evm-precompile-democracy/std", "pallet-evm-precompile-parachain-staking/std", + "pallet-evm-precompile-preimage/std", "pallet-evm-precompile-randomness/std", + "pallet-evm-precompile-referenda/std", "pallet-evm-precompile-xcm-transactor/std", "pallet-evm-precompile-xcm-utils/std", "pallet-evm-precompile-xtokens/std", diff --git a/runtime/moonbase/src/precompiles.rs b/runtime/moonbase/src/precompiles.rs index 51fcf743ec..7999f3b677 100644 --- a/runtime/moonbase/src/precompiles.rs +++ b/runtime/moonbase/src/precompiles.rs @@ -28,12 +28,15 @@ use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_call_permit::CallPermitPrecompile; use pallet_evm_precompile_collective::CollectivePrecompile; +use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile; use pallet_evm_precompile_crowdloan_rewards::CrowdloanRewardsPrecompile; use pallet_evm_precompile_democracy::DemocracyPrecompile; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_parachain_staking::ParachainStakingPrecompile; +use pallet_evm_precompile_preimage::PreimagePrecompile; use pallet_evm_precompile_proxy::ProxyPrecompile; use pallet_evm_precompile_randomness::RandomnessPrecompile; +use pallet_evm_precompile_referenda::ReferendaPrecompile; use pallet_evm_precompile_relay_encoder::RelayEncoderPrecompile; use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; @@ -131,6 +134,9 @@ pub type MoonbasePrecompiles = PrecompileSetBuilder< PrecompileAt, CollectivePrecompile>, PrecompileAt, CollectivePrecompile>, PrecompileAt, CollectivePrecompile>, + PrecompileAt, ReferendaPrecompile>, + PrecompileAt, ConvictionVotingPrecompile>, + PrecompileAt, PreimagePrecompile>, ), >, // Prefixed precompile sets (XC20) From f1c55b5216d60ea80cd7f9a9b2b1e97bb0bb82bc Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 10 Jan 2023 11:02:19 -0500 Subject: [PATCH 26/52] fix --- .../conviction-voting/ConvictionVoting.sol | 25 +++++++++------- precompiles/conviction-voting/src/lib.rs | 10 +++---- precompiles/conviction-voting/src/mock.rs | 29 +++++++++---------- precompiles/conviction-voting/src/tests.rs | 4 +-- precompiles/preimage/Preimage.sol | 12 ++++---- precompiles/preimage/src/lib.rs | 8 ++--- precompiles/preimage/src/mock.rs | 14 ++------- precompiles/preimage/src/tests.rs | 2 +- precompiles/referenda/Referenda.sol | 18 ++++++------ precompiles/referenda/src/lib.rs | 4 +-- precompiles/referenda/src/mock.rs | 13 ++------- precompiles/referenda/src/tests.rs | 2 +- 12 files changed, 63 insertions(+), 78 deletions(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index 4547c419b0..1014ca845b 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -15,12 +15,12 @@ ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( /// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS interface ConvictionVoting { /// @dev Vote in a poll. - /// @custom:selector 74a34dd3 + /// @custom:selector 6cd18b0d /// @param pollIndex Index of poll /// @param aye Yes or no vote /// @param voteAmount Balance locked for vote /// @param conviction Conviction multiplier for length of vote lock - function standard_vote( + function standardVote( uint256 pollIndex, bool aye, uint256 voteAmount, @@ -28,18 +28,23 @@ interface ConvictionVoting { ) external; /// @dev Remove vote in poll - /// @custom:selector 74a34dd3 + /// @custom:selector 3f68fde4 /// @param pollIndex Index of the poll - function remove_vote(uint256 pollIndex) external; + function removeVote(uint256 pollIndex) external; /// @dev Remove vote in poll for other voter - /// @custom:selector 74a34dd3 - /// @param class The class + /// @custom:selector 135ef12d + //// @param target The voter to have vote removed + /// @param class The class /// @param pollIndex the poll index - function remove_other_vote(uint256 class, uint256 pollIndex) external; + function removeOtherVote( + address target, + uint256 class, + uint256 pollIndex + ) external; /// @dev Delegate to a representative for the vote class - /// @custom:selector 74a34dd3 + /// @custom:selector 7efe44c7 /// @param class The class /// @param representative The representative for the class /// @param conviction The conviction multiplier @@ -52,12 +57,12 @@ interface ConvictionVoting { ) external; /// @dev Undelegate for the vote class - /// @custom:selector 74a34dd3 + /// @custom:selector 6c68c0e1 /// @param class The class function undelegate(uint256 class) external; /// @dev Unlock tokens locked for vote class - /// @custom:selector 74a34dd3 + /// @custom:selector f1d2ec1d /// @param class The class /// @param target The target address function unlock(uint256 class, address target) external; diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 01927fd5fd..e854a4b397 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -28,10 +28,10 @@ use sp_core::{H160, H256, U256}; use sp_runtime::traits::StaticLookup; use sp_std::marker::PhantomData; -// #[cfg(test)] -// mod mock; -// #[cfg(test)] -// mod tests; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; type BalanceOf = <::Currency as Currency< ::AccountId, @@ -192,7 +192,7 @@ where Ok(()) } - #[precompile::public("unDelegate(uint256)")] + #[precompile::public("undelegate(uint256)")] fn undelegate( handle: &mut impl PrecompileHandle, class: SolidityConvert, diff --git a/precompiles/conviction-voting/src/mock.rs b/precompiles/conviction-voting/src/mock.rs index f181cb7c68..fbbc8b86ff 100644 --- a/precompiles/conviction-voting/src/mock.rs +++ b/precompiles/conviction-voting/src/mock.rs @@ -18,23 +18,16 @@ use super::*; use frame_support::{ construct_runtime, parameter_types, - traits::{ - Everything, GenesisBuild, OnFinalize, OnInitialize, PollStatus, Polling, TotalIssuanceOf, - }, + traits::{Everything, PollStatus, Polling, TotalIssuanceOf}, weights::Weight, }; -use frame_system::EnsureRoot; use pallet_conviction_voting::TallyOf; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; -use precompile_utils::{ - precompile_set::*, - testing::{Alice, MockAccount}, -}; +use precompile_utils::{precompile_set::*, testing::MockAccount}; use sp_core::{H256, U256}; -use sp_io; use sp_runtime::{ - traits::{BlakeTwo256, ConstU32, ConstU64, IdentityLookup}, - DispatchError, Perbill, Percent, + traits::{BlakeTwo256, ConstU32, IdentityLookup}, + DispatchError, Perbill, }; use sp_std::collections::btree_map::BTreeMap; @@ -183,7 +176,7 @@ impl Polling> for TestPolls { } fn access_poll( index: Self::Index, - f: impl FnOnce(PollStatus<&mut TallyOf, u64, u8>) -> R, + f: impl FnOnce(PollStatus<&mut TallyOf, u32, u8>) -> R, ) -> R { let mut polls = Polls::get(); let entry = polls.get_mut(&index); @@ -191,7 +184,10 @@ impl Polling> for TestPolls { Some(Ongoing(ref mut tally_mut_ref, class)) => { f(PollStatus::Ongoing(tally_mut_ref, *class)) } - Some(Completed(when, succeeded)) => f(PollStatus::Completed(*when, *succeeded)), + Some(Completed(when, succeeded)) => f(PollStatus::Completed( + (*when).try_into().unwrap(), + *succeeded, + )), None => f(PollStatus::None), }; Polls::set(polls); @@ -199,7 +195,7 @@ impl Polling> for TestPolls { } fn try_access_poll( index: Self::Index, - f: impl FnOnce(PollStatus<&mut TallyOf, u64, u8>) -> Result, + f: impl FnOnce(PollStatus<&mut TallyOf, u32, u8>) -> Result, ) -> Result { let mut polls = Polls::get(); let entry = polls.get_mut(&index); @@ -207,7 +203,10 @@ impl Polling> for TestPolls { Some(Ongoing(ref mut tally_mut_ref, class)) => { f(PollStatus::Ongoing(tally_mut_ref, *class)) } - Some(Completed(when, succeeded)) => f(PollStatus::Completed(*when, *succeeded)), + Some(Completed(when, succeeded)) => f(PollStatus::Completed( + (*when).try_into().unwrap(), + *succeeded, + )), None => f(PollStatus::None), }?; Polls::set(polls); diff --git a/precompiles/conviction-voting/src/tests.rs b/precompiles/conviction-voting/src/tests.rs index 72306d4311..e0bfa7b747 100644 --- a/precompiles/conviction-voting/src/tests.rs +++ b/precompiles/conviction-voting/src/tests.rs @@ -18,7 +18,7 @@ use precompile_utils::testing::*; #[test] fn test_solidity_interface_has_all_function_selectors_documented_and_implemented() { - for file in ["Preimage.sol"] { + for file in ["ConvictionVoting.sol"] { for solidity_fn in solidity::get_selectors(file) { assert_eq!( solidity_fn.compute_selector_hex(), @@ -39,4 +39,4 @@ fn test_solidity_interface_has_all_function_selectors_documented_and_implemented } } } -} \ No newline at end of file +} diff --git a/precompiles/preimage/Preimage.sol b/precompiles/preimage/Preimage.sol index 23468918f7..a52cddece1 100644 --- a/precompiles/preimage/Preimage.sol +++ b/precompiles/preimage/Preimage.sol @@ -13,14 +13,12 @@ Preimage constant Preimage_CONTRACT = Preimage(Preimage_ADDRESS); /// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS interface Preimage { /// @dev Register a Preimage on-chain. - /// @custom:selector 74a34dd3 - /// @param encodedProposal - function note_preimage( - bytes memory encodedProposal, - ) external; + /// @custom:selector cb00f603 + /// @param encodedProposal The preimage to be registered on-chain + function notePreimage(bytes memory encodedProposal) external; /// @dev Clear an unrequested preimage from storage. - /// @custom:selector 74a34dd3 + /// @custom:selector 02e71b45 /// @param hash The preimage to be cleared from storage - function unnote_preimage(bytes32 hash) external; + function unnotePreimage(bytes32 hash) external; } diff --git a/precompiles/preimage/src/lib.rs b/precompiles/preimage/src/lib.rs index c0714b409e..58d7145ef4 100644 --- a/precompiles/preimage/src/lib.rs +++ b/precompiles/preimage/src/lib.rs @@ -26,10 +26,10 @@ use precompile_utils::prelude::*; use sp_core::H256; use sp_std::marker::PhantomData; -// #[cfg(test)] -// mod mock; -// #[cfg(test)] -// mod tests; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; pub const ENCODED_PROPOSAL_SIZE_LIMIT: u32 = 2u32.pow(16); type GetEncodedProposalSizeLimit = ConstU32; diff --git a/precompiles/preimage/src/mock.rs b/precompiles/preimage/src/mock.rs index ff8a59200e..f81e10ad66 100644 --- a/precompiles/preimage/src/mock.rs +++ b/precompiles/preimage/src/mock.rs @@ -16,22 +16,14 @@ //! Test utilities use super::*; -use frame_support::{ - construct_runtime, parameter_types, - traits::{Everything, GenesisBuild, OnFinalize, OnInitialize}, - weights::Weight, -}; +use frame_support::{construct_runtime, parameter_types, traits::Everything, weights::Weight}; use frame_system::EnsureRoot; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; -use precompile_utils::{ - precompile_set::*, - testing::{Alice, MockAccount}, -}; +use precompile_utils::{precompile_set::*, testing::MockAccount}; use sp_core::{H256, U256}; -use sp_io; use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, - Perbill, Percent, + Perbill, }; pub type AccountId = MockAccount; diff --git a/precompiles/preimage/src/tests.rs b/precompiles/preimage/src/tests.rs index 72306d4311..8508f747d7 100644 --- a/precompiles/preimage/src/tests.rs +++ b/precompiles/preimage/src/tests.rs @@ -39,4 +39,4 @@ fn test_solidity_interface_has_all_function_selectors_documented_and_implemented } } } -} \ No newline at end of file +} diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index ed7d6d3748..25ec70bb87 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -26,21 +26,21 @@ interface Referenda { } /// Return the total referendum count - /// @custom:selector 81797566 + /// @custom:selector 3a42ee31 function referendumCount() external view returns (uint256); /// Return the submission deposit for all referenda - /// @custom:selector 81797566 + /// @custom:selector aa14c39a function submissionDeposit() external view returns (uint256); /// Return the total count of deciding referenda per track /// @param trackId The track identifier - /// @custom:selector 81797566 + /// @custom:selector 23cbda16 function decidingCount(uint256 trackId) external view returns (uint256); /// Return the total count of deciding referenda per track /// @param trackId The track identifier - /// @custom:selector 81797566 + /// @custom:selector 35028c55 function trackInfo(uint256 trackId) external view @@ -54,7 +54,7 @@ interface Referenda { ); /// @dev Submit a referenda - /// @custom:selector 74a34dd3 + /// @custom:selector d865f8e8 /// @param origin The origin from which the proposed referenda would be dispatched /// @param hash Hash of the proposal preimage /// @param at If true then AT block_number, else AFTER block_number @@ -67,12 +67,12 @@ interface Referenda { ) external; /// @dev Post the Decision Deposit for a referendum - /// @custom:selector 74a34dd3 + /// @custom:selector 245ce18d /// @param index The index of the ongoing referendum that is not yet deciding - function place_decision_deposit(uint32 index) external; + function placeDecisionDeposit(uint32 index) external; /// @dev Refund the Decision Deposit for a closed referendum back to the depositor - /// @custom:selector 74a34dd3 + /// @custom:selector 1325d528 /// @param index The index of a closed referendum with decision deposit still locked - function refund_decision_deposit(uint32 index) external; + function refundDecisionDeposit(uint32 index) external; } diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 145af120dc..8e1fc30595 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -30,8 +30,8 @@ use sp_std::{boxed::Box, marker::PhantomData}; #[cfg(test)] mod mock; -// #[cfg(test)] -// mod tests; +#[cfg(test)] +mod tests; pub const CALL_DATA_LIMIT: u32 = 2u32.pow(16); diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs index a707f02300..fb5a588afa 100644 --- a/precompiles/referenda/src/mock.rs +++ b/precompiles/referenda/src/mock.rs @@ -17,10 +17,8 @@ //! A minimal precompile runtime including the pallet-randomness pallet use super::*; use frame_support::{ - construct_runtime, ord_parameter_types, parameter_types, - traits::{ - ConstU128, ConstU32, ConstU64, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally, - }, + construct_runtime, parameter_types, + traits::{ConstU128, ConstU32, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally}, weights::Weight, }; use frame_system::{EnsureRoot, EnsureSigned, EnsureSignedBy}; @@ -376,10 +374,3 @@ impl ExtBuilder { ext } } - -pub(crate) fn events() -> Vec { - System::events() - .into_iter() - .map(|r| r.event) - .collect::>() -} diff --git a/precompiles/referenda/src/tests.rs b/precompiles/referenda/src/tests.rs index 6692c739dc..6c7a3070e5 100644 --- a/precompiles/referenda/src/tests.rs +++ b/precompiles/referenda/src/tests.rs @@ -39,4 +39,4 @@ fn test_solidity_interface_has_all_function_selectors_documented_and_implemented } } } -} \ No newline at end of file +} From 58620edd7f9108f76a2192e3fb8b7d7f48e5eced Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 10 Jan 2023 12:37:00 -0500 Subject: [PATCH 27/52] precompile existence test fix --- runtime/moonbase/tests/integration_test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/moonbase/tests/integration_test.rs b/runtime/moonbase/tests/integration_test.rs index fc1041fae8..b9ae1f371b 100644 --- a/runtime/moonbase/tests/integration_test.rs +++ b/runtime/moonbase/tests/integration_test.rs @@ -2912,7 +2912,7 @@ fn precompile_existence() { let precompiles = Precompiles::new(); let precompile_addresses: std::collections::BTreeSet<_> = vec![ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1024, 1026, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, - 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, + 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, ] .into_iter() .map(H160::from_low_u64_be) From 6ed417f958c03edf14e91ba94f8a7adbb4960f73 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 10 Jan 2023 13:25:00 -0500 Subject: [PATCH 28/52] update solidity addresses as per moonbase config --- precompiles/conviction-voting/ConvictionVoting.sol | 6 +++--- precompiles/preimage/Preimage.sol | 6 +++--- precompiles/referenda/Referenda.sol | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index 1014ca845b..48ea63683b 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.3; -/// @dev The Conviction Voting contract's address. TODO: UPDATE ADDRESS -address constant Conviction_Voting_ADDRESS = 0x000000000000000000000000000000000000080b; +/// @dev The Conviction Voting contract's address. +address constant Conviction_Voting_ADDRESS = 0x0000000000000000000000000000000000000812; /// @dev The Conviction Voting contract's instance. ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( @@ -12,7 +12,7 @@ ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( /// @author The Moonbeam Team /// @title Pallet Conviction Voting Interface /// @title The interface through which solidity contracts will interact with the Conviction Voting pallet -/// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS +/// @custom:address 0x0000000000000000000000000000000000000812 interface ConvictionVoting { /// @dev Vote in a poll. /// @custom:selector 6cd18b0d diff --git a/precompiles/preimage/Preimage.sol b/precompiles/preimage/Preimage.sol index a52cddece1..52ce716914 100644 --- a/precompiles/preimage/Preimage.sol +++ b/precompiles/preimage/Preimage.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.3; -/// @dev The Preimage contract's address. TODO: UPDATE ADDRESS -address constant Preimage_ADDRESS = 0x000000000000000000000000000000000000080b; +/// @dev The Preimage contract's address. +address constant Preimage_ADDRESS = 0x0000000000000000000000000000000000000813; /// @dev The Preimage contract's instance. Preimage constant Preimage_CONTRACT = Preimage(Preimage_ADDRESS); @@ -10,7 +10,7 @@ Preimage constant Preimage_CONTRACT = Preimage(Preimage_ADDRESS); /// @author The Moonbeam Team /// @title Pallet Preimage Interface /// @title The interface through which solidity contracts will interact with the Preimage pallet -/// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS +/// @custom:address 0x0000000000000000000000000000000000000813 interface Preimage { /// @dev Register a Preimage on-chain. /// @custom:selector cb00f603 diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index 25ec70bb87..4c6196ba33 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.3; -/// @dev The Referenda contract's address. TODO: UPDATE ADDRESS -address constant REFERENDA_ADDRESS = 0x000000000000000000000000000000000000080b; +/// @dev The Referenda contract's address. +address constant REFERENDA_ADDRESS = 0x0000000000000000000000000000000000000811; /// @dev The Referenda contract's instance. Referenda constant REFERENDA_CONTRACT = Referenda(REFERENDA_ADDRESS); @@ -10,7 +10,7 @@ Referenda constant REFERENDA_CONTRACT = Referenda(REFERENDA_ADDRESS); /// @author The Moonbeam Team /// @title Pallet Referenda Interface /// @title The interface through which solidity contracts will interact with the Referenda pallet -/// @custom:address 0x000000000000000000000000000000000000080b TODO: UPDATE ADDRESS +/// @custom:address 0x0000000000000000000000000000000000000811 interface Referenda { /// @dev Defines the referenda origins that have tracks corresponding to uint8 representation /// The uint8 representation is defined in pallet-governance-origins Into for Origin From 2fcef74f56d122f466a4de85b5d1425668b810bc Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 10 Jan 2023 23:16:57 -0500 Subject: [PATCH 29/52] rename standard vote to vote in conviction voting pallet --- precompiles/conviction-voting/ConvictionVoting.sol | 4 ++-- precompiles/conviction-voting/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index 48ea63683b..0754f2679a 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -15,12 +15,12 @@ ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( /// @custom:address 0x0000000000000000000000000000000000000812 interface ConvictionVoting { /// @dev Vote in a poll. - /// @custom:selector 6cd18b0d + /// @custom:selector f56cb3b3 /// @param pollIndex Index of poll /// @param aye Yes or no vote /// @param voteAmount Balance locked for vote /// @param conviction Conviction multiplier for length of vote lock - function standardVote( + function vote( uint256 pollIndex, bool aye, uint256 voteAmount, diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index e854a4b397..007266bc64 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -77,8 +77,8 @@ where /// * aye: Yes or no vote /// * vote_amount: Balance locked for vote /// * conviction: Conviction multiplier for length of vote lock - #[precompile::public("standardVote(uint256,bool,uint256,uint256)")] - fn standard_vote( + #[precompile::public("vote(uint256,bool,uint256,uint256)")] + fn vote( handle: &mut impl PrecompileHandle, poll_index: SolidityConvert, aye: bool, From 87235894a51ba4c9f539b5b9ededb15ea177cc01 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 11 Jan 2023 11:16:57 -0500 Subject: [PATCH 30/52] start moving origins out of pallet and using additional generic instead --- Cargo.lock | 15 ------------ Cargo.toml | 1 - pallets/governance-origins/Cargo.toml | 24 ------------------- precompiles/conviction-voting/Cargo.toml | 2 -- precompiles/conviction-voting/src/lib.rs | 3 +-- precompiles/preimage/Cargo.toml | 2 -- precompiles/referenda/Cargo.toml | 2 -- precompiles/referenda/Referenda.sol | 2 +- precompiles/referenda/src/lib.rs | 18 ++++++-------- precompiles/referenda/src/mock.rs | 17 +++++++------ runtime/moonbase/Cargo.toml | 3 --- runtime/moonbase/src/governance/mod.rs | 3 ++- .../moonbase/src/governance/origins.rs | 0 runtime/moonbase/src/governance/tracks.rs | 2 +- 14 files changed, 20 insertions(+), 74 deletions(-) delete mode 100644 pallets/governance-origins/Cargo.toml rename pallets/governance-origins/src/lib.rs => runtime/moonbase/src/governance/origins.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index ae0bd0db01..43181c6956 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4903,7 +4903,6 @@ dependencies = [ "pallet-evm-precompile-xcm-utils", "pallet-evm-precompile-xtokens", "pallet-evm-precompileset-assets-erc20", - "pallet-governance-origins", "pallet-identity", "pallet-maintenance-mode", "pallet-migrations", @@ -6982,7 +6981,6 @@ dependencies = [ "pallet-balances", "pallet-conviction-voting", "pallet-evm", - "pallet-governance-origins", "pallet-timestamp", "parity-scale-codec", "precompile-utils", @@ -7112,7 +7110,6 @@ dependencies = [ "num_enum", "pallet-balances", "pallet-evm", - "pallet-governance-origins", "pallet-preimage", "pallet-timestamp", "parity-scale-codec", @@ -7196,7 +7193,6 @@ dependencies = [ "num_enum", "pallet-balances", "pallet-evm", - "pallet-governance-origins", "pallet-preimage", "pallet-referenda", "pallet-scheduler", @@ -7423,17 +7419,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-governance-origins" -version = "0.1.0" -dependencies = [ - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-std", -] - [[package]] name = "pallet-grandpa" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index 1a54d23e4c..191e8b2ce5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "node", "node/cli", "node/service", - "pallets/governance-origins", "pallets/maintenance-mode", "pallets/migrations", "pallets/moonbeam-orbiters", diff --git a/pallets/governance-origins/Cargo.toml b/pallets/governance-origins/Cargo.toml deleted file mode 100644 index 71d0d28af2..0000000000 --- a/pallets/governance-origins/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "pallet-governance-origins" -authors = [ "PureStake" ] -description = "Custom origins for governance interventions" -edition = "2021" -version = "0.1.0" - -[dependencies] -frame-support = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } -frame-system = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } -parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive" ] } -scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } -sp-std = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } - -[features] -default = [ "std" ] -std = [ - "frame-support/std", - "frame-system/std", - "parity-scale-codec/std", - "scale-info/std", - "sp-std/std", -] -runtime-benchmarks = [] diff --git a/precompiles/conviction-voting/Cargo.toml b/precompiles/conviction-voting/Cargo.toml index 57edc607ae..26214880c4 100644 --- a/precompiles/conviction-voting/Cargo.toml +++ b/precompiles/conviction-voting/Cargo.toml @@ -11,7 +11,6 @@ num_enum = { version = "0.5.3", default-features = false } rustc-hex = { version = "2.0.1", default-features = false } # Moonbeam -pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } precompile-utils = { path = "../utils", default-features = false } # Substrate @@ -50,7 +49,6 @@ std = [ "frame-system/std", "pallet-conviction-voting/std", "pallet-evm/std", - "pallet-governance-origins/std", "parity-scale-codec/std", "parity-scale-codec/std", "precompile-utils/std", diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 007266bc64..b3b7e42ba5 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -24,7 +24,7 @@ use pallet_conviction_voting::Call as ConvictionVotingCall; use pallet_conviction_voting::{AccountVote, Conviction, Tally, Vote}; use pallet_evm::AddressMapping; use precompile_utils::prelude::*; -use sp_core::{H160, H256, U256}; +use sp_core::{H160, U256}; use sp_runtime::traits::StaticLookup; use sp_std::marker::PhantomData; @@ -61,7 +61,6 @@ impl ConvictionVotingPrecompile where Runtime: pallet_conviction_voting::Config + pallet_evm::Config + frame_system::Config, BalanceOf: TryFrom, - ::Hash: TryFrom, ::RuntimeCall: Dispatchable + GetDispatchInfo, <::RuntimeCall as Dispatchable>::RuntimeOrigin: diff --git a/precompiles/preimage/Cargo.toml b/precompiles/preimage/Cargo.toml index 04d86dbb94..c84fcf3ee1 100644 --- a/precompiles/preimage/Cargo.toml +++ b/precompiles/preimage/Cargo.toml @@ -11,7 +11,6 @@ num_enum = { version = "0.5.3", default-features = false } rustc-hex = { version = "2.0.1", default-features = false } # Moonbeam -pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } precompile-utils = { path = "../utils", default-features = false } # Substrate @@ -49,7 +48,6 @@ std = [ "frame-support/std", "frame-system/std", "pallet-evm/std", - "pallet-governance-origins/std", "pallet-preimage/std", "parity-scale-codec/std", "parity-scale-codec/std", diff --git a/precompiles/referenda/Cargo.toml b/precompiles/referenda/Cargo.toml index 3cf87ed05d..d91094f1f9 100644 --- a/precompiles/referenda/Cargo.toml +++ b/precompiles/referenda/Cargo.toml @@ -11,7 +11,6 @@ num_enum = { version = "0.5.3", default-features = false } rustc-hex = { version = "2.0.1", default-features = false } # Moonbeam -pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } precompile-utils = { path = "../utils", default-features = false } # Substrate @@ -51,7 +50,6 @@ std = [ "frame-support/std", "frame-system/std", "pallet-evm/std", - "pallet-governance-origins/std", "pallet-referenda/std", "parity-scale-codec/std", "parity-scale-codec/std", diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index 4c6196ba33..f70f2897b0 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -13,7 +13,7 @@ Referenda constant REFERENDA_CONTRACT = Referenda(REFERENDA_ADDRESS); /// @custom:address 0x0000000000000000000000000000000000000811 interface Referenda { /// @dev Defines the referenda origins that have tracks corresponding to uint8 representation - /// The uint8 representation is defined in pallet-governance-origins Into for Origin + /// The uint8 representation is defined in origins pallet Into for Origin /// From top to bottom: 1, 10, 11, 12, 13, 14, 15 enum Origin { WhitelistedCaller, diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 8e1fc30595..26bcd25f69 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -49,16 +49,13 @@ type OriginOf = <::RuntimeOrigin as OriginTrait>::PalletsOrigin; /// A precompile to wrap the functionality from pallet-referenda. -pub struct ReferendaPrecompile(PhantomData); +pub struct ReferendaPrecompile>(PhantomData<(Runtime, GovOrigin)>); #[precompile_utils::precompile] -impl ReferendaPrecompile +impl> ReferendaPrecompile where - Runtime: pallet_referenda::Config - + pallet_evm::Config - + frame_system::Config - + pallet_governance_origins::Config, - OriginOf: From, + Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, + OriginOf: From, ::RuntimeCall: Dispatchable + GetDispatchInfo, <::RuntimeCall as Dispatchable>::RuntimeOrigin: @@ -158,10 +155,9 @@ where at: bool, block_number: u32, ) -> EvmResult { - let gov_origin: pallet_governance_origins::Origin = - proposal_origin.try_into().map_err(|_| { - RevertReason::custom("Origin does not exist for u8").in_field("proposal_origin") - })?; + let gov_origin: GovOrigin = proposal_origin.try_into().map_err(|_| { + RevertReason::custom("Origin does not exist for u8").in_field("proposal_origin") + })?; let proposal_origin: Box> = Box::new(gov_origin.into()); let proposal: BoundedCallOf = Bounded::Inline( frame_support::BoundedVec::try_from(proposal.as_bytes().to_vec()).map_err(|_| { diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs index fb5a588afa..28b2ac3aaa 100644 --- a/precompiles/referenda/src/mock.rs +++ b/precompiles/referenda/src/mock.rs @@ -55,7 +55,6 @@ construct_runtime!( Preimage: pallet_preimage, Scheduler: pallet_scheduler, Referenda: pallet_referenda, - GovernanceOrigins: pallet_governance_origins::{Pallet, Origin}, } ); @@ -111,12 +110,12 @@ impl pallet_balances::Config for Runtime { pub type TestPrecompiles = PrecompileSetBuilder< R, ( - PrecompileAt, ReferendaPrecompile, LimitRecursionTo<1>>, + PrecompileAt, ReferendaPrecompile, LimitRecursionTo<1>>, RevertPrecompile>, ), >; -pub type PCall = ReferendaPrecompileCall; +pub type PCall = ReferendaPrecompileCall; parameter_types! { pub PrecompilesValue: TestPrecompiles = TestPrecompiles::new(); @@ -328,12 +327,12 @@ impl pallet_referenda::Config for Runtime { type Preimages = Preimage; } -impl pallet_governance_origins::Config for Runtime { - type Currency = pallet_balances::Pallet; - type MaxSmallSpenderSpend = ConstU128<1>; - type MaxMediumSpenderSpend = ConstU128<1>; - type MaxBigSpenderSpend = ConstU128<1>; - type MaxTreasurerSpend = ConstU128<1>; +pub struct GovOrigin; +impl TryFrom for GovOrigin { + type Error = (); + fn try_from(_input: u8) -> Result { + Ok(GovOrigin) + } } /// Externality builder for pallet referenda mock runtime diff --git a/runtime/moonbase/Cargo.toml b/runtime/moonbase/Cargo.toml index a2217cbb27..163fa2d62e 100644 --- a/runtime/moonbase/Cargo.toml +++ b/runtime/moonbase/Cargo.toml @@ -32,7 +32,6 @@ pallet-author-mapping = { path = "../../pallets/author-mapping", default-feature pallet-crowdloan-rewards = { git = "https://github.com/purestake/crowdloan-rewards", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-ethereum-chain-id = { path = "../../pallets/ethereum-chain-id", default-features = false } pallet-ethereum-xcm = { path = "../../pallets/ethereum-xcm", default-features = false } -pallet-governance-origins = { path = "../../pallets/governance-origins", default-features = false } pallet-maintenance-mode = { path = "../../pallets/maintenance-mode", default-features = false, features = [ "xcm-support" ] } pallet-migrations = { path = "../../pallets/migrations", default-features = false } pallet-moonbeam-orbiters = { path = "../../pallets/moonbeam-orbiters", default-features = false } @@ -222,7 +221,6 @@ std = [ "pallet-evm-precompile-xtokens/std", "pallet-evm-precompileset-assets-erc20/std", "pallet-evm/std", - "pallet-governance-origins/std", "pallet-identity/std", "pallet-maintenance-mode/std", "pallet-migrations/std", @@ -300,7 +298,6 @@ runtime-benchmarks = [ "pallet-crowdloan-rewards/runtime-benchmarks", "pallet-ethereum-xcm/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", - "pallet-governance-origins/runtime-benchmarks", "pallet-migrations/runtime-benchmarks", "pallet-moonbeam-orbiters/runtime-benchmarks", "pallet-parachain-staking/runtime-benchmarks", diff --git a/runtime/moonbase/src/governance/mod.rs b/runtime/moonbase/src/governance/mod.rs index 831d624ece..5d90fe7d74 100644 --- a/runtime/moonbase/src/governance/mod.rs +++ b/runtime/moonbase/src/governance/mod.rs @@ -22,7 +22,8 @@ pub mod referenda; use super::*; -pub use pallet_governance_origins::{ +mod origins; +pub use origins::{ governance_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, }; mod tracks; diff --git a/pallets/governance-origins/src/lib.rs b/runtime/moonbase/src/governance/origins.rs similarity index 100% rename from pallets/governance-origins/src/lib.rs rename to runtime/moonbase/src/governance/origins.rs diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index 82393cc29b..1317eb7d73 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -170,7 +170,7 @@ impl pallet_referenda::TracksInfo for TracksInfo { _ => Err(()), } } else if let Ok(custom_origin) = governance_origins::Origin::try_from(id.clone()) { - // Origins => TrackId defined in Into for Origin (in pallet-governance-origins) + // Origins => TrackId defined in Into for Origin Ok(custom_origin.into()) } else { Err(()) From a1f469ec19cb40d5ca6d45ecb1725c9cf4a80b01 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Wed, 11 Jan 2023 14:19:32 -0500 Subject: [PATCH 31/52] fix finish moving pallet custom origins back into runtime --- precompiles/referenda/src/mock.rs | 12 +++++++++--- runtime/moonbase/src/governance/mod.rs | 2 +- runtime/moonbase/src/governance/origins.rs | 6 +++--- runtime/moonbase/src/governance/referenda.rs | 8 +++----- runtime/moonbase/src/governance/tracks.rs | 2 +- runtime/moonbase/src/lib.rs | 2 +- runtime/moonbase/src/precompiles.rs | 5 ++++- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs index 28b2ac3aaa..3bf21cb8c9 100644 --- a/precompiles/referenda/src/mock.rs +++ b/precompiles/referenda/src/mock.rs @@ -18,10 +18,10 @@ use super::*; use frame_support::{ construct_runtime, parameter_types, - traits::{ConstU128, ConstU32, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally}, + traits::{ConstU32, EqualPrivilegeOnly, Everything, SortedMembers, VoteTally}, weights::Weight, }; -use frame_system::{EnsureRoot, EnsureSigned, EnsureSignedBy}; +use frame_system::{EnsureRoot, EnsureSigned, EnsureSignedBy, RawOrigin}; use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; use pallet_referenda::{impl_tracksinfo_get, Curve, TrackInfo}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -330,11 +330,17 @@ impl pallet_referenda::Config for Runtime { pub struct GovOrigin; impl TryFrom for GovOrigin { type Error = (); - fn try_from(_input: u8) -> Result { + fn try_from(_i: u8) -> Result { Ok(GovOrigin) } } +impl From for OriginCaller { + fn from(_o: GovOrigin) -> OriginCaller { + OriginCaller::system(RawOrigin::Root) + } +} + /// Externality builder for pallet referenda mock runtime pub(crate) struct ExtBuilder { /// Balance amounts per AccountId diff --git a/runtime/moonbase/src/governance/mod.rs b/runtime/moonbase/src/governance/mod.rs index 5d90fe7d74..d4785f1a4d 100644 --- a/runtime/moonbase/src/governance/mod.rs +++ b/runtime/moonbase/src/governance/mod.rs @@ -24,7 +24,7 @@ use super::*; mod origins; pub use origins::{ - governance_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, + custom_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, }; mod tracks; pub use tracks::TracksInfo; diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs index 8dfa1a6d8c..72d75e8105 100644 --- a/runtime/moonbase/src/governance/origins.rs +++ b/runtime/moonbase/src/governance/origins.rs @@ -14,10 +14,10 @@ //! Custom origins for governance interventions. #![cfg_attr(not(feature = "std"), no_std)] -pub use governance_origins::*; +pub use custom_origins::*; #[frame_support::pallet] -pub mod governance_origins { +pub mod custom_origins { use frame_support::{pallet_prelude::*, traits::Currency}; type BalanceOf = @@ -179,7 +179,7 @@ pub mod governance_origins { } } - // Origins able to spend up = $AMOUNT from the treasury at once + // Origins able to spend $AMOUNT from treasury at once decl_ensure! { pub type Spender: EnsureOrigin> { SmallSpender = T::MaxSmallSpenderSpend::get(), diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index 95774e20c2..2d07922a23 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -55,12 +55,10 @@ parameter_types! { parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); } -pub type TreasurySpender = EitherOf< - EnsureRootWithSuccess, - pallet_governance_origins::Spender, ->; +pub type TreasurySpender = + EitherOf, custom_origins::Spender>; -impl pallet_governance_origins::Config for Runtime { +impl custom_origins::Config for Runtime { type Currency = Balances; type MaxSmallSpenderSpend = ConstU128<{ 200 * UNIT * SUPPLY_FACTOR }>; type MaxMediumSpenderSpend = ConstU128<{ 2000 * UNIT * SUPPLY_FACTOR }>; diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index 1317eb7d73..373b30df81 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -169,7 +169,7 @@ impl pallet_referenda::TracksInfo for TracksInfo { frame_system::RawOrigin::Root => Ok(0), _ => Err(()), } - } else if let Ok(custom_origin) = governance_origins::Origin::try_from(id.clone()) { + } else if let Ok(custom_origin) = custom_origins::Origin::try_from(id.clone()) { // Origins => TrackId defined in Into for Origin Ok(custom_origin.into()) } else { diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index 023a85b89a..b5d188ec04 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -1169,7 +1169,7 @@ construct_runtime! { pallet_collective::::{Pallet, Call, Storage, Event, Origin, Config} = 40, ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 41, Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 42, - Origins: pallet_governance_origins::{Origin} = 43, + Origins: governance::custom_origins::{Origin} = 43, Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 44, Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 45, } diff --git a/runtime/moonbase/src/precompiles.rs b/runtime/moonbase/src/precompiles.rs index 7999f3b677..6d91de8e2a 100644 --- a/runtime/moonbase/src/precompiles.rs +++ b/runtime/moonbase/src/precompiles.rs @@ -134,7 +134,10 @@ pub type MoonbasePrecompiles = PrecompileSetBuilder< PrecompileAt, CollectivePrecompile>, PrecompileAt, CollectivePrecompile>, PrecompileAt, CollectivePrecompile>, - PrecompileAt, ReferendaPrecompile>, + PrecompileAt< + AddressU64<2065>, + ReferendaPrecompile, + >, PrecompileAt, ConvictionVotingPrecompile>, PrecompileAt, PreimagePrecompile>, ), From e1f84caddd65fe2327d8fd0eee45bfdc0e454dca Mon Sep 17 00:00:00 2001 From: librelois Date: Thu, 12 Jan 2023 11:29:20 +0100 Subject: [PATCH 32/52] add opengov precompiles in proxy evm filter --- runtime/moonbase/src/lib.rs | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index cdfe05161c..f5430834d5 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -780,6 +780,19 @@ impl Default for ProxyType { } } +fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bool { + matches!( + precompile_name, + PrecompileName::DemocracyPrecompile + | PrecompileName::CouncilInstance + | PrecompileName::TechCommitteeInstance + | PrecompileName::TreasuryCouncilInstance + | PrecompileName::ReferendaPrecompile + | PrecompileName::ConvictionVotingPrecompile + | PrecompileName::PreimagePrecompile, + ) +} + use precompiles::PrecompileName; impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { // TODO: add opengov precompiles @@ -791,7 +804,6 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { use pallet_evm::PrecompileSet as _; match self { ProxyType::Any => { - // match PrecompileName::from_address(call.to.0) { // Any precompile that can execute a subcall should be forbidden here, // to ensure that unauthorized smart contract can't be called @@ -799,12 +811,9 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { // To be safe, we only allow the precompiles we need. Some( PrecompileName::AuthorMappingPrecompile - | PrecompileName::DemocracyPrecompile - | PrecompileName::ParachainStakingPrecompile - | PrecompileName::CouncilInstance - | PrecompileName::TechCommitteeInstance - | PrecompileName::TreasuryCouncilInstance, + | PrecompileName::ParachainStakingPrecompile, ) => true, + Some(ref precompile) if is_governance_precompile(precompile) => true, // All non-whitelisted precompiles are forbidden Some(_) => false, // Allow evm transfer to "simple" account (no code nor precompile) @@ -822,28 +831,20 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { } ProxyType::NonTransfer => { call.value == U256::default() - && matches!( - PrecompileName::from_address(call.to.0), + && match PrecompileName::from_address(call.to.0) { Some( PrecompileName::AuthorMappingPrecompile - | PrecompileName::DemocracyPrecompile - | PrecompileName::ParachainStakingPrecompile - | PrecompileName::CouncilInstance - | PrecompileName::TechCommitteeInstance - | PrecompileName::TreasuryCouncilInstance - ) - ) + | PrecompileName::ParachainStakingPrecompile, + ) => true, + Some(ref precompile) if is_governance_precompile(precompile) => true, + _ => false, + } } ProxyType::Governance => { call.value == U256::default() && matches!( PrecompileName::from_address(call.to.0), - Some( - PrecompileName::DemocracyPrecompile - | PrecompileName::CouncilInstance - | PrecompileName::TechCommitteeInstance - | PrecompileName::TreasuryCouncilInstance - ) + Some(ref precompile) if is_governance_precompile(precompile) ) } ProxyType::Staking => { From 6064e97d1aac32275132240d06c6ff7aa50aa0bf Mon Sep 17 00:00:00 2001 From: Amar Singh Date: Thu, 12 Jan 2023 10:12:47 -0500 Subject: [PATCH 33/52] SolidityConvert no longer necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éloïs Co-authored-by: Stephen Shelton --- precompiles/conviction-voting/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index b3b7e42ba5..2fdc84970e 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -79,13 +79,13 @@ where #[precompile::public("vote(uint256,bool,uint256,uint256)")] fn vote( handle: &mut impl PrecompileHandle, - poll_index: SolidityConvert, + poll_index: u32, aye: bool, vote_amount: U256, - conviction: SolidityConvert, + conviction: u8, ) -> EvmResult { let poll_index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; - let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; + let vote_amount = Self::u256_to_amount(vote_amount).in_field("vote_amount")?; let conviction = Self::u8_to_conviction(conviction.converted()).in_field("conviction")?; let vote = AccountVote::Standard { From 19c29140ce352c543707b0ee0bdfe726e216abbe Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 10:40:28 -0500 Subject: [PATCH 34/52] rm SolidityConvert and add Conviction enum --- .../conviction-voting/ConvictionVoting.sol | 14 ++++++- precompiles/conviction-voting/src/lib.rs | 42 +++++++------------ precompiles/referenda/src/lib.rs | 9 +--- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index 0754f2679a..1ff9b6015c 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -14,6 +14,18 @@ ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( /// @title The interface through which solidity contracts will interact with the Conviction Voting pallet /// @custom:address 0x0000000000000000000000000000000000000812 interface ConvictionVoting { + /// @dev Defines the conviction multiplier type represented as `uint8`. + /// The values start at `0` with 0.1x multiplier and votes unlocked. + enum Conviction { + None, + Locked1x, + Locked2x, + Locked3x, + Locked4x, + Locked5x, + Locked6x + } + /// @dev Vote in a poll. /// @custom:selector f56cb3b3 /// @param pollIndex Index of poll @@ -24,7 +36,7 @@ interface ConvictionVoting { uint256 pollIndex, bool aye, uint256 voteAmount, - uint256 conviction + Conviction conviction ) external; /// @dev Remove vote in poll diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 2fdc84970e..90f3a98d1c 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -84,9 +84,9 @@ where vote_amount: U256, conviction: u8, ) -> EvmResult { - let poll_index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; + let poll_index = Self::u32_to_index(poll_index).in_field("poll_index")?; let vote_amount = Self::u256_to_amount(vote_amount).in_field("vote_amount")?; - let conviction = Self::u8_to_conviction(conviction.converted()).in_field("conviction")?; + let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; let vote = AccountVote::Standard { vote: Vote { aye, conviction }, @@ -107,11 +107,8 @@ where } #[precompile::public("removeVote(uint256)")] - fn remove_vote( - handle: &mut impl PrecompileHandle, - poll_index: SolidityConvert, - ) -> EvmResult { - let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; + fn remove_vote(handle: &mut impl PrecompileHandle, poll_index: u32) -> EvmResult { + let index = Self::u32_to_index(poll_index).in_field("poll_index")?; log::trace!( target: "conviction-voting-precompile", @@ -131,11 +128,11 @@ where fn remove_other_vote( handle: &mut impl PrecompileHandle, target: Address, - class: SolidityConvert, - poll_index: SolidityConvert, + class: u16, + poll_index: u32, ) -> EvmResult { - let class = Self::u16_to_class(class.converted()).in_field("class")?; - let index = Self::u32_to_index(poll_index.converted()).in_field("poll_index")?; + let class = Self::u16_to_class(class).in_field("class")?; + let index = Self::u32_to_index(poll_index).in_field("poll_index")?; let target = Runtime::AddressMapping::into_account_id(target.into()); let target: ::Source = @@ -162,14 +159,14 @@ where #[precompile::public("delegate(uint256,address,uint256,uint256)")] fn delegate( handle: &mut impl PrecompileHandle, - class: SolidityConvert, + class: u16, representative: Address, - conviction: SolidityConvert, + conviction: u8, amount: U256, ) -> EvmResult { - let class = Self::u16_to_class(class.converted()).in_field("class")?; + let class = Self::u16_to_class(class).in_field("class")?; let amount = Self::u256_to_amount(amount).in_field("amount")?; - let conviction = Self::u8_to_conviction(conviction.converted()).in_field("conviction")?; + let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; log::trace!(target: "conviction-voting-precompile", "Delegating vote to {:?} with balance {:?} and conviction {:?}", @@ -192,11 +189,8 @@ where Ok(()) } #[precompile::public("undelegate(uint256)")] - fn undelegate( - handle: &mut impl PrecompileHandle, - class: SolidityConvert, - ) -> EvmResult { - let class = Self::u16_to_class(class.converted()).in_field("class")?; + fn undelegate(handle: &mut impl PrecompileHandle, class: u16) -> EvmResult { + let class = Self::u16_to_class(class).in_field("class")?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ConvictionVotingCall::::undelegate { class }; @@ -205,12 +199,8 @@ where Ok(()) } #[precompile::public("unlock(uint256,address)")] - fn unlock( - handle: &mut impl PrecompileHandle, - class: SolidityConvert, - target: Address, - ) -> EvmResult { - let class = Self::u16_to_class(class.converted()).in_field("class")?; + fn unlock(handle: &mut impl PrecompileHandle, class: u16, target: Address) -> EvmResult { + let class = Self::u16_to_class(class).in_field("class")?; let target: H160 = target.into(); let target = Runtime::AddressMapping::into_account_id(target); let target: ::Source = diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 26bcd25f69..310c68e929 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -90,14 +90,10 @@ where #[precompile::public("decidingCount(uint256)")] #[precompile::view] - fn deciding_count( - handle: &mut impl PrecompileHandle, - track_id: SolidityConvert, - ) -> EvmResult { + fn deciding_count(handle: &mut impl PrecompileHandle, track_id: u16) -> EvmResult { // Fetch data from pallet handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; let track_id: TrackIdOf = track_id - .converted() .try_into() .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) .in_field("track")?; @@ -115,12 +111,11 @@ where #[precompile::view] fn track_info( handle: &mut impl PrecompileHandle, - track_id: SolidityConvert, + track_id: u16, ) -> EvmResult<(U256, U256, U256, U256, U256, U256)> { // Fetch data from pallet handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; let track_id: TrackIdOf = track_id - .converted() .try_into() .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) .in_field("track")?; From 046a7ac1ef346ff140fafef225c741f37b9e7412 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 11:04:26 -0500 Subject: [PATCH 35/52] use trackId as input for submit instead of origin and convert from trackId to origin based on mapping --- precompiles/referenda/Referenda.sol | 18 +++--------------- precompiles/referenda/src/lib.rs | 8 ++++---- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index f70f2897b0..1df8df6a25 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -12,19 +12,6 @@ Referenda constant REFERENDA_CONTRACT = Referenda(REFERENDA_ADDRESS); /// @title The interface through which solidity contracts will interact with the Referenda pallet /// @custom:address 0x0000000000000000000000000000000000000811 interface Referenda { - /// @dev Defines the referenda origins that have tracks corresponding to uint8 representation - /// The uint8 representation is defined in origins pallet Into for Origin - /// From top to bottom: 1, 10, 11, 12, 13, 14, 15 - enum Origin { - WhitelistedCaller, - Treasurer, - ReferendumCanceller, - ReferendumKiller, - SmallSpender, - MediumSpender, - BigSpender - } - /// Return the total referendum count /// @custom:selector 3a42ee31 function referendumCount() external view returns (uint256); @@ -55,12 +42,13 @@ interface Referenda { /// @dev Submit a referenda /// @custom:selector d865f8e8 - /// @param origin The origin from which the proposed referenda would be dispatched + /// @param trackId The trackId corresponding to the origin from which the proposal is to be + /// dispatched. The trackId => origin mapping lives in `runtime/governance/tracks.rs` /// @param hash Hash of the proposal preimage /// @param at If true then AT block_number, else AFTER block_number /// @param block Inner block number for DispatchTime function submit( - Origin origin, + uint8 trackId, bytes memory hash, bool at, uint32 block diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 310c68e929..765bd50b88 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -145,15 +145,15 @@ where #[precompile::public("submit(uint8,bytes,bool,uint32)")] fn submit( handle: &mut impl PrecompileHandle, - proposal_origin: u8, + track_id: u8, proposal: BoundedBytes, at: bool, block_number: u32, ) -> EvmResult { - let gov_origin: GovOrigin = proposal_origin.try_into().map_err(|_| { - RevertReason::custom("Origin does not exist for u8").in_field("proposal_origin") + let origin: GovOrigin = track_id.try_into().map_err(|_| { + RevertReason::custom("Origin does not exist for TrackId").in_field("track_id") })?; - let proposal_origin: Box> = Box::new(gov_origin.into()); + let proposal_origin: Box> = Box::new(origin.into()); let proposal: BoundedCallOf = Bounded::Inline( frame_support::BoundedVec::try_from(proposal.as_bytes().to_vec()).map_err(|_| { RevertReason::custom("Proposal input is not a runtime call").in_field("proposal") From 7839709f0e6d2410a0ab7f3941862d4c233e22f2 Mon Sep 17 00:00:00 2001 From: Amar Singh Date: Thu, 12 Jan 2023 11:12:45 -0500 Subject: [PATCH 36/52] camelCase error msgs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éloïs --- precompiles/conviction-voting/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 90f3a98d1c..0aa1761540 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -84,8 +84,8 @@ where vote_amount: U256, conviction: u8, ) -> EvmResult { - let poll_index = Self::u32_to_index(poll_index).in_field("poll_index")?; - let vote_amount = Self::u256_to_amount(vote_amount).in_field("vote_amount")?; + let poll_index = Self::u32_to_index(poll_index).in_field("pollIndex")?; + let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; let vote = AccountVote::Standard { @@ -108,7 +108,7 @@ where #[precompile::public("removeVote(uint256)")] fn remove_vote(handle: &mut impl PrecompileHandle, poll_index: u32) -> EvmResult { - let index = Self::u32_to_index(poll_index).in_field("poll_index")?; + let index = Self::u32_to_index(poll_index).in_field("pollIndex")?; log::trace!( target: "conviction-voting-precompile", @@ -132,7 +132,7 @@ where poll_index: u32, ) -> EvmResult { let class = Self::u16_to_class(class).in_field("class")?; - let index = Self::u32_to_index(poll_index).in_field("poll_index")?; + let index = Self::u32_to_index(poll_index).in_field("pollIndex")?; let target = Runtime::AddressMapping::into_account_id(target.into()); let target: ::Source = From 3357394c54e8c22a09b69312229cfa5498da62c9 Mon Sep 17 00:00:00 2001 From: Amar Singh Date: Thu, 12 Jan 2023 11:13:05 -0500 Subject: [PATCH 37/52] Update precompiles/referenda/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éloïs --- precompiles/referenda/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 765bd50b88..d24b54f101 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -151,7 +151,7 @@ where block_number: u32, ) -> EvmResult { let origin: GovOrigin = track_id.try_into().map_err(|_| { - RevertReason::custom("Origin does not exist for TrackId").in_field("track_id") + RevertReason::custom("Origin does not exist for TrackId").in_field("trackId") })?; let proposal_origin: Box> = Box::new(origin.into()); let proposal: BoundedCallOf = Bounded::Inline( From 5efa9d5adddc46fa2594eb0458f7bb400b2191b1 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 11:48:09 -0500 Subject: [PATCH 38/52] fix conviction precompile interface --- .../conviction-voting/ConvictionVoting.sol | 28 +++++++++---------- precompiles/conviction-voting/src/lib.rs | 12 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index 1ff9b6015c..da57cd8eb0 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -27,55 +27,55 @@ interface ConvictionVoting { } /// @dev Vote in a poll. - /// @custom:selector f56cb3b3 + /// @custom:selector 35ee6e0e /// @param pollIndex Index of poll /// @param aye Yes or no vote /// @param voteAmount Balance locked for vote /// @param conviction Conviction multiplier for length of vote lock function vote( - uint256 pollIndex, + uint32 pollIndex, bool aye, uint256 voteAmount, Conviction conviction ) external; /// @dev Remove vote in poll - /// @custom:selector 3f68fde4 + /// @custom:selector 79cae220 /// @param pollIndex Index of the poll - function removeVote(uint256 pollIndex) external; + function removeVote(uint32 pollIndex) external; /// @dev Remove vote in poll for other voter - /// @custom:selector 135ef12d + /// @custom:selector cbcb9276 //// @param target The voter to have vote removed /// @param class The class /// @param pollIndex the poll index function removeOtherVote( address target, - uint256 class, - uint256 pollIndex + uint16 class, + uint32 pollIndex ) external; /// @dev Delegate to a representative for the vote class - /// @custom:selector 7efe44c7 + /// @custom:selector 681750e8 /// @param class The class /// @param representative The representative for the class /// @param conviction The conviction multiplier /// @param amount delegated to representative for this vote class function delegate( - uint256 class, + uint16 class, address representative, - uint256 conviction, + Conviction conviction, uint256 amount ) external; /// @dev Undelegate for the vote class - /// @custom:selector 6c68c0e1 + /// @custom:selector 98be4094 /// @param class The class - function undelegate(uint256 class) external; + function undelegate(uint16 class) external; /// @dev Unlock tokens locked for vote class - /// @custom:selector f1d2ec1d + /// @custom:selector 4259d98c /// @param class The class /// @param target The target address - function unlock(uint256 class, address target) external; + function unlock(uint16 class, address target) external; } diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 0aa1761540..c650278d57 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -76,7 +76,7 @@ where /// * aye: Yes or no vote /// * vote_amount: Balance locked for vote /// * conviction: Conviction multiplier for length of vote lock - #[precompile::public("vote(uint256,bool,uint256,uint256)")] + #[precompile::public("vote(uint32,bool,uint256,uint8)")] fn vote( handle: &mut impl PrecompileHandle, poll_index: u32, @@ -106,7 +106,7 @@ where Ok(()) } - #[precompile::public("removeVote(uint256)")] + #[precompile::public("removeVote(uint32)")] fn remove_vote(handle: &mut impl PrecompileHandle, poll_index: u32) -> EvmResult { let index = Self::u32_to_index(poll_index).in_field("pollIndex")?; @@ -124,7 +124,7 @@ where Ok(()) } - #[precompile::public("removeOtherVote(address,uint256,uint256)")] + #[precompile::public("removeOtherVote(address,uint16,uint32)")] fn remove_other_vote( handle: &mut impl PrecompileHandle, target: Address, @@ -156,7 +156,7 @@ where Ok(()) } - #[precompile::public("delegate(uint256,address,uint256,uint256)")] + #[precompile::public("delegate(uint16,address,uint8,uint256)")] fn delegate( handle: &mut impl PrecompileHandle, class: u16, @@ -188,7 +188,7 @@ where Ok(()) } - #[precompile::public("undelegate(uint256)")] + #[precompile::public("undelegate(uint16)")] fn undelegate(handle: &mut impl PrecompileHandle, class: u16) -> EvmResult { let class = Self::u16_to_class(class).in_field("class")?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -198,7 +198,7 @@ where Ok(()) } - #[precompile::public("unlock(uint256,address)")] + #[precompile::public("unlock(uint16,address)")] fn unlock(handle: &mut impl PrecompileHandle, class: u16, target: Address) -> EvmResult { let class = Self::u16_to_class(class).in_field("class")?; let target: H160 = target.into(); From 145f6f9f26f2b7f60f26f839431215d25a2310e9 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 11:55:17 -0500 Subject: [PATCH 39/52] fix referenda precompile interface --- precompiles/referenda/Referenda.sol | 8 ++++---- precompiles/referenda/src/lib.rs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index 1df8df6a25..4da5970722 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -22,13 +22,13 @@ interface Referenda { /// Return the total count of deciding referenda per track /// @param trackId The track identifier - /// @custom:selector 23cbda16 - function decidingCount(uint256 trackId) external view returns (uint256); + /// @custom:selector 983d6425 + function decidingCount(uint16 trackId) external view returns (uint256); /// Return the total count of deciding referenda per track /// @param trackId The track identifier - /// @custom:selector 35028c55 - function trackInfo(uint256 trackId) + /// @custom:selector 34038146 + function trackInfo(uint16 trackId) external view returns ( diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index d24b54f101..80db5d750f 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -88,7 +88,7 @@ where Ok(submission_deposit.into()) } - #[precompile::public("decidingCount(uint256)")] + #[precompile::public("decidingCount(uint16)")] #[precompile::view] fn deciding_count(handle: &mut impl PrecompileHandle, track_id: u16) -> EvmResult { // Fetch data from pallet @@ -96,7 +96,7 @@ where let track_id: TrackIdOf = track_id .try_into() .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) - .in_field("track")?; + .in_field("trackId")?; let deciding_count = DecidingCount::::get(track_id); log::trace!( target: "referendum-precompile", "Track {:?} deciding count is {:?}", @@ -107,7 +107,7 @@ where Ok(deciding_count.into()) } - #[precompile::public("trackInfo(uint256)")] + #[precompile::public("trackInfo(uint16)")] #[precompile::view] fn track_info( handle: &mut impl PrecompileHandle, @@ -118,7 +118,7 @@ where let track_id: TrackIdOf = track_id .try_into() .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) - .in_field("track")?; + .in_field("trackId")?; let tracks = Runtime::Tracks::tracks(); let index = tracks .binary_search_by_key(&track_id, |x| x.0) @@ -138,7 +138,7 @@ where /// Propose a referendum on a privileged action. /// /// Parameters: - /// * proposal_origin: The origin from which the proposal should be executed. + /// * track_id: The trackId for the origin from which the proposal is to be dispatched. /// * proposal: The proposed runtime call. /// * at: If true then AT block_number, else AFTER block_number /// * block_number: Inner block number for DispatchTime From 694378d3d38489d337fcfd0cdb7d610178ff1fec Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 12:29:53 -0500 Subject: [PATCH 40/52] test to ensure all tracks have min enactment period less than vote locking period --- precompiles/referenda/Referenda.sol | 2 +- precompiles/referenda/src/lib.rs | 9 +++++---- runtime/moonbase/src/governance/origins.rs | 8 ++++++++ runtime/moonbase/src/governance/referenda.rs | 4 ---- runtime/moonbase/src/governance/tracks.rs | 15 +++++++++++++++ runtime/moonbase/src/lib.rs | 1 - 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index 4da5970722..b582e29764 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -48,7 +48,7 @@ interface Referenda { /// @param at If true then AT block_number, else AFTER block_number /// @param block Inner block number for DispatchTime function submit( - uint8 trackId, + uint16 trackId, bytes memory hash, bool at, uint32 block diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 80db5d750f..4efc589be8 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -49,10 +49,10 @@ type OriginOf = <::RuntimeOrigin as OriginTrait>::PalletsOrigin; /// A precompile to wrap the functionality from pallet-referenda. -pub struct ReferendaPrecompile>(PhantomData<(Runtime, GovOrigin)>); +pub struct ReferendaPrecompile>(PhantomData<(Runtime, GovOrigin)>); #[precompile_utils::precompile] -impl> ReferendaPrecompile +impl ReferendaPrecompile where Runtime: pallet_referenda::Config + pallet_evm::Config + frame_system::Config, OriginOf: From, @@ -64,6 +64,7 @@ where Runtime::BlockNumber: Into, TrackIdOf: TryFrom, BalanceOf: Into, + GovOrigin: TryFrom, { // The accessors are first. They directly return their result. #[precompile::public("referendumCount()")] @@ -142,10 +143,10 @@ where /// * proposal: The proposed runtime call. /// * at: If true then AT block_number, else AFTER block_number /// * block_number: Inner block number for DispatchTime - #[precompile::public("submit(uint8,bytes,bool,uint32)")] + #[precompile::public("submit(uint16,bytes,bool,uint32)")] fn submit( handle: &mut impl PrecompileHandle, - track_id: u8, + track_id: u16, proposal: BoundedBytes, at: bool, block_number: u32, diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs index 72d75e8105..25d02afc36 100644 --- a/runtime/moonbase/src/governance/origins.rs +++ b/runtime/moonbase/src/governance/origins.rs @@ -80,6 +80,14 @@ pub mod custom_origins { } } + impl TryFrom for Origin { + type Error = (); + /// TrackId => Origin + fn try_from(value: u16) -> Result { + (value as u8).try_into() + } + } + impl Into for Origin { /// Origin => TrackId fn into(self) -> u16 { diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index 2d07922a23..582ce3ce71 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -35,14 +35,10 @@ impl pallet_conviction_voting::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type Polls = Referenda; - // TODO: reduce this by funds in system that cannot vote i.e. - // parachain auction deposit but would this require runtime upgrade every time this changes? type MaxTurnout = frame_support::traits::TotalIssuanceOf; // Maximum number of concurrent votes an account may have type MaxVotes = ConstU32<512>; // Minimum period of vote locking - // TODO: add test that this is always greater than the Enactment period so successful voters are - // locked into consequences of vote type VoteLockingPeriod = VoteLockingPeriod; } diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index 373b30df81..928fd6b39f 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -199,3 +199,18 @@ fn print_all_approval_and_support_curves() { } assert!(false); } + +#[test] +/// To ensure voters are always locked into their vote +fn vote_locking_always_longer_than_enactment_period() { + for (_, track) in TRACKS_DATA { + assert!( + ::VoteLockingPeriod::get() + > track.min_enactment_period, + "Track {} has enactment period {} < vote locking period {}", + track.name, + track.min_enactment_period, + ::VoteLockingPeriod::get(), + ); + } +} diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index f5430834d5..c53d16b789 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -795,7 +795,6 @@ fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bo use precompiles::PrecompileName; impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { - // TODO: add opengov precompiles fn is_evm_proxy_call_allowed( &self, call: &pallet_evm_precompile_proxy::EvmSubCall, From 9bfd9ff97ffb830e671c8ceb6ffc9ecae50fc06b Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 12:59:43 -0500 Subject: [PATCH 41/52] update tracks based on wiki --- runtime/moonbase/src/governance/origins.rs | 12 +++- runtime/moonbase/src/governance/referenda.rs | 6 +- runtime/moonbase/src/governance/tracks.rs | 68 ++++++++----------- runtime/moonriver/src/governance/councils.rs | 0 runtime/moonriver/src/governance/democracy.rs | 0 runtime/moonriver/src/governance/mod.rs | 30 ++++++++ runtime/moonriver/src/governance/origins.rs | 0 runtime/moonriver/src/governance/referenda.rs | 0 runtime/moonriver/src/governance/tracks.rs | 0 9 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 runtime/moonriver/src/governance/councils.rs create mode 100644 runtime/moonriver/src/governance/democracy.rs create mode 100644 runtime/moonriver/src/governance/mod.rs create mode 100644 runtime/moonriver/src/governance/origins.rs create mode 100644 runtime/moonriver/src/governance/referenda.rs create mode 100644 runtime/moonriver/src/governance/tracks.rs diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs index 25d02afc36..ef79fff6c0 100644 --- a/runtime/moonbase/src/governance/origins.rs +++ b/runtime/moonbase/src/governance/origins.rs @@ -61,6 +61,8 @@ pub mod custom_origins { MediumSpender, /// Origin able to spend up to MaxBigSpenderSpend from the treasury at once. BigSpender, + /// General admin + GeneralAdmin, } impl TryFrom for Origin { @@ -75,6 +77,7 @@ pub mod custom_origins { 13 => Ok(Origin::SmallSpender), 14 => Ok(Origin::MediumSpender), 15 => Ok(Origin::BigSpender), + 16 => Ok(Origin::GeneralAdmin), _ => Err(()), } } @@ -99,6 +102,7 @@ pub mod custom_origins { Origin::SmallSpender => 13, Origin::MediumSpender => 14, Origin::BigSpender => 15, + Origin::GeneralAdmin => 16, } } } @@ -120,6 +124,7 @@ pub mod custom_origins { has_consistent_conversions!(Origin::SmallSpender); has_consistent_conversions!(Origin::MediumSpender); has_consistent_conversions!(Origin::BigSpender); + has_consistent_conversions!(Origin::GeneralAdmin); } macro_rules! decl_unit_ensures { @@ -152,7 +157,12 @@ pub mod custom_origins { }; () => {} } - decl_unit_ensures!(ReferendumCanceller, ReferendumKiller, WhitelistedCaller,); + decl_unit_ensures!( + ReferendumCanceller, + ReferendumKiller, + WhitelistedCaller, + GeneralAdmin + ); macro_rules! decl_ensure { ( diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index 582ce3ce71..b03d4cf6d5 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -56,9 +56,9 @@ pub type TreasurySpender = impl custom_origins::Config for Runtime { type Currency = Balances; - type MaxSmallSpenderSpend = ConstU128<{ 200 * UNIT * SUPPLY_FACTOR }>; - type MaxMediumSpenderSpend = ConstU128<{ 2000 * UNIT * SUPPLY_FACTOR }>; - type MaxBigSpenderSpend = ConstU128<{ 10000 * UNIT * SUPPLY_FACTOR }>; + type MaxSmallSpenderSpend = ConstU128<{ 2 * KILOUNIT * SUPPLY_FACTOR }>; + type MaxMediumSpenderSpend = ConstU128<{ 20 * KILOUNIT * SUPPLY_FACTOR }>; + type MaxBigSpenderSpend = ConstU128<{ 200 * KILOUNIT * SUPPLY_FACTOR }>; type MaxTreasurerSpend = MaxBalance; } diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index 928fd6b39f..83ab81f9af 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -23,7 +23,7 @@ const fn percent(x: i32) -> sp_runtime::FixedI64 { sp_runtime::FixedI64::from_rational(x as u128, 100) } use pallet_referenda::Curve; -const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] = [ +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] = [ ( 0, pallet_referenda::TrackInfo { @@ -35,13 +35,13 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] // Amount that must be placed on deposit before a decision can be made. decision_deposit: 100 * KILOUNIT * SUPPLY_FACTOR, // Amount of time this must be submitted for before a decision can be made. - prepare_period: 3 * HOURS, + prepare_period: 1 * DAYS, // Amount of time that a decision may take to be approved prior to cancellation. decision_period: 14 * DAYS, // Amount of time that the approval criteria must hold before it can be approved. - confirm_period: 3 * HOURS, + confirm_period: 1 * DAYS, // Minimum amount of time that an approved proposal must be in the dispatch queue. - min_enactment_period: 3 * HOURS, + min_enactment_period: 1 * DAYS, // Minimum aye votes as percentage of overall conviction-weighted votes needed for // approval as a function of time into decision period. min_approval: Curve::make_reciprocal(4, 14, percent(80), percent(50), percent(100)), @@ -54,9 +54,9 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] 1, pallet_referenda::TrackInfo { name: "whitelisted_caller", - max_deciding: 10, + max_deciding: 100, decision_deposit: 10 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 30 * MINUTES, + prepare_period: 10 * MINUTES, decision_period: 14 * DAYS, confirm_period: 10 * MINUTES, min_enactment_period: 30 * MINUTES, @@ -88,11 +88,11 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] 11, pallet_referenda::TrackInfo { name: "referendum_canceller", - max_deciding: 100, - decision_deposit: 5 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 4, + max_deciding: 20, + decision_deposit: 10 * KILOUNIT * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, decision_period: 14 * DAYS, - confirm_period: 1 * DAYS, + confirm_period: 3 * HOURS, min_enactment_period: 10 * MINUTES, min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), min_support: Curve::make_reciprocal(1, 14, percent(1), percent(0), percent(50)), @@ -103,10 +103,10 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "referendum_killer", max_deciding: 100, - decision_deposit: 5 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 4, + decision_deposit: 20 * KILOUNIT * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, decision_period: 14 * DAYS, - confirm_period: 1 * DAYS, + confirm_period: 3 * HOURS, min_enactment_period: 10 * MINUTES, min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), min_support: Curve::make_reciprocal(7, 14, percent(1), percent(0), percent(10)), @@ -131,7 +131,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "medium_spender", max_deciding: 5, - decision_deposit: 3000 * UNIT * SUPPLY_FACTOR, + decision_deposit: 3 * KILOUNIT * SUPPLY_FACTOR, prepare_period: 4, decision_period: 14 * DAYS, confirm_period: 24 * HOURS, @@ -145,15 +145,29 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "big_spender", max_deciding: 5, - decision_deposit: 30 * KILOUNIT * SUPPLY_FACTOR, + decision_deposit: 3 * KILOUNIT * SUPPLY_FACTOR, prepare_period: 4, decision_period: 14 * DAYS, - confirm_period: 48 * HOURS, + confirm_period: 24 * HOURS, min_enactment_period: 1 * DAYS, min_approval: Curve::make_linear(14, 14, percent(50), percent(100)), min_support: Curve::make_reciprocal(8, 14, percent(1), percent(0), percent(10)), }, ), + ( + 16, + pallet_referenda::TrackInfo { + name: "general_admin", + max_deciding: 10, + decision_deposit: 500 * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 1 * DAYS, + min_enactment_period: 1 * DAYS, + min_approval: Curve::make_linear(4, 14, percent(50), percent(100)), + min_support: Curve::make_reciprocal(7, 14, percent(10), percent(0), percent(50)), + }, + ), ]; pub struct TracksInfo; @@ -178,28 +192,6 @@ impl pallet_referenda::TracksInfo for TracksInfo { } } -#[test] -#[should_panic] // comment out to see curve info for all tracks -fn print_all_approval_and_support_curves() { - for (_, track_info) in TRACKS_DATA { - println!("{} TRACK", track_info.name); - let decision_period_days = track_info.decision_period / DAYS; - println!( - "{} DECISION PERIOD: {} days", - track_info.name, decision_period_days - ); - println!("{} MIN APPROVAL:", track_info.name); - track_info - .min_approval - .info(decision_period_days, track_info.name); - println!("{} MIN SUPPORT:", track_info.name); - track_info - .min_support - .info(decision_period_days, track_info.name); - } - assert!(false); -} - #[test] /// To ensure voters are always locked into their vote fn vote_locking_always_longer_than_enactment_period() { diff --git a/runtime/moonriver/src/governance/councils.rs b/runtime/moonriver/src/governance/councils.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/runtime/moonriver/src/governance/democracy.rs b/runtime/moonriver/src/governance/democracy.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/runtime/moonriver/src/governance/mod.rs b/runtime/moonriver/src/governance/mod.rs new file mode 100644 index 0000000000..4832e518c1 --- /dev/null +++ b/runtime/moonriver/src/governance/mod.rs @@ -0,0 +1,30 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Governance configurations + +pub mod councils; +mod democracy; +pub mod referenda; + +use super::*; + +mod origins; +pub use origins::{ + pallet_custom_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, +}; +mod tracks; +pub use tracks::TracksInfo; diff --git a/runtime/moonriver/src/governance/origins.rs b/runtime/moonriver/src/governance/origins.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/runtime/moonriver/src/governance/referenda.rs b/runtime/moonriver/src/governance/referenda.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/runtime/moonriver/src/governance/tracks.rs b/runtime/moonriver/src/governance/tracks.rs new file mode 100644 index 0000000000..e69de29bb2 From a11ee95ac1b839ad2bbd3865fcfa668632c299b6 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 13:00:10 -0500 Subject: [PATCH 42/52] revert accidental commit --- runtime/moonriver/src/governance/councils.rs | 0 runtime/moonriver/src/governance/democracy.rs | 0 runtime/moonriver/src/governance/mod.rs | 30 ------------------- runtime/moonriver/src/governance/origins.rs | 0 runtime/moonriver/src/governance/referenda.rs | 0 runtime/moonriver/src/governance/tracks.rs | 0 6 files changed, 30 deletions(-) delete mode 100644 runtime/moonriver/src/governance/councils.rs delete mode 100644 runtime/moonriver/src/governance/democracy.rs delete mode 100644 runtime/moonriver/src/governance/mod.rs delete mode 100644 runtime/moonriver/src/governance/origins.rs delete mode 100644 runtime/moonriver/src/governance/referenda.rs delete mode 100644 runtime/moonriver/src/governance/tracks.rs diff --git a/runtime/moonriver/src/governance/councils.rs b/runtime/moonriver/src/governance/councils.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/runtime/moonriver/src/governance/democracy.rs b/runtime/moonriver/src/governance/democracy.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/runtime/moonriver/src/governance/mod.rs b/runtime/moonriver/src/governance/mod.rs deleted file mode 100644 index 4832e518c1..0000000000 --- a/runtime/moonriver/src/governance/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Governance configurations - -pub mod councils; -mod democracy; -pub mod referenda; - -use super::*; - -mod origins; -pub use origins::{ - pallet_custom_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, -}; -mod tracks; -pub use tracks::TracksInfo; diff --git a/runtime/moonriver/src/governance/origins.rs b/runtime/moonriver/src/governance/origins.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/runtime/moonriver/src/governance/referenda.rs b/runtime/moonriver/src/governance/referenda.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/runtime/moonriver/src/governance/tracks.rs b/runtime/moonriver/src/governance/tracks.rs deleted file mode 100644 index e69de29bb2..0000000000 From a1941ec40fbe5f1aa2020e4187131bffc89b3799 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 13:27:55 -0500 Subject: [PATCH 43/52] fix referenda precompile unit tests --- precompiles/referenda/Referenda.sol | 2 +- precompiles/referenda/src/mock.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index b582e29764..1e4ae88512 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -41,7 +41,7 @@ interface Referenda { ); /// @dev Submit a referenda - /// @custom:selector d865f8e8 + /// @custom:selector 767820eb /// @param trackId The trackId corresponding to the origin from which the proposal is to be /// dispatched. The trackId => origin mapping lives in `runtime/governance/tracks.rs` /// @param hash Hash of the proposal preimage diff --git a/precompiles/referenda/src/mock.rs b/precompiles/referenda/src/mock.rs index 3bf21cb8c9..146564e686 100644 --- a/precompiles/referenda/src/mock.rs +++ b/precompiles/referenda/src/mock.rs @@ -328,9 +328,9 @@ impl pallet_referenda::Config for Runtime { } pub struct GovOrigin; -impl TryFrom for GovOrigin { +impl TryFrom for GovOrigin { type Error = (); - fn try_from(_i: u8) -> Result { + fn try_from(_i: u16) -> Result { Ok(GovOrigin) } } From 6e991801ef28605d8b34c9c065f9cdb8b5d99cf0 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 13:46:02 -0500 Subject: [PATCH 44/52] update config based on polkadot 6372 gov2 config tweaks --- runtime/moonbase/src/governance/referenda.rs | 11 +++++------ runtime/moonbase/src/governance/tracks.rs | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index b03d4cf6d5..e2ffea5e4d 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -48,18 +48,17 @@ parameter_types! { pub const UndecidingTimeout: BlockNumber = 28 * DAYS; } -parameter_types! { - pub const MaxBalance: Balance = Balance::max_value(); -} -pub type TreasurySpender = - EitherOf, custom_origins::Spender>; +pub type TreasurySpender = EitherOf< + EnsureRootWithSuccess, + custom_origins::Spender, +>; impl custom_origins::Config for Runtime { type Currency = Balances; type MaxSmallSpenderSpend = ConstU128<{ 2 * KILOUNIT * SUPPLY_FACTOR }>; type MaxMediumSpenderSpend = ConstU128<{ 20 * KILOUNIT * SUPPLY_FACTOR }>; type MaxBigSpenderSpend = ConstU128<{ 200 * KILOUNIT * SUPPLY_FACTOR }>; - type MaxTreasurerSpend = MaxBalance; + type MaxTreasurerSpend = ConstU128<{ 500 * KILOUNIT * SUPPLY_FACTOR }>; } // The purpose of this pallet is to queue calls to be dispatched as by root later => the Dispatch diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index 83ab81f9af..b7a0f05fae 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -118,7 +118,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] name: "small_spender", max_deciding: 5, decision_deposit: 300 * UNIT * SUPPLY_FACTOR, - prepare_period: 4, + prepare_period: 1 * MINUTES, decision_period: 14 * DAYS, confirm_period: 12 * HOURS, min_enactment_period: 1 * DAYS, @@ -132,7 +132,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] name: "medium_spender", max_deciding: 5, decision_deposit: 3 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 4, + prepare_period: 1 * MINUTES, decision_period: 14 * DAYS, confirm_period: 24 * HOURS, min_enactment_period: 1 * DAYS, @@ -146,7 +146,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] name: "big_spender", max_deciding: 5, decision_deposit: 3 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 4, + prepare_period: 1 * MINUTES, decision_period: 14 * DAYS, confirm_period: 24 * HOURS, min_enactment_period: 1 * DAYS, From 83e5a1c5dc6a2ba834f7633da845fec8e81526ed Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Thu, 12 Jan 2023 13:55:40 -0500 Subject: [PATCH 45/52] fix --- runtime/moonbase/src/governance/referenda.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index e2ffea5e4d..ea073df51b 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -49,7 +49,7 @@ parameter_types! { } pub type TreasurySpender = EitherOf< - EnsureRootWithSuccess, + EnsureRootWithSuccess>, custom_origins::Spender, >; From 362fef71bd9a92f9b12fc701856d36846dd1b4af Mon Sep 17 00:00:00 2001 From: Amar Singh Date: Tue, 17 Jan 2023 10:15:32 -0500 Subject: [PATCH 46/52] Configure moonriver OpenGov (#2038) * configure opengov for movr * Staking precompile: candidateAutoCompoundingDelegationCount (#2037) * candidateAutoCompoundingDelegationCount * Remove unecessary `.into()` Co-authored-by: Amar Singh * typo Co-authored-by: Stephen Shelton Co-authored-by: Amar Singh Co-authored-by: Stephen Shelton * precompiles * address some review todos not done yet * Fixes balance smoke test (#2040) Co-authored-by: Crystalin None * trackIds getter and full TrackInfo impl with Curves * patch evm version (#2026) * Removes treasurer in Moonriver * Update eth contract code smoke test (#2043) Change account limit * Adds OpenGov to Moonriver (#2041) * Adds OpenGov to Moonriver * Updates Moonbase * fmt * fixes test * fix impoty Co-authored-by: nanocryk <6422796+nanocryk@users.noreply.github.com> Co-authored-by: Stephen Shelton Co-authored-by: Alan Sapede Co-authored-by: Crystalin None Co-authored-by: Crystalin Co-authored-by: Tim B <79199034+timbrinded@users.noreply.github.com> --- Cargo.lock | 18 ++- Cargo.toml | 4 + .../conviction-voting/ConvictionVoting.sol | 37 +++-- precompiles/conviction-voting/src/lib.rs | 20 +-- .../parachain-staking/StakingInterface.sol | 12 +- precompiles/parachain-staking/src/lib.rs | 17 ++ precompiles/parachain-staking/src/tests.rs | 71 +++++++++ precompiles/referenda/Referenda.sol | 32 +++- precompiles/referenda/src/lib.rs | 93 +++++++++-- runtime/moonbase/src/governance/mod.rs | 2 +- runtime/moonbase/src/governance/origins.rs | 104 ++---------- runtime/moonbase/src/governance/referenda.rs | 13 +- runtime/moonbase/src/governance/tracks.rs | 100 +++--------- runtime/moonbase/src/lib.rs | 4 +- runtime/moonriver/Cargo.toml | 18 +++ runtime/moonriver/src/governance/councils.rs | 68 ++++++++ runtime/moonriver/src/governance/democracy.rs | 76 +++++++++ runtime/moonriver/src/governance/mod.rs | 30 ++++ runtime/moonriver/src/governance/origins.rs | 128 +++++++++++++++ runtime/moonriver/src/governance/referenda.rs | 95 +++++++++++ runtime/moonriver/src/governance/tracks.rs | 150 ++++++++++++++++++ runtime/moonriver/src/lib.rs | 111 +------------ runtime/moonriver/src/precompiles.rs | 9 ++ runtime/moonriver/tests/integration_test.rs | 2 +- .../smoke-tests/test-balances-consistency.ts | 4 +- .../test-ethereum-contract-code.ts | 4 +- 26 files changed, 872 insertions(+), 350 deletions(-) create mode 100644 runtime/moonriver/src/governance/councils.rs create mode 100644 runtime/moonriver/src/governance/democracy.rs create mode 100644 runtime/moonriver/src/governance/mod.rs create mode 100644 runtime/moonriver/src/governance/origins.rs create mode 100644 runtime/moonriver/src/governance/referenda.rs create mode 100644 runtime/moonriver/src/governance/tracks.rs diff --git a/Cargo.lock b/Cargo.lock index c0046c62e8..c4b5502119 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2296,8 +2296,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "evm" version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4448c65b71e8e2b9718232d84d09045eeaaccb2320494e6bd6dbf7e58fec8ff" +source = "git+https://github.com/rust-blockchain/evm?rev=842e03d068ddb6a3195a2dedc4a9b63caadb3355#842e03d068ddb6a3195a2dedc4a9b63caadb3355" dependencies = [ "auto_impl", "environmental", @@ -2317,8 +2316,7 @@ dependencies = [ [[package]] name = "evm-core" version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c51bec0eb68a891c2575c758eaaa1d61373fc51f7caaf216b1fb5c3fea3b5d" +source = "git+https://github.com/rust-blockchain/evm?rev=842e03d068ddb6a3195a2dedc4a9b63caadb3355#842e03d068ddb6a3195a2dedc4a9b63caadb3355" dependencies = [ "parity-scale-codec", "primitive-types", @@ -2329,8 +2327,7 @@ dependencies = [ [[package]] name = "evm-gasometer" version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8b93c59c54fc26522d842f0e0d3f8e8be331c776df18ff3e540b53c2f64d509" +source = "git+https://github.com/rust-blockchain/evm?rev=842e03d068ddb6a3195a2dedc4a9b63caadb3355#842e03d068ddb6a3195a2dedc4a9b63caadb3355" dependencies = [ "environmental", "evm-core", @@ -2341,8 +2338,7 @@ dependencies = [ [[package]] name = "evm-runtime" version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79b9459ce64f1a28688397c4013764ce53cd57bb84efc16b5187fa9b05b13ad" +source = "git+https://github.com/rust-blockchain/evm?rev=842e03d068ddb6a3195a2dedc4a9b63caadb3355#842e03d068ddb6a3195a2dedc4a9b63caadb3355" dependencies = [ "auto_impl", "environmental", @@ -5649,6 +5645,7 @@ dependencies = [ "pallet-balances", "pallet-base-fee", "pallet-collective", + "pallet-conviction-voting", "pallet-crowdloan-rewards", "pallet-democracy", "pallet-ethereum", @@ -5661,13 +5658,16 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-call-permit", "pallet-evm-precompile-collective", + "pallet-evm-precompile-conviction-voting", "pallet-evm-precompile-crowdloan-rewards", "pallet-evm-precompile-democracy", "pallet-evm-precompile-dispatch", "pallet-evm-precompile-modexp", "pallet-evm-precompile-parachain-staking", + "pallet-evm-precompile-preimage", "pallet-evm-precompile-proxy", "pallet-evm-precompile-randomness", + "pallet-evm-precompile-referenda", "pallet-evm-precompile-relay-encoder", "pallet-evm-precompile-sha3fips", "pallet-evm-precompile-simple", @@ -5685,6 +5685,7 @@ dependencies = [ "pallet-proxy-genesis-companion", "pallet-randomness", "pallet-randomness-collective-flip", + "pallet-referenda", "pallet-scheduler", "pallet-society", "pallet-timestamp", @@ -5692,6 +5693,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-treasury", "pallet-utility", + "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-transactor", diff --git a/Cargo.toml b/Cargo.toml index 191e8b2ce5..ae51c346a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,10 @@ members = [ ] [patch.crates-io] +evm = { git = "https://github.com/rust-blockchain/evm", rev = "842e03d068ddb6a3195a2dedc4a9b63caadb3355" } +evm-core = { git = "https://github.com/rust-blockchain/evm", rev = "842e03d068ddb6a3195a2dedc4a9b63caadb3355" } +evm-gasometer = { git = "https://github.com/rust-blockchain/evm", rev = "842e03d068ddb6a3195a2dedc4a9b63caadb3355" } +evm-runtime = { git = "https://github.com/rust-blockchain/evm", rev = "842e03d068ddb6a3195a2dedc4a9b63caadb3355" } jsonrpsee = { git = "https://github.com/PureStake/jsonrpsee", branch = "moonbeam-v0.15.1" } jsonrpsee-core = { git = "https://github.com/PureStake/jsonrpsee", branch = "moonbeam-v0.15.1" } jsonrpsee-types = { git = "https://github.com/PureStake/jsonrpsee", branch = "moonbeam-v0.15.1" } diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index da57cd8eb0..3d11a988ac 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -14,8 +14,15 @@ ConvictionVoting constant Conviction_Voting_CONTRACT = ConvictionVoting( /// @title The interface through which solidity contracts will interact with the Conviction Voting pallet /// @custom:address 0x0000000000000000000000000000000000000812 interface ConvictionVoting { - /// @dev Defines the conviction multiplier type represented as `uint8`. - /// The values start at `0` with 0.1x multiplier and votes unlocked. + /// @dev Defines the conviction multiplier type. + /// The values start at `0` and are represented as `uint8`. + /// None => 0.1x votes, unlocked. + /// Locked1x => 1x votes, locked for an enactment period following a successful vote. + /// Locked2x => 2x votes, locked for 2x enactment periods following a successful vote + /// Locked3x => 3x votes, locked for 4x... + /// Locked4x => 4x votes, locked for 8x..., + /// Locked5x => 5x votes, locked for 16x... + /// Locked6x => 6x votes, locked for 32x... enum Conviction { None, Locked1x, @@ -47,35 +54,35 @@ interface ConvictionVoting { /// @dev Remove vote in poll for other voter /// @custom:selector cbcb9276 //// @param target The voter to have vote removed - /// @param class The class + /// @param trackId The trackId /// @param pollIndex the poll index function removeOtherVote( address target, - uint16 class, + uint16 trackId, uint32 pollIndex ) external; - /// @dev Delegate to a representative for the vote class + /// @dev Delegate to a representative for the vote trackId /// @custom:selector 681750e8 - /// @param class The class - /// @param representative The representative for the class + /// @param trackId The trackId + /// @param representative The representative for the trackId /// @param conviction The conviction multiplier - /// @param amount delegated to representative for this vote class + /// @param amount delegated to representative for this vote trackId function delegate( - uint16 class, + uint16 trackId, address representative, Conviction conviction, uint256 amount ) external; - /// @dev Undelegate for the vote class + /// @dev Undelegate for the trackId /// @custom:selector 98be4094 - /// @param class The class - function undelegate(uint16 class) external; + /// @param trackId The trackId + function undelegate(uint16 trackId) external; - /// @dev Unlock tokens locked for vote class + /// @dev Unlock tokens locked for trackId /// @custom:selector 4259d98c - /// @param class The class + /// @param trackId The trackId /// @param target The target address - function unlock(uint16 class, address target) external; + function unlock(uint16 trackId, address target) external; } diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index c650278d57..8c722eccf3 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -128,10 +128,10 @@ where fn remove_other_vote( handle: &mut impl PrecompileHandle, target: Address, - class: u16, + track_id: u16, poll_index: u32, ) -> EvmResult { - let class = Self::u16_to_class(class).in_field("class")?; + let class = Self::u16_to_track_id(track_id).in_field("trackId")?; let index = Self::u32_to_index(poll_index).in_field("pollIndex")?; let target = Runtime::AddressMapping::into_account_id(target.into()); @@ -159,12 +159,12 @@ where #[precompile::public("delegate(uint16,address,uint8,uint256)")] fn delegate( handle: &mut impl PrecompileHandle, - class: u16, + track_id: u16, representative: Address, conviction: u8, amount: U256, ) -> EvmResult { - let class = Self::u16_to_class(class).in_field("class")?; + let class = Self::u16_to_track_id(track_id).in_field("trackId")?; let amount = Self::u256_to_amount(amount).in_field("amount")?; let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; @@ -189,8 +189,8 @@ where Ok(()) } #[precompile::public("undelegate(uint16)")] - fn undelegate(handle: &mut impl PrecompileHandle, class: u16) -> EvmResult { - let class = Self::u16_to_class(class).in_field("class")?; + fn undelegate(handle: &mut impl PrecompileHandle, track_id: u16) -> EvmResult { + let class = Self::u16_to_track_id(track_id).in_field("trackId")?; let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); let call = ConvictionVotingCall::::undelegate { class }; @@ -199,8 +199,8 @@ where Ok(()) } #[precompile::public("unlock(uint16,address)")] - fn unlock(handle: &mut impl PrecompileHandle, class: u16, target: Address) -> EvmResult { - let class = Self::u16_to_class(class).in_field("class")?; + fn unlock(handle: &mut impl PrecompileHandle, track_id: u16, target: Address) -> EvmResult { + let class = Self::u16_to_track_id(track_id).in_field("trackId")?; let target: H160 = target.into(); let target = Runtime::AddressMapping::into_account_id(target); let target: ::Source = @@ -228,10 +228,10 @@ where .try_into() .map_err(|_| RevertReason::value_is_too_large("index type").into()) } - fn u16_to_class(class: u16) -> MayRevert> { + fn u16_to_track_id(class: u16) -> MayRevert> { class .try_into() - .map_err(|_| RevertReason::value_is_too_large("class type").into()) + .map_err(|_| RevertReason::value_is_too_large("trackId type").into()) } fn u256_to_amount(value: U256) -> MayRevert> { value diff --git a/precompiles/parachain-staking/StakingInterface.sol b/precompiles/parachain-staking/StakingInterface.sol index 89edba675b..163aacff34 100644 --- a/precompiles/parachain-staking/StakingInterface.sol +++ b/precompiles/parachain-staking/StakingInterface.sol @@ -85,7 +85,17 @@ interface ParachainStaking { function candidateDelegationCount(address candidate) external view - returns (uint256); + returns (uint32); + + /// @dev Get the CandidateAutoCompoundingDelegationCount weight hint + /// @custom:selector 905f0806 + /// @param candidate The address for which we are querying the auto compounding + /// delegation count + /// @return The number of auto compounding delegations + function candidateAutoCompoundingDelegationCount(address candidate) + external + view + returns (uint32); /// @dev Get the DelegatorDelegationCount weight hint /// @custom:selector 067ec822 diff --git a/precompiles/parachain-staking/src/lib.rs b/precompiles/parachain-staking/src/lib.rs index 7445925b04..998dd91c95 100644 --- a/precompiles/parachain-staking/src/lib.rs +++ b/precompiles/parachain-staking/src/lib.rs @@ -146,6 +146,23 @@ where Ok(result) } + #[precompile::public("candidateAutoCompoundingDelegationCount(address)")] + #[precompile::view] + fn candidate_auto_compounding_delegation_count( + handle: &mut impl PrecompileHandle, + candidate: Address, + ) -> EvmResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + let candidate = Runtime::AddressMapping::into_account_id(candidate.0); + + let count = + >::auto_compounding_delegations(&candidate) + .len() as u32; + + Ok(count) + } + #[precompile::public("delegatorDelegationCount(address)")] #[precompile::public("delegator_delegation_count(address)")] #[precompile::view] diff --git a/precompiles/parachain-staking/src/tests.rs b/precompiles/parachain-staking/src/tests.rs index ddb5dc9576..5c8ad21265 100644 --- a/precompiles/parachain-staking/src/tests.rs +++ b/precompiles/parachain-staking/src/tests.rs @@ -56,6 +56,7 @@ fn selectors() { assert!(PCall::candidate_count_selectors().contains(&0xa9a981a3)); assert!(PCall::round_selectors().contains(&0x146ca531)); assert!(PCall::candidate_delegation_count_selectors().contains(&0x2ec087eb)); + assert!(PCall::candidate_auto_compounding_delegation_count_selectors().contains(&0x905f0806)); assert!(PCall::delegator_delegation_count_selectors().contains(&0x067ec822)); assert!(PCall::selected_candidates_selectors().contains(&0xbcf868a6)); assert!(PCall::delegation_request_is_pending_selectors().contains(&0x3b16def8)); @@ -369,6 +370,76 @@ fn candidate_delegation_count_works() { }); } +#[test] +fn candidate_auto_compounding_delegation_count_works() { + ExtBuilder::default() + .with_balances(vec![ + (Alice.into(), 1_000), + (Bob.into(), 50), + (Charlie.into(), 50), + (David.into(), 50), + ]) + .with_candidates(vec![(Alice.into(), 1_000)]) + .with_delegations(vec![ + (Bob.into(), Alice.into(), 50), + (Charlie.into(), Alice.into(), 50), + (David.into(), Alice.into(), 50), + ]) + .with_auto_compounding_delegations(vec![( + Charlie.into(), + Alice.into(), + 50, + Percent::from_percent(50), + )]) + .build() + .execute_with(|| { + // Assert that there 1 auto compounding delegations to Alice + precompiles() + .prepare_test( + Alice, + Precompile1, + PCall::candidate_auto_compounding_delegation_count { + candidate: Address(Alice.into()), + }, + ) + .expect_cost(0) // TODO: Test db read/write costs + .expect_no_logs() + .execute_returns_encoded(1u32); + }); +} + +#[test] +fn candidate_auto_compounding_elegation_count_works_with_zero() { + ExtBuilder::default() + .with_balances(vec![ + (Alice.into(), 1_000), + (Bob.into(), 50), + (Charlie.into(), 50), + (David.into(), 50), + ]) + .with_candidates(vec![(Alice.into(), 1_000)]) + .with_delegations(vec![ + (Bob.into(), Alice.into(), 50), + (Charlie.into(), Alice.into(), 50), + (David.into(), Alice.into(), 50), + ]) + .build() + .execute_with(|| { + // Assert that there 0 auto compounding delegations to Alice + precompiles() + .prepare_test( + Alice, + Precompile1, + PCall::candidate_auto_compounding_delegation_count { + candidate: Address(Alice.into()), + }, + ) + .expect_cost(0) // TODO: Test db read/write costs + .expect_no_logs() + .execute_returns_encoded(0u32); + }); +} + #[test] fn delegator_delegation_count_works() { ExtBuilder::default() diff --git a/precompiles/referenda/Referenda.sol b/precompiles/referenda/Referenda.sol index 1e4ae88512..5039ba767a 100644 --- a/precompiles/referenda/Referenda.sol +++ b/precompiles/referenda/Referenda.sol @@ -25,32 +25,50 @@ interface Referenda { /// @custom:selector 983d6425 function decidingCount(uint16 trackId) external view returns (uint256); - /// Return the total count of deciding referenda per track + /// Return the trackIds + /// @return trackIds Identifiers for all tracks (and origins) + /// @custom:selector cc17da14 + function trackIds() external view returns (uint16[] memory trackIds); + + /// Return the governance parameters configured for the input TrackId /// @param trackId The track identifier /// @custom:selector 34038146 function trackInfo(uint16 trackId) external view returns ( + string memory, + uint256, uint256, uint256, uint256, uint256, uint256, - uint256 + bytes memory, + bytes memory ); /// @dev Submit a referenda - /// @custom:selector 767820eb + /// @custom:selector 95f9ed68 + /// @param trackId The trackId corresponding to the origin from which the proposal is to be + /// dispatched. The trackId => origin mapping lives in `runtime/governance/tracks.rs` + /// @param hash Hash of the proposal preimage + /// @param block Block number at which this will be executed + function submitAt( + uint16 trackId, + bytes memory hash, + uint32 block + ) external; + + /// @dev Submit a referenda + /// @custom:selector 0a1ecbe9 /// @param trackId The trackId corresponding to the origin from which the proposal is to be /// dispatched. The trackId => origin mapping lives in `runtime/governance/tracks.rs` /// @param hash Hash of the proposal preimage - /// @param at If true then AT block_number, else AFTER block_number - /// @param block Inner block number for DispatchTime - function submit( + /// @param block Block number after which this will be executed + function submitAfter( uint16 trackId, bytes memory hash, - bool at, uint32 block ) external; diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 4efc589be8..5a3b03c10e 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -24,9 +24,10 @@ use frame_support::traits::{ }; use pallet_evm::AddressMapping; use pallet_referenda::{Call as ReferendaCall, DecidingCount, ReferendumCount, TracksInfo}; +use parity_scale_codec::Encode; use precompile_utils::prelude::*; use sp_core::U256; -use sp_std::{boxed::Box, marker::PhantomData}; +use sp_std::{boxed::Box, marker::PhantomData, vec::Vec}; #[cfg(test)] mod mock; @@ -62,7 +63,7 @@ where From>, ::RuntimeCall: From>, Runtime::BlockNumber: Into, - TrackIdOf: TryFrom, + TrackIdOf: TryFrom + TryInto, BalanceOf: Into, GovOrigin: TryFrom, { @@ -108,13 +109,42 @@ where Ok(deciding_count.into()) } + #[precompile::public("trackIds()")] + #[precompile::view] + fn track_ids(handle: &mut impl PrecompileHandle) -> EvmResult> { + // Fetch data from runtime + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + let track_ids: Vec = Runtime::Tracks::tracks() + .into_iter() + .filter_map(|x| { + if let Ok(track_id) = x.0.try_into() { + Some(track_id) + } else { + None + } + }) + .collect(); + + Ok(track_ids) + } + #[precompile::public("trackInfo(uint16)")] #[precompile::view] fn track_info( handle: &mut impl PrecompileHandle, track_id: u16, - ) -> EvmResult<(U256, U256, U256, U256, U256, U256)> { - // Fetch data from pallet + ) -> EvmResult<( + UnboundedBytes, + U256, + U256, + U256, + U256, + U256, + U256, + UnboundedBytes, + UnboundedBytes, + )> { + // Fetch data from runtime handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; let track_id: TrackIdOf = track_id .try_into() @@ -127,12 +157,15 @@ where let track_info = &tracks[index].1; Ok(( + track_info.name.as_bytes().into(), track_info.max_deciding.into(), track_info.decision_deposit.into(), track_info.prepare_period.into(), track_info.decision_period.into(), track_info.confirm_period.into(), track_info.min_enactment_period.into(), + track_info.min_approval.encode().into(), + track_info.min_support.encode().into(), )) } @@ -141,14 +174,50 @@ where /// Parameters: /// * track_id: The trackId for the origin from which the proposal is to be dispatched. /// * proposal: The proposed runtime call. - /// * at: If true then AT block_number, else AFTER block_number - /// * block_number: Inner block number for DispatchTime - #[precompile::public("submit(uint16,bytes,bool,uint32)")] - fn submit( + /// * block_number: Block number at which proposal is dispatched. + #[precompile::public("submitAt(uint16,bytes,uint32)")] + fn submit_at( + handle: &mut impl PrecompileHandle, + track_id: u16, + proposal: BoundedBytes, + block_number: u32, + ) -> EvmResult { + let origin: GovOrigin = track_id.try_into().map_err(|_| { + RevertReason::custom("Origin does not exist for TrackId").in_field("trackId") + })?; + let proposal_origin: Box> = Box::new(origin.into()); + let proposal: BoundedCallOf = Bounded::Inline( + frame_support::BoundedVec::try_from(proposal.as_bytes().to_vec()).map_err(|_| { + RevertReason::custom("Proposal input is not a runtime call").in_field("proposal") + })?, + ); + let enactment_moment = DispatchTime::At(block_number.into()); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + + let call = ReferendaCall::::submit { + proposal_origin, + proposal, + enactment_moment, + } + .into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + /// Propose a referendum on a privileged action. + /// + /// Parameters: + /// * track_id: The trackId for the origin from which the proposal is to be dispatched. + /// * proposal: The proposed runtime call. + /// * block_number: Block number after which proposal is dispatched. + #[precompile::public("submitAfter(uint16,bytes,uint32)")] + fn submit_after( handle: &mut impl PrecompileHandle, track_id: u16, proposal: BoundedBytes, - at: bool, block_number: u32, ) -> EvmResult { let origin: GovOrigin = track_id.try_into().map_err(|_| { @@ -160,11 +229,7 @@ where RevertReason::custom("Proposal input is not a runtime call").in_field("proposal") })?, ); - let enactment_moment: DispatchTime = if at { - DispatchTime::At(block_number.into()) - } else { - DispatchTime::After(block_number.into()) - }; + let enactment_moment = DispatchTime::After(block_number.into()); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); diff --git a/runtime/moonbase/src/governance/mod.rs b/runtime/moonbase/src/governance/mod.rs index d4785f1a4d..0367cdf063 100644 --- a/runtime/moonbase/src/governance/mod.rs +++ b/runtime/moonbase/src/governance/mod.rs @@ -24,7 +24,7 @@ use super::*; mod origins; pub use origins::{ - custom_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller, + custom_origins, GeneralAdmin, ReferendumCanceller, ReferendumKiller, WhitelistedCaller, }; mod tracks; pub use tracks::TracksInfo; diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs index ef79fff6c0..c133b5749b 100644 --- a/runtime/moonbase/src/governance/origins.rs +++ b/runtime/moonbase/src/governance/origins.rs @@ -18,28 +18,10 @@ pub use custom_origins::*; #[frame_support::pallet] pub mod custom_origins { - use frame_support::{pallet_prelude::*, traits::Currency}; - - type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + use frame_support::pallet_prelude::*; #[pallet::config] - pub trait Config: frame_system::Config { - /// Currency type to limit spends per spend origin - type Currency: Currency; - /// Maximum amount able to be spent by SmallSpender origin from treasury at once - #[pallet::constant] - type MaxSmallSpenderSpend: Get>; - /// Maximum amount able to be spent by MediumSpender origin from treasury at once - #[pallet::constant] - type MaxMediumSpenderSpend: Get>; - /// Maximum amount able to be spent by BigSpender origin from treasury at once - #[pallet::constant] - type MaxBigSpenderSpend: Get>; - /// Maximum amount able to be spent by Treasurer origin from treasury at once - #[pallet::constant] - type MaxTreasurerSpend: Get>; - } + pub trait Config: frame_system::Config {} #[pallet::pallet] pub struct Pallet(_); @@ -49,35 +31,24 @@ pub mod custom_origins { pub enum Origin { /// Origin able to dispatch a whitelisted call. WhitelistedCaller, - /// Origin able to spend up to MaxTreasurerSpend from the treasury at once. - Treasurer, + /// General admin + GeneralAdmin, /// Origin able to cancel referenda. ReferendumCanceller, /// Origin able to kill referenda. ReferendumKiller, - /// Origin able to spend up to MaxSmallSpenderSpend from the treasury at once. - SmallSpender, - /// Origin able to spend up to MaxMediumSpenderSpend from the treasury at once. - MediumSpender, - /// Origin able to spend up to MaxBigSpenderSpend from the treasury at once. - BigSpender, - /// General admin - GeneralAdmin, } + // where is this used, comment out and check TODO impl TryFrom for Origin { type Error = (); /// TrackId => Origin fn try_from(value: u8) -> Result { match value { 1 => Ok(Origin::WhitelistedCaller), - 10 => Ok(Origin::Treasurer), - 11 => Ok(Origin::ReferendumCanceller), - 12 => Ok(Origin::ReferendumKiller), - 13 => Ok(Origin::SmallSpender), - 14 => Ok(Origin::MediumSpender), - 15 => Ok(Origin::BigSpender), - 16 => Ok(Origin::GeneralAdmin), + 2 => Ok(Origin::GeneralAdmin), + 3 => Ok(Origin::ReferendumCanceller), + 4 => Ok(Origin::ReferendumKiller), _ => Err(()), } } @@ -96,13 +67,9 @@ pub mod custom_origins { fn into(self) -> u16 { match self { Origin::WhitelistedCaller => 1, - Origin::Treasurer => 10, - Origin::ReferendumCanceller => 11, - Origin::ReferendumKiller => 12, - Origin::SmallSpender => 13, - Origin::MediumSpender => 14, - Origin::BigSpender => 15, - Origin::GeneralAdmin => 16, + Origin::GeneralAdmin => 2, + Origin::ReferendumCanceller => 3, + Origin::ReferendumKiller => 4, } } } @@ -118,13 +85,9 @@ pub mod custom_origins { }; } has_consistent_conversions!(Origin::WhitelistedCaller); - has_consistent_conversions!(Origin::Treasurer); + has_consistent_conversions!(Origin::GeneralAdmin); has_consistent_conversions!(Origin::ReferendumCanceller); has_consistent_conversions!(Origin::ReferendumKiller); - has_consistent_conversions!(Origin::SmallSpender); - has_consistent_conversions!(Origin::MediumSpender); - has_consistent_conversions!(Origin::BigSpender); - has_consistent_conversions!(Origin::GeneralAdmin); } macro_rules! decl_unit_ensures { @@ -163,47 +126,4 @@ pub mod custom_origins { WhitelistedCaller, GeneralAdmin ); - - macro_rules! decl_ensure { - ( - $vis:vis type $name:ident: EnsureOrigin { - $( $item:ident = $success:expr, )* - } - ) => { - $vis struct $name(sp_std::marker::PhantomData); - impl> + From> - EnsureOrigin for $name - { - type Success = $success_type; - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - $( - Origin::$item => Ok($success), - )* - r => Err(O::from(r)), - }) - } - #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin() -> Result { - // By convention the more privileged origins go later, so for greatest chance - // of success, we want the last one. - let _result: Result = Err(()); - $( - let _result: Result = Ok(O::from(Origin::$item)); - )* - _result - } - } - } - } - - // Origins able to spend $AMOUNT from treasury at once - decl_ensure! { - pub type Spender: EnsureOrigin> { - SmallSpender = T::MaxSmallSpenderSpend::get(), - MediumSpender = T::MaxMediumSpenderSpend::get(), - BigSpender = T::MaxBigSpenderSpend::get(), - Treasurer = T::MaxTreasurerSpend::get(), - } - } } diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs index ea073df51b..0ac2e2db79 100644 --- a/runtime/moonbase/src/governance/referenda.rs +++ b/runtime/moonbase/src/governance/referenda.rs @@ -48,18 +48,7 @@ parameter_types! { pub const UndecidingTimeout: BlockNumber = 28 * DAYS; } -pub type TreasurySpender = EitherOf< - EnsureRootWithSuccess>, - custom_origins::Spender, ->; - -impl custom_origins::Config for Runtime { - type Currency = Balances; - type MaxSmallSpenderSpend = ConstU128<{ 2 * KILOUNIT * SUPPLY_FACTOR }>; - type MaxMediumSpenderSpend = ConstU128<{ 20 * KILOUNIT * SUPPLY_FACTOR }>; - type MaxBigSpenderSpend = ConstU128<{ 200 * KILOUNIT * SUPPLY_FACTOR }>; - type MaxTreasurerSpend = ConstU128<{ 500 * KILOUNIT * SUPPLY_FACTOR }>; -} +impl custom_origins::Config for Runtime {} // The purpose of this pallet is to queue calls to be dispatched as by root later => the Dispatch // origin corresponds to the Gov2 Whitelist track. diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs index b7a0f05fae..3c3949e7d6 100644 --- a/runtime/moonbase/src/governance/tracks.rs +++ b/runtime/moonbase/src/governance/tracks.rs @@ -22,8 +22,12 @@ use crate::currency::{KILOUNIT, SUPPLY_FACTOR, UNIT}; const fn percent(x: i32) -> sp_runtime::FixedI64 { sp_runtime::FixedI64::from_rational(x as u128, 100) } +const fn permill(x: i32) -> sp_runtime::FixedI64 { + sp_runtime::FixedI64::from_rational(x as u128, 1000) +} + use pallet_referenda::Curve; -const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] = [ +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 5] = [ ( 0, pallet_referenda::TrackInfo { @@ -31,7 +35,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] name: "root", // A limit for the number of referenda on this track that can be being decided at once. // For Root origin this should generally be just one. - max_deciding: 1, + max_deciding: 5, // Amount that must be placed on deposit before a decision can be made. decision_deposit: 100 * KILOUNIT * SUPPLY_FACTOR, // Amount of time this must be submitted for before a decision can be made. @@ -47,7 +51,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] min_approval: Curve::make_reciprocal(4, 14, percent(80), percent(50), percent(100)), // Minimum pre-conviction aye-votes ("support") as percentage of overall population that // is needed for approval as a function of time into decision period. - min_support: Curve::make_linear(14, 14, percent(0), percent(50)), + min_support: Curve::make_linear(14, 14, permill(5), percent(25)), }, ), ( @@ -60,32 +64,26 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] decision_period: 14 * DAYS, confirm_period: 10 * MINUTES, min_enactment_period: 30 * MINUTES, - min_approval: Curve::make_reciprocal( - 1, - 14 * 24, - percent(96), - percent(50), - percent(100), - ), - min_support: Curve::make_reciprocal(1, 14 * 24, percent(4), percent(2), percent(50)), + min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), + min_support: Curve::make_reciprocal(1, 14 * 24, percent(1), percent(0), percent(2)), }, ), ( - 10, + 2, pallet_referenda::TrackInfo { - name: "treasurer", - max_deciding: 1, - decision_deposit: 10 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 1 * DAYS, + name: "general_admin", + max_deciding: 10, + decision_deposit: 500 * UNIT * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, decision_period: 14 * DAYS, - confirm_period: 2 * DAYS, - min_enactment_period: 2 * DAYS, - min_approval: Curve::make_linear(14, 14, percent(50), percent(100)), - min_support: Curve::make_reciprocal(10, 14, percent(10), percent(0), percent(50)), + confirm_period: 1 * DAYS, + min_enactment_period: 1 * DAYS, + min_approval: Curve::make_reciprocal(4, 14, percent(80), percent(50), percent(100)), + min_support: Curve::make_reciprocal(7, 14, percent(10), percent(0), percent(50)), }, ), ( - 11, + 3, pallet_referenda::TrackInfo { name: "referendum_canceller", max_deciding: 20, @@ -99,7 +97,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] }, ), ( - 12, + 4, pallet_referenda::TrackInfo { name: "referendum_killer", max_deciding: 100, @@ -109,63 +107,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] confirm_period: 3 * HOURS, min_enactment_period: 10 * MINUTES, min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), - min_support: Curve::make_reciprocal(7, 14, percent(1), percent(0), percent(10)), - }, - ), - ( - 13, - pallet_referenda::TrackInfo { - name: "small_spender", - max_deciding: 5, - decision_deposit: 300 * UNIT * SUPPLY_FACTOR, - prepare_period: 1 * MINUTES, - decision_period: 14 * DAYS, - confirm_period: 12 * HOURS, - min_enactment_period: 1 * DAYS, - min_approval: Curve::make_linear(8, 14, percent(50), percent(100)), - min_support: Curve::make_reciprocal(2, 14, percent(1), percent(0), percent(10)), - }, - ), - ( - 14, - pallet_referenda::TrackInfo { - name: "medium_spender", - max_deciding: 5, - decision_deposit: 3 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 1 * MINUTES, - decision_period: 14 * DAYS, - confirm_period: 24 * HOURS, - min_enactment_period: 1 * DAYS, - min_approval: Curve::make_linear(10, 14, percent(50), percent(100)), - min_support: Curve::make_reciprocal(4, 14, percent(1), percent(0), percent(10)), - }, - ), - ( - 15, - pallet_referenda::TrackInfo { - name: "big_spender", - max_deciding: 5, - decision_deposit: 3 * KILOUNIT * SUPPLY_FACTOR, - prepare_period: 1 * MINUTES, - decision_period: 14 * DAYS, - confirm_period: 24 * HOURS, - min_enactment_period: 1 * DAYS, - min_approval: Curve::make_linear(14, 14, percent(50), percent(100)), - min_support: Curve::make_reciprocal(8, 14, percent(1), percent(0), percent(10)), - }, - ), - ( - 16, - pallet_referenda::TrackInfo { - name: "general_admin", - max_deciding: 10, - decision_deposit: 500 * SUPPLY_FACTOR, - prepare_period: 1 * HOURS, - decision_period: 14 * DAYS, - confirm_period: 1 * DAYS, - min_enactment_period: 1 * DAYS, - min_approval: Curve::make_linear(4, 14, percent(50), percent(100)), - min_support: Curve::make_reciprocal(7, 14, percent(10), percent(0), percent(50)), + min_support: Curve::make_reciprocal(1, 14, percent(1), percent(0), percent(10)), }, ), ]; diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index c53d16b789..cbbde7d0b9 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -115,7 +115,7 @@ pub type Precompiles = MoonbasePrecompiles; pub mod asset_config; pub mod governance; pub mod xcm_config; -use governance::{councils::*, referenda::*}; +use governance::councils::*; /// UNIT, the native token, uses 18 decimals of precision. pub mod currency { @@ -530,7 +530,7 @@ impl pallet_treasury::Config for Runtime { type WeightInfo = pallet_treasury::weights::SubstrateWeight; type SpendFunds = (); type ProposalBondMaximum = (); - type SpendOrigin = TreasurySpender; + type SpendOrigin = frame_support::traits::NeverEnsureOrigin; // Same as Polkadot } type IdentityForceOrigin = EitherOfDiverse< diff --git a/runtime/moonriver/Cargo.toml b/runtime/moonriver/Cargo.toml index 248530ddf8..31136e67a8 100644 --- a/runtime/moonriver/Cargo.toml +++ b/runtime/moonriver/Cargo.toml @@ -45,11 +45,14 @@ pallet-evm-precompile-balances-erc20 = { path = "../../precompiles/balances-erc2 pallet-evm-precompile-batch = { path = "../../precompiles/batch", default-features = false } pallet-evm-precompile-call-permit = { path = "../../precompiles/call-permit", default-features = false } pallet-evm-precompile-collective = { path = "../../precompiles/collective", default-features = false } +pallet-evm-precompile-conviction-voting = { path = "../../precompiles/conviction-voting", default-features = false } pallet-evm-precompile-crowdloan-rewards = { path = "../../precompiles/crowdloan-rewards", default-features = false } pallet-evm-precompile-democracy = { path = "../../precompiles/pallet-democracy", default-features = false } pallet-evm-precompile-parachain-staking = { path = "../../precompiles/parachain-staking", default-features = false } +pallet-evm-precompile-preimage = { path = "../../precompiles/preimage", default-features = false } pallet-evm-precompile-proxy = { path = "../../precompiles/proxy", default-features = false } pallet-evm-precompile-randomness = { path = "../../precompiles/randomness", default-features = false } +pallet-evm-precompile-referenda = { path = "../../precompiles/referenda", default-features = false } pallet-evm-precompile-relay-encoder = { path = "../../precompiles/relay-encoder", default-features = false } pallet-evm-precompile-xcm-transactor = { path = "../../precompiles/xcm-transactor", default-features = false } pallet-evm-precompile-xcm-utils = { path = "../../precompiles/xcm-utils", default-features = false } @@ -70,11 +73,13 @@ frame-system-rpc-runtime-api = { git = "https://github.com/purestake/substrate", pallet-assets = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-collective = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-conviction-voting = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-democracy = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-identity = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-proxy = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-randomness-collective-flip = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-referenda = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-scheduler = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-society = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-timestamp = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } @@ -82,6 +87,7 @@ pallet-transaction-payment = { git = "https://github.com/purestake/substrate", b pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-treasury = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } pallet-utility = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } +pallet-whitelist = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive", "max-encoded-len" ] } scale-info = { version = "2.0", default-features = false, features = [ "derive" ] } sp-api = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.32", default-features = false } @@ -191,6 +197,7 @@ std = [ "pallet-balances/std", "pallet-base-fee/std", "pallet-collective/std", + "pallet-conviction-voting/std", "pallet-crowdloan-rewards/std", "pallet-democracy/std", "pallet-ethereum-chain-id/std", @@ -200,9 +207,12 @@ std = [ "pallet-evm-precompile-batch/std", "pallet-evm-precompile-call-permit/std", "pallet-evm-precompile-collective/std", + "pallet-evm-precompile-conviction-voting/std", "pallet-evm-precompile-democracy/std", "pallet-evm-precompile-parachain-staking/std", + "pallet-evm-precompile-preimage/std", "pallet-evm-precompile-randomness/std", + "pallet-evm-precompile-referenda/std", "pallet-evm-precompile-xcm-transactor/std", "pallet-evm-precompile-xcm-utils/std", "pallet-evm-precompile-xtokens/std", @@ -217,6 +227,7 @@ std = [ "pallet-proxy/std", "pallet-randomness-collective-flip/std", "pallet-randomness/std", + "pallet-referenda/std", "pallet-scheduler/std", "pallet-society/std", "pallet-timestamp/std", @@ -224,6 +235,7 @@ std = [ "pallet-transaction-payment/std", "pallet-treasury/std", "pallet-utility/std", + "pallet-whitelist/std", "pallet-xcm-transactor/std", "pallet-xcm/std", "parachain-info/std", @@ -277,6 +289,7 @@ runtime-benchmarks = [ "pallet-author-slot-filter/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collective/runtime-benchmarks", + "pallet-conviction-voting/runtime-benchmarks", "pallet-crowdloan-rewards/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", "pallet-migrations/runtime-benchmarks", @@ -284,8 +297,10 @@ runtime-benchmarks = [ "pallet-parachain-staking/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", "pallet-randomness/runtime-benchmarks", + "pallet-referenda/runtime-benchmarks", "pallet-society/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-whitelist/runtime-benchmarks", "pallet-xcm-benchmarks", "pallet-xcm-transactor/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", @@ -303,13 +318,16 @@ try-runtime = [ "pallet-author-slot-filter/try-runtime", "pallet-balances/try-runtime", "pallet-collective/try-runtime", + "pallet-conviction-voting/try-runtime", "pallet-democracy/try-runtime", "pallet-maintenance-mode/try-runtime", #"pallet-crowdloan-rewards/try-runtime", "pallet-migrations/try-runtime", "pallet-parachain-staking/try-runtime", "pallet-preimage/try-runtime", + "pallet-referenda/try-runtime", "pallet-scheduler/try-runtime", "pallet-society/try-runtime", "pallet-timestamp/try-runtime", + "pallet-whitelist/try-runtime", ] diff --git a/runtime/moonriver/src/governance/councils.rs b/runtime/moonriver/src/governance/councils.rs new file mode 100644 index 0000000000..7c915525e9 --- /dev/null +++ b/runtime/moonriver/src/governance/councils.rs @@ -0,0 +1,68 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Councils for Gov1 + +use super::*; + +pub type CouncilInstance = pallet_collective::Instance1; +pub type TechCommitteeInstance = pallet_collective::Instance2; +pub type TreasuryCouncilInstance = pallet_collective::Instance3; + +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Proposal = RuntimeCall; + /// The maximum amount of time (in blocks) for council members to vote on motions. + /// Motions may end in fewer blocks if enough votes are cast to determine the result. + type MotionDuration = ConstU32<{ 3 * DAYS }>; + /// The maximum number of proposals that can be open in the council at once. + type MaxProposals = ConstU32<100>; + /// The maximum number of council members. + type MaxMembers = ConstU32<100>; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Proposal = RuntimeCall; + /// The maximum amount of time (in blocks) for technical committee members to vote on motions. + /// Motions may end in fewer blocks if enough votes are cast to determine the result. + type MotionDuration = ConstU32<{ 3 * DAYS }>; + /// The maximum number of proposals that can be open in the technical committee at once. + type MaxProposals = ConstU32<100>; + /// The maximum number of technical committee members. + type MaxMembers = ConstU32<100>; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Proposal = RuntimeCall; + /// The maximum amount of time (in blocks) for treasury council members to vote on motions. + /// Motions may end in fewer blocks if enough votes are cast to determine the result. + type MotionDuration = ConstU32<{ 3 * DAYS }>; + /// The maximum number of proposals that can be open in the treasury council at once. + type MaxProposals = ConstU32<20>; + /// The maximum number of treasury council members. + type MaxMembers = ConstU32<9>; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} diff --git a/runtime/moonriver/src/governance/democracy.rs b/runtime/moonriver/src/governance/democracy.rs new file mode 100644 index 0000000000..d27fedaf12 --- /dev/null +++ b/runtime/moonriver/src/governance/democracy.rs @@ -0,0 +1,76 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Democracy config for Gov1 + +use super::councils::*; +use crate::*; + +// The purpose of this offset is to ensure that a democratic proposal will not apply in the same +// block as a round change. +const ENACTMENT_OFFSET: u32 = 300; + +impl pallet_democracy::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type EnactmentPeriod = ConstU32<{ 1 * DAYS + ENACTMENT_OFFSET }>; + type LaunchPeriod = ConstU32<{ 1 * DAYS }>; + type VotingPeriod = ConstU32<{ 5 * DAYS }>; + + type VoteLockingPeriod = ConstU32<{ 1 * DAYS }>; + type FastTrackVotingPeriod = ConstU32<{ 3 * HOURS }>; + type MinimumDeposit = ConstU128<{ 4 * currency::MOVR * currency::SUPPLY_FACTOR }>; + /// To decide what their next motion is. + type ExternalOrigin = + pallet_collective::EnsureProportionAtLeast; + /// To have the next scheduled referendum be a straight majority-carries vote. + type ExternalMajorityOrigin = + pallet_collective::EnsureProportionAtLeast; + /// To have the next scheduled referendum be a straight default-carries (NTB) vote. + type ExternalDefaultOrigin = + pallet_collective::EnsureProportionAtLeast; + /// To allow a shorter voting/enactment period for external proposals. + type FastTrackOrigin = + pallet_collective::EnsureProportionAtLeast; + /// To instant fast track. + type InstantOrigin = + pallet_collective::EnsureProportionAtLeast; + // To cancel a proposal which has been passed. + type CancellationOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, + >; + // To cancel a proposal before it has been passed. + type CancelProposalOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, + >; + type BlacklistOrigin = EnsureRoot; + // Any single technical committee member may veto a coming council proposal, however they can + // only do it once and it lasts only for the cooloff period. + type VetoOrigin = pallet_collective::EnsureMember; + type CooloffPeriod = ConstU32<{ 7 * DAYS }>; + type Slash = (); + type InstantAllowed = ConstBool; + type Scheduler = Scheduler; + type MaxVotes = ConstU32<100>; + type PalletsOrigin = OriginCaller; + type WeightInfo = pallet_democracy::weights::SubstrateWeight; + type MaxProposals = ConstU32<100>; + type Preimages = Preimage; + type MaxDeposits = ConstU32<100>; + type MaxBlacklisted = ConstU32<100>; +} diff --git a/runtime/moonriver/src/governance/mod.rs b/runtime/moonriver/src/governance/mod.rs new file mode 100644 index 0000000000..0367cdf063 --- /dev/null +++ b/runtime/moonriver/src/governance/mod.rs @@ -0,0 +1,30 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! Governance configurations + +pub mod councils; +mod democracy; +pub mod referenda; + +use super::*; + +mod origins; +pub use origins::{ + custom_origins, GeneralAdmin, ReferendumCanceller, ReferendumKiller, WhitelistedCaller, +}; +mod tracks; +pub use tracks::TracksInfo; diff --git a/runtime/moonriver/src/governance/origins.rs b/runtime/moonriver/src/governance/origins.rs new file mode 100644 index 0000000000..c0e85c0f54 --- /dev/null +++ b/runtime/moonriver/src/governance/origins.rs @@ -0,0 +1,128 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +//! Custom origins for governance interventions. +#![cfg_attr(not(feature = "std"), no_std)] + +pub use custom_origins::*; + +#[frame_support::pallet] +pub mod custom_origins { + use frame_support::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)] + #[pallet::origin] + pub enum Origin { + /// Origin able to dispatch a whitelisted call. + WhitelistedCaller, + /// General admin + GeneralAdmin, + /// Origin able to cancel referenda. + ReferendumCanceller, + /// Origin able to kill referenda. + ReferendumKiller, + } + + impl TryFrom for Origin { + type Error = (); + /// TrackId => Origin + fn try_from(value: u8) -> Result { + match value { + 1 => Ok(Origin::WhitelistedCaller), + 2 => Ok(Origin::GeneralAdmin), + 3 => Ok(Origin::ReferendumCanceller), + 4 => Ok(Origin::ReferendumKiller), + _ => Err(()), + } + } + } + + impl TryFrom for Origin { + type Error = (); + /// TrackId => Origin + fn try_from(value: u16) -> Result { + (value as u8).try_into() + } + } + + impl Into for Origin { + /// Origin => TrackId + fn into(self) -> u16 { + match self { + Origin::WhitelistedCaller => 1, + Origin::GeneralAdmin => 2, + Origin::ReferendumCanceller => 3, + Origin::ReferendumKiller => 4, + } + } + } + + #[test] + fn origin_track_conversion_is_consistent() { + macro_rules! has_consistent_conversions { + ( $o:expr ) => { + let origin_as_u16 = >::into($o); + let u16_as_u8: u8 = origin_as_u16.try_into().unwrap(); + let u8_as_origin: Origin = u16_as_u8.try_into().unwrap(); + assert_eq!($o, u8_as_origin); + }; + } + has_consistent_conversions!(Origin::WhitelistedCaller); + has_consistent_conversions!(Origin::GeneralAdmin); + has_consistent_conversions!(Origin::ReferendumCanceller); + has_consistent_conversions!(Origin::ReferendumKiller); + } + + macro_rules! decl_unit_ensures { + ( $name:ident: $success_type:ty = $success:expr ) => { + pub struct $name; + impl> + From> + EnsureOrigin for $name + { + type Success = $success_type; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + Origin::$name => Ok($success), + r => Err(O::from(r)), + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::$name)) + } + } + }; + ( $name:ident ) => { decl_unit_ensures! { $name : () = () } }; + ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => { + decl_unit_ensures! { $name: $success_type = $success } + decl_unit_ensures! { $( $rest )* } + }; + ( $name:ident, $( $rest:tt )* ) => { + decl_unit_ensures! { $name } + decl_unit_ensures! { $( $rest )* } + }; + () => {} + } + decl_unit_ensures!( + ReferendumCanceller, + ReferendumKiller, + WhitelistedCaller, + GeneralAdmin + ); +} diff --git a/runtime/moonriver/src/governance/referenda.rs b/runtime/moonriver/src/governance/referenda.rs new file mode 100644 index 0000000000..71b527d8e7 --- /dev/null +++ b/runtime/moonriver/src/governance/referenda.rs @@ -0,0 +1,95 @@ +// Copyright 2019-2022 PureStake Inc. +// This file is part of Moonbeam. + +// Moonbeam is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Moonbeam is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Moonbeam. If not, see . + +//! # Gov2 config +//! Includes runtime configs for these substrate pallets: +//! 1. pallet-conviction-voting +//! 2. pallet-whitelist +//! 3. pallet-referenda + +use super::*; +use crate::currency::*; +use frame_support::traits::{EitherOf, MapSuccess}; +use frame_system::EnsureRootWithSuccess; +use sp_runtime::traits::Replace; + +parameter_types! { + pub const VoteLockingPeriod: BlockNumber = 7 * DAYS; +} + +impl pallet_conviction_voting::Config for Runtime { + type WeightInfo = pallet_conviction_voting::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type Polls = Referenda; + type MaxTurnout = frame_support::traits::TotalIssuanceOf; + // Maximum number of concurrent votes an account may have + type MaxVotes = ConstU32<512>; + // Minimum period of vote locking + type VoteLockingPeriod = VoteLockingPeriod; +} + +parameter_types! { + pub const AlarmInterval: BlockNumber = 1; + pub const SubmissionDeposit: Balance = 100 * MOVR * SUPPLY_FACTOR; + pub const UndecidingTimeout: BlockNumber = 28 * DAYS; +} + +impl custom_origins::Config for Runtime {} + +// The purpose of this pallet is to queue calls to be dispatched as by root later => the Dispatch +// origin corresponds to the Gov2 Whitelist track. +impl pallet_whitelist::Config for Runtime { + type WeightInfo = pallet_whitelist::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type WhitelistOrigin = EitherOf< + EnsureRootWithSuccess>, + MapSuccess< + pallet_collective::EnsureProportionAtLeast< + Self::AccountId, + TechCommitteeInstance, + 2, + 3, + >, + Replace>, + >, + >; + type DispatchWhitelistedOrigin = EitherOf, WhitelistedCaller>; + type PreimageProvider = Preimage; +} + +pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); + +impl pallet_referenda::Config for Runtime { + type WeightInfo = pallet_referenda::weights::SubstrateWeight; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + type SubmitOrigin = frame_system::EnsureSigned; + type CancelOrigin = ReferendumCanceller; + type KillOrigin = ReferendumKiller; + type Slash = Treasury; + type Votes = pallet_conviction_voting::VotesOf; + type Tally = pallet_conviction_voting::TallyOf; + type SubmissionDeposit = SubmissionDeposit; + type MaxQueued = ConstU32<100>; + type UndecidingTimeout = UndecidingTimeout; + type AlarmInterval = AlarmInterval; + type Tracks = TracksInfo; + type Preimages = Preimage; +} diff --git a/runtime/moonriver/src/governance/tracks.rs b/runtime/moonriver/src/governance/tracks.rs new file mode 100644 index 0000000000..64d29b6d86 --- /dev/null +++ b/runtime/moonriver/src/governance/tracks.rs @@ -0,0 +1,150 @@ +// Copyright 2022 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Track configurations for governance. + +use super::*; +use crate::currency::{KILOMOVR, MOVR, SUPPLY_FACTOR}; + +const fn percent(x: i32) -> sp_runtime::FixedI64 { + sp_runtime::FixedI64::from_rational(x as u128, 100) +} +const fn permill(x: i32) -> sp_runtime::FixedI64 { + sp_runtime::FixedI64::from_rational(x as u128, 1000) +} + +use pallet_referenda::Curve; +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 5] = [ + ( + 0, + pallet_referenda::TrackInfo { + // Name of this track. + name: "root", + // A limit for the number of referenda on this track that can be being decided at once. + // For Root origin this should generally be just one. + max_deciding: 5, + // Amount that must be placed on deposit before a decision can be made. + decision_deposit: 100 * KILOMOVR * SUPPLY_FACTOR, + // Amount of time this must be submitted for before a decision can be made. + prepare_period: 1 * DAYS, + // Amount of time that a decision may take to be approved prior to cancellation. + decision_period: 14 * DAYS, + // Amount of time that the approval criteria must hold before it can be approved. + confirm_period: 1 * DAYS, + // Minimum amount of time that an approved proposal must be in the dispatch queue. + min_enactment_period: 1 * DAYS, + // Minimum aye votes as percentage of overall conviction-weighted votes needed for + // approval as a function of time into decision period. + min_approval: Curve::make_reciprocal(4, 14, percent(80), percent(50), percent(100)), + // Minimum pre-conviction aye-votes ("support") as percentage of overall population that + // is needed for approval as a function of time into decision period. + min_support: Curve::make_linear(14, 14, permill(5), percent(25)), + }, + ), + ( + 1, + pallet_referenda::TrackInfo { + name: "whitelisted_caller", + max_deciding: 100, + decision_deposit: 10 * KILOMOVR * SUPPLY_FACTOR, + prepare_period: 10 * MINUTES, + decision_period: 14 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 30 * MINUTES, + min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), + min_support: Curve::make_reciprocal(1, 14 * 24, percent(1), percent(0), percent(2)), + }, + ), + ( + 2, + pallet_referenda::TrackInfo { + name: "general_admin", + max_deciding: 10, + decision_deposit: 500 * MOVR * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 1 * DAYS, + min_enactment_period: 1 * DAYS, + min_approval: Curve::make_reciprocal(4, 14, percent(80), percent(50), percent(100)), + min_support: Curve::make_reciprocal(7, 14, percent(10), percent(0), percent(50)), + }, + ), + ( + 3, + pallet_referenda::TrackInfo { + name: "referendum_canceller", + max_deciding: 20, + decision_deposit: 10 * KILOMOVR * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), + min_support: Curve::make_reciprocal(1, 14, percent(1), percent(0), percent(50)), + }, + ), + ( + 4, + pallet_referenda::TrackInfo { + name: "referendum_killer", + max_deciding: 100, + decision_deposit: 20 * KILOMOVR * SUPPLY_FACTOR, + prepare_period: 1 * HOURS, + decision_period: 14 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)), + min_support: Curve::make_reciprocal(1, 14, percent(1), percent(0), percent(10)), + }, + ), +]; + +pub struct TracksInfo; +impl pallet_referenda::TracksInfo for TracksInfo { + type Id = u16; + type RuntimeOrigin = ::PalletsOrigin; + fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { + &TRACKS_DATA[..] + } + fn track_for(id: &Self::RuntimeOrigin) -> Result { + if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) { + match system_origin { + frame_system::RawOrigin::Root => Ok(0), + _ => Err(()), + } + } else if let Ok(custom_origin) = custom_origins::Origin::try_from(id.clone()) { + // Origins => TrackId defined in Into for Origin + Ok(custom_origin.into()) + } else { + Err(()) + } + } +} + +#[test] +/// To ensure voters are always locked into their vote +fn vote_locking_always_longer_than_enactment_period() { + for (_, track) in TRACKS_DATA { + assert!( + ::VoteLockingPeriod::get() + > track.min_enactment_period, + "Track {} has enactment period {} < vote locking period {}", + track.name, + track.min_enactment_period, + ::VoteLockingPeriod::get(), + ); + } +} diff --git a/runtime/moonriver/src/lib.rs b/runtime/moonriver/src/lib.rs index ce12ef4518..fa79e042af 100644 --- a/runtime/moonriver/src/lib.rs +++ b/runtime/moonriver/src/lib.rs @@ -106,7 +106,9 @@ pub use sp_runtime::BuildStorage; pub type Precompiles = MoonriverPrecompiles; pub mod asset_config; +pub mod governance; pub mod xcm_config; +use governance::councils::*; /// MOVR, the native token, uses 18 decimals of precision. pub mod currency { @@ -480,111 +482,6 @@ impl pallet_preimage::Config for Runtime { type ByteDeposit = ConstU128<{ currency::STORAGE_BYTE_FEE }>; } -type CouncilInstance = pallet_collective::Instance1; -type TechCommitteeInstance = pallet_collective::Instance2; -type TreasuryCouncilInstance = pallet_collective::Instance3; - -impl pallet_collective::Config for Runtime { - type RuntimeOrigin = RuntimeOrigin; - type RuntimeEvent = RuntimeEvent; - type Proposal = RuntimeCall; - /// The maximum amount of time (in blocks) for council members to vote on motions. - /// Motions may end in fewer blocks if enough votes are cast to determine the result. - type MotionDuration = ConstU32<{ 3 * DAYS }>; - /// The maximum number of proposals that can be open in the council at once. - type MaxProposals = ConstU32<100>; - /// The maximum number of council members. - type MaxMembers = ConstU32<100>; - type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; - type WeightInfo = pallet_collective::weights::SubstrateWeight; -} - -impl pallet_collective::Config for Runtime { - type RuntimeOrigin = RuntimeOrigin; - type RuntimeEvent = RuntimeEvent; - type Proposal = RuntimeCall; - /// The maximum amount of time (in blocks) for technical committee members to vote on motions. - /// Motions may end in fewer blocks if enough votes are cast to determine the result. - type MotionDuration = ConstU32<{ 3 * DAYS }>; - /// The maximum number of proposals that can be open in the technical committee at once. - type MaxProposals = ConstU32<100>; - /// The maximum number of technical committee members. - type MaxMembers = ConstU32<100>; - type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; - type WeightInfo = pallet_collective::weights::SubstrateWeight; -} - -impl pallet_collective::Config for Runtime { - type RuntimeOrigin = RuntimeOrigin; - type RuntimeEvent = RuntimeEvent; - type Proposal = RuntimeCall; - /// The maximum amount of time (in blocks) for treasury council members to vote on motions. - /// Motions may end in fewer blocks if enough votes are cast to determine the result. - type MotionDuration = ConstU32<{ 3 * DAYS }>; - /// The maximum number of proposals that can be open in the treasury council at once. - type MaxProposals = ConstU32<20>; - /// The maximum number of treasury council members. - type MaxMembers = ConstU32<9>; - type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; - type WeightInfo = pallet_collective::weights::SubstrateWeight; -} - -// The purpose of this offset is to ensure that a democratic proposal will not apply in the same -// block as a round change. -const ENACTMENT_OFFSET: u32 = 300; - -impl pallet_democracy::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type EnactmentPeriod = ConstU32<{ 1 * DAYS + ENACTMENT_OFFSET }>; - type LaunchPeriod = ConstU32<{ 1 * DAYS }>; - type VotingPeriod = ConstU32<{ 5 * DAYS }>; - - type VoteLockingPeriod = ConstU32<{ 1 * DAYS }>; - type FastTrackVotingPeriod = ConstU32<{ 3 * HOURS }>; - type MinimumDeposit = ConstU128<{ 4 * currency::MOVR * currency::SUPPLY_FACTOR }>; - /// To decide what their next motion is. - type ExternalOrigin = - pallet_collective::EnsureProportionAtLeast; - /// To have the next scheduled referendum be a straight majority-carries vote. - type ExternalMajorityOrigin = - pallet_collective::EnsureProportionAtLeast; - /// To have the next scheduled referendum be a straight default-carries (NTB) vote. - type ExternalDefaultOrigin = - pallet_collective::EnsureProportionAtLeast; - /// To allow a shorter voting/enactment period for external proposals. - type FastTrackOrigin = - pallet_collective::EnsureProportionAtLeast; - /// To instant fast track. - type InstantOrigin = - pallet_collective::EnsureProportionAtLeast; - // To cancel a proposal which has been passed. - type CancellationOrigin = EitherOfDiverse< - EnsureRoot, - pallet_collective::EnsureProportionAtLeast, - >; - // To cancel a proposal before it has been passed. - type CancelProposalOrigin = EitherOfDiverse< - EnsureRoot, - pallet_collective::EnsureProportionAtLeast, - >; - type BlacklistOrigin = EnsureRoot; - // Any single technical committee member may veto a coming council proposal, however they can - // only do it once and it lasts only for the cooloff period. - type VetoOrigin = pallet_collective::EnsureMember; - type CooloffPeriod = ConstU32<{ 7 * DAYS }>; - type Slash = (); - type InstantAllowed = ConstBool; - type Scheduler = Scheduler; - type MaxVotes = ConstU32<100>; - type PalletsOrigin = OriginCaller; - type WeightInfo = pallet_democracy::weights::SubstrateWeight; - type MaxProposals = ConstU32<100>; - type Preimages = Preimage; - type MaxDeposits = ConstU32<100>; - type MaxBlacklisted = ConstU32<100>; -} - parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); pub const TreasuryId: PalletId = PalletId(*b"py/trsry"); @@ -1239,6 +1136,10 @@ construct_runtime! { Scheduler: pallet_scheduler::{Pallet, Storage, Event, Call} = 60, Democracy: pallet_democracy::{Pallet, Storage, Config, Event, Call} = 61, Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 62, + ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 63, + Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 64, + Origins: governance::custom_origins::{Origin} = 65, + Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 66, // Council stuff. CouncilCollective: diff --git a/runtime/moonriver/src/precompiles.rs b/runtime/moonriver/src/precompiles.rs index 38e579663b..dbf5307788 100644 --- a/runtime/moonriver/src/precompiles.rs +++ b/runtime/moonriver/src/precompiles.rs @@ -28,11 +28,14 @@ use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_call_permit::CallPermitPrecompile; use pallet_evm_precompile_collective::CollectivePrecompile; +use pallet_evm_precompile_conviction_voting::ConvictionVotingPrecompile; use pallet_evm_precompile_crowdloan_rewards::CrowdloanRewardsPrecompile; use pallet_evm_precompile_democracy::DemocracyPrecompile; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_parachain_staking::ParachainStakingPrecompile; +use pallet_evm_precompile_preimage::PreimagePrecompile; use pallet_evm_precompile_randomness::RandomnessPrecompile; +use pallet_evm_precompile_referenda::ReferendaPrecompile; use pallet_evm_precompile_relay_encoder::RelayEncoderPrecompile; use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; @@ -128,6 +131,12 @@ pub type MoonriverPrecompiles = PrecompileSetBuilder< PrecompileAt, CollectivePrecompile>, PrecompileAt, CollectivePrecompile>, PrecompileAt, CollectivePrecompile>, + PrecompileAt< + AddressU64<2065>, + ReferendaPrecompile, + >, + PrecompileAt, ConvictionVotingPrecompile>, + PrecompileAt, PreimagePrecompile>, ), >, // Prefixed precompile sets (XC20) diff --git a/runtime/moonriver/tests/integration_test.rs b/runtime/moonriver/tests/integration_test.rs index 05f2172c06..aa6e5dcdb6 100644 --- a/runtime/moonriver/tests/integration_test.rs +++ b/runtime/moonriver/tests/integration_test.rs @@ -2769,7 +2769,7 @@ fn precompile_existence() { let precompiles = Precompiles::new(); let precompile_addresses: std::collections::BTreeSet<_> = vec![ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1024, 1026, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, - 2056, 2057, 2058, 2060, 2062, 2063, 2064, + 2056, 2057, 2058, 2060, 2062, 2063, 2064, 2065, 2066, 2067, ] .into_iter() .map(H160::from_low_u64_be) diff --git a/tests/smoke-tests/test-balances-consistency.ts b/tests/smoke-tests/test-balances-consistency.ts index ad1b7ae702..9a93d4c1f6 100644 --- a/tests/smoke-tests/test-balances-consistency.ts +++ b/tests/smoke-tests/test-balances-consistency.ts @@ -272,7 +272,9 @@ describeSmokeSuite(`Verifying balances consistency...`, (context) => { .filter((status) => status[1].unwrap().isUnrequested || status[1].unwrap().isRequested) .map((status) => { const deposit = extractPreimageDeposit( - status[1].unwrap().asUnrequested || status[1].unwrap().asRequested + status[1].unwrap().isUnrequested + ? status[1].unwrap().asUnrequested + : status[1].unwrap().asRequested ); return { accountId: deposit.accountId, diff --git a/tests/smoke-tests/test-ethereum-contract-code.ts b/tests/smoke-tests/test-ethereum-contract-code.ts index 38cf062db3..0d0cf159d5 100644 --- a/tests/smoke-tests/test-ethereum-contract-code.ts +++ b/tests/smoke-tests/test-ethereum-contract-code.ts @@ -18,10 +18,10 @@ describeSmokeSuite(`Ethereum contract bytecode should not be large...`, (context return (hex.length - 2) / 2; }; - before("Retrieve all contrcact bytecode", async function () { + before("Retrieve all contract bytecode", async function () { this.timeout(3_000_000); - const limit = 1000; + const limit = 500; let last_key = ""; let count = 0; From db81510c7fa85fd338a5a0a1083db9556fa75adb Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 17 Jan 2023 10:59:19 -0500 Subject: [PATCH 47/52] remove TryFrom u8 impl for Origin unused --- runtime/moonbase/src/governance/origins.rs | 13 ++----------- runtime/moonriver/src/governance/origins.rs | 12 ++---------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs index c133b5749b..a95925659b 100644 --- a/runtime/moonbase/src/governance/origins.rs +++ b/runtime/moonbase/src/governance/origins.rs @@ -39,11 +39,10 @@ pub mod custom_origins { ReferendumKiller, } - // where is this used, comment out and check TODO - impl TryFrom for Origin { + impl TryFrom for Origin { type Error = (); /// TrackId => Origin - fn try_from(value: u8) -> Result { + fn try_from(value: u16) -> Result { match value { 1 => Ok(Origin::WhitelistedCaller), 2 => Ok(Origin::GeneralAdmin), @@ -54,14 +53,6 @@ pub mod custom_origins { } } - impl TryFrom for Origin { - type Error = (); - /// TrackId => Origin - fn try_from(value: u16) -> Result { - (value as u8).try_into() - } - } - impl Into for Origin { /// Origin => TrackId fn into(self) -> u16 { diff --git a/runtime/moonriver/src/governance/origins.rs b/runtime/moonriver/src/governance/origins.rs index c0e85c0f54..a95925659b 100644 --- a/runtime/moonriver/src/governance/origins.rs +++ b/runtime/moonriver/src/governance/origins.rs @@ -39,10 +39,10 @@ pub mod custom_origins { ReferendumKiller, } - impl TryFrom for Origin { + impl TryFrom for Origin { type Error = (); /// TrackId => Origin - fn try_from(value: u8) -> Result { + fn try_from(value: u16) -> Result { match value { 1 => Ok(Origin::WhitelistedCaller), 2 => Ok(Origin::GeneralAdmin), @@ -53,14 +53,6 @@ pub mod custom_origins { } } - impl TryFrom for Origin { - type Error = (); - /// TrackId => Origin - fn try_from(value: u16) -> Result { - (value as u8).try_into() - } - } - impl Into for Origin { /// Origin => TrackId fn into(self) -> u16 { From d3a8bdaade84f4a6450b25b3f6d3c6ba7a00211a Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 17 Jan 2023 11:03:46 -0500 Subject: [PATCH 48/52] split convictionVoting vote into voteYes and voteNo so can add voteAbstain in future version without breaking backwards compatibility --- .../conviction-voting/ConvictionVoting.sol | 19 +++++-- precompiles/conviction-voting/src/lib.rs | 53 ++++++++++++++++--- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index 3d11a988ac..ed9df960d5 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -33,15 +33,24 @@ interface ConvictionVoting { Locked6x } - /// @dev Vote in a poll. - /// @custom:selector 35ee6e0e + /// @dev Vote yes in a poll. + /// @custom:selector da9df518 /// @param pollIndex Index of poll - /// @param aye Yes or no vote /// @param voteAmount Balance locked for vote /// @param conviction Conviction multiplier for length of vote lock - function vote( + function voteYes( + uint32 pollIndex, + uint256 voteAmount, + Conviction conviction + ) external; + + /// @dev Vote no in a poll. + /// @custom:selector cc600eba + /// @param pollIndex Index of poll + /// @param voteAmount Balance locked for vote + /// @param conviction Conviction multiplier for length of vote lock + function voteNo( uint32 pollIndex, - bool aye, uint256 voteAmount, Conviction conviction ) external; diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index 8c722eccf3..a8c3253e15 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -69,18 +69,16 @@ where IndexOf: TryFrom, ClassOf: TryFrom, { - /// Vote in a poll. + /// Vote yes in a poll. /// /// Parameters: /// * poll_index: Index of poll - /// * aye: Yes or no vote /// * vote_amount: Balance locked for vote /// * conviction: Conviction multiplier for length of vote lock - #[precompile::public("vote(uint32,bool,uint256,uint8)")] - fn vote( + #[precompile::public("voteYes(uint32,uint256,uint8)")] + fn vote_yes( handle: &mut impl PrecompileHandle, poll_index: u32, - aye: bool, vote_amount: U256, conviction: u8, ) -> EvmResult { @@ -89,13 +87,54 @@ where let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; let vote = AccountVote::Standard { - vote: Vote { aye, conviction }, + vote: Vote { + aye: true, + conviction, + }, balance: vote_amount, }; log::trace!(target: "conviction-voting-precompile", "Voting {:?} on poll {:?}, with conviction {:?}", - aye, poll_index, conviction + true, poll_index, conviction + ); + + let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); + let call = ConvictionVotingCall::::vote { poll_index, vote }.into(); + + >::try_dispatch(handle, Some(origin).into(), call)?; + + Ok(()) + } + + /// Vote no in a poll. + /// + /// Parameters: + /// * poll_index: Index of poll + /// * vote_amount: Balance locked for vote + /// * conviction: Conviction multiplier for length of vote lock + #[precompile::public("voteNo(uint32,uint256,uint8)")] + fn vote_no( + handle: &mut impl PrecompileHandle, + poll_index: u32, + vote_amount: U256, + conviction: u8, + ) -> EvmResult { + let poll_index = Self::u32_to_index(poll_index).in_field("pollIndex")?; + let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; + let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; + + let vote = AccountVote::Standard { + vote: Vote { + aye: false, + conviction, + }, + balance: vote_amount, + }; + + log::trace!(target: "conviction-voting-precompile", + "Voting {:?} on poll {:?}, with conviction {:?}", + false, poll_index, conviction ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); From 4c3e81b1faaeee31a587c26a7fa84f12223a75b8 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 17 Jan 2023 11:31:16 -0500 Subject: [PATCH 49/52] fix consistent conversion test --- runtime/moonbase/src/governance/origins.rs | 5 ++--- runtime/moonriver/src/governance/origins.rs | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs index a95925659b..6f131bbd30 100644 --- a/runtime/moonbase/src/governance/origins.rs +++ b/runtime/moonbase/src/governance/origins.rs @@ -70,9 +70,8 @@ pub mod custom_origins { macro_rules! has_consistent_conversions { ( $o:expr ) => { let origin_as_u16 = >::into($o); - let u16_as_u8: u8 = origin_as_u16.try_into().unwrap(); - let u8_as_origin: Origin = u16_as_u8.try_into().unwrap(); - assert_eq!($o, u8_as_origin); + let u16_as_origin: Origin = origin_as_u16.try_into().unwrap(); + assert_eq!($o, u16_as_origin); }; } has_consistent_conversions!(Origin::WhitelistedCaller); diff --git a/runtime/moonriver/src/governance/origins.rs b/runtime/moonriver/src/governance/origins.rs index a95925659b..6f131bbd30 100644 --- a/runtime/moonriver/src/governance/origins.rs +++ b/runtime/moonriver/src/governance/origins.rs @@ -70,9 +70,8 @@ pub mod custom_origins { macro_rules! has_consistent_conversions { ( $o:expr ) => { let origin_as_u16 = >::into($o); - let u16_as_u8: u8 = origin_as_u16.try_into().unwrap(); - let u8_as_origin: Origin = u16_as_u8.try_into().unwrap(); - assert_eq!($o, u8_as_origin); + let u16_as_origin: Origin = origin_as_u16.try_into().unwrap(); + assert_eq!($o, u16_as_origin); }; } has_consistent_conversions!(Origin::WhitelistedCaller); From be79f7c73011b576633e8e96dd9928abc6714ba7 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 17 Jan 2023 16:57:07 -0500 Subject: [PATCH 50/52] follow suggestions --- precompiles/conviction-voting/src/lib.rs | 84 ++++++++++++++---------- precompiles/referenda/src/lib.rs | 4 +- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/precompiles/conviction-voting/src/lib.rs b/precompiles/conviction-voting/src/lib.rs index a8c3253e15..90bedd252c 100644 --- a/precompiles/conviction-voting/src/lib.rs +++ b/precompiles/conviction-voting/src/lib.rs @@ -53,6 +53,14 @@ type ClassOf = <::Polls as >, >>::Class; +/// Direction of vote +enum VoteDirection { + Yes, + No, + #[allow(unused)] + Abstain, +} + /// A precompile to wrap the functionality from pallet-conviction-voting. pub struct ConvictionVotingPrecompile(PhantomData); @@ -69,16 +77,11 @@ where IndexOf: TryFrom, ClassOf: TryFrom, { - /// Vote yes in a poll. - /// - /// Parameters: - /// * poll_index: Index of poll - /// * vote_amount: Balance locked for vote - /// * conviction: Conviction multiplier for length of vote lock - #[precompile::public("voteYes(uint32,uint256,uint8)")] - fn vote_yes( + /// Internal helper function for vote* extrinsics exposed in this precompile. + fn vote( handle: &mut impl PrecompileHandle, poll_index: u32, + vote: VoteDirection, vote_amount: U256, conviction: u8, ) -> EvmResult { @@ -86,17 +89,20 @@ where let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; + let aye = match vote { + VoteDirection::Yes => true, + VoteDirection::No => false, + _ => return Err(RevertReason::custom("Abstain not supported").into()), + }; + let vote = AccountVote::Standard { - vote: Vote { - aye: true, - conviction, - }, + vote: Vote { aye, conviction }, balance: vote_amount, }; log::trace!(target: "conviction-voting-precompile", "Voting {:?} on poll {:?}, with conviction {:?}", - true, poll_index, conviction + aye, poll_index, conviction ); let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -107,6 +113,28 @@ where Ok(()) } + /// Vote yes in a poll. + /// + /// Parameters: + /// * poll_index: Index of poll + /// * vote_amount: Balance locked for vote + /// * conviction: Conviction multiplier for length of vote lock + #[precompile::public("voteYes(uint32,uint256,uint8)")] + fn vote_yes( + handle: &mut impl PrecompileHandle, + poll_index: u32, + vote_amount: U256, + conviction: u8, + ) -> EvmResult { + Self::vote( + handle, + poll_index, + VoteDirection::Yes, + vote_amount, + conviction, + ) + } + /// Vote no in a poll. /// /// Parameters: @@ -120,29 +148,13 @@ where vote_amount: U256, conviction: u8, ) -> EvmResult { - let poll_index = Self::u32_to_index(poll_index).in_field("pollIndex")?; - let vote_amount = Self::u256_to_amount(vote_amount).in_field("voteAmount")?; - let conviction = Self::u8_to_conviction(conviction).in_field("conviction")?; - - let vote = AccountVote::Standard { - vote: Vote { - aye: false, - conviction, - }, - balance: vote_amount, - }; - - log::trace!(target: "conviction-voting-precompile", - "Voting {:?} on poll {:?}, with conviction {:?}", - false, poll_index, conviction - ); - - let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); - let call = ConvictionVotingCall::::vote { poll_index, vote }.into(); - - >::try_dispatch(handle, Some(origin).into(), call)?; - - Ok(()) + Self::vote( + handle, + poll_index, + VoteDirection::No, + vote_amount, + conviction, + ) } #[precompile::public("removeVote(uint32)")] diff --git a/precompiles/referenda/src/lib.rs b/precompiles/referenda/src/lib.rs index 5a3b03c10e..7c7abda8af 100644 --- a/precompiles/referenda/src/lib.rs +++ b/precompiles/referenda/src/lib.rs @@ -182,10 +182,10 @@ where proposal: BoundedBytes, block_number: u32, ) -> EvmResult { - let origin: GovOrigin = track_id.try_into().map_err(|_| { + let proposal_origin: GovOrigin = track_id.try_into().map_err(|_| { RevertReason::custom("Origin does not exist for TrackId").in_field("trackId") })?; - let proposal_origin: Box> = Box::new(origin.into()); + let proposal_origin: Box> = Box::new(proposal_origin.into()); let proposal: BoundedCallOf = Bounded::Inline( frame_support::BoundedVec::try_from(proposal.as_bytes().to_vec()).map_err(|_| { RevertReason::custom("Proposal input is not a runtime call").in_field("proposal") From dea9998eede9f50c9a1d902db024d855c3c4b990 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 17 Jan 2023 16:58:58 -0500 Subject: [PATCH 51/52] add doc note to removeOtherVote --- precompiles/conviction-voting/ConvictionVoting.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompiles/conviction-voting/ConvictionVoting.sol b/precompiles/conviction-voting/ConvictionVoting.sol index ed9df960d5..a35670b31d 100644 --- a/precompiles/conviction-voting/ConvictionVoting.sol +++ b/precompiles/conviction-voting/ConvictionVoting.sol @@ -62,7 +62,7 @@ interface ConvictionVoting { /// @dev Remove vote in poll for other voter /// @custom:selector cbcb9276 - //// @param target The voter to have vote removed + //// @param target The voter to have vote removed. The removed vote must already be expired. /// @param trackId The trackId /// @param pollIndex the poll index function removeOtherVote( From d4782eb98bb6db32993ccc489163a99e66f57300 Mon Sep 17 00:00:00 2001 From: 4meta5 Date: Tue, 17 Jan 2023 17:05:00 -0500 Subject: [PATCH 52/52] fix --- runtime/moonbase/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index b53370f958..fe84e64abc 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -809,7 +809,7 @@ fn is_governance_precompile(precompile_name: &precompiles::PrecompileName) -> bo | PrecompileName::TreasuryCouncilInstance | PrecompileName::ReferendaPrecompile | PrecompileName::ConvictionVotingPrecompile - | PrecompileName::PreimagePrecompile, + | PrecompileName::PreimagePrecompile | PrecompileName::OpenTechCommitteeInstance, ) }