-
Notifications
You must be signed in to change notification settings - Fork 382
Implement OpenGov Precompiles #1885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
50562c0
9395e66
8ed14e7
315116a
8f24362
d83be8e
21ffc60
0eb6dc3
09e90db
138a848
8e1a709
276d8a4
a940199
a9ab0e3
9067ba0
467e845
c6c8d1b
4d8f70a
a234655
def4e70
e86512c
66e5164
c389722
5bb1673
e7c765b
c5e2220
d05803f
b784aca
f1c55b5
58620ed
6ed417f
2fcef74
8723589
a1f469e
3e4e868
72f78a1
e1f84ca
6064e97
19c2914
046a7ac
7839709
3357394
5efa9d5
145f6f9
694378d
9bfd9ff
a11ee95
a1941ec
6e99180
83e5a1c
362fef7
af079a9
db81510
d3a8bda
4c3e81b
fd381a7
be79f7c
dea9998
052a56e
d4782eb
3cccdb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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")?; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does conviction represent in solidity? a multiplier? an enum? Perhaps it would be good if u use a u8 that represents an enum instead of asking for a u256? (similar yo what we use in substrate)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An enum, I believe the reason to use U256 is because either way it is U256 in the EVM because this is the smallest variable size. @nanocryk is it something like that
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I was making the suggestion is because there are other precompiles (like proxy) where the enum is defined in the solidity file, hence developers might have a better notion on what to put: https://github.com/PureStake/moonbeam/blob/6924ede17db074c4d5d530294bc0ff2eb484c674/precompiles/proxy/Proxy.sol#L17 |
||
|
|
||
| let vote = AccountVote::Standard { | ||
| vote: Vote { aye, conviction }, | ||
|
|
@@ -138,8 +134,7 @@ where | |
| class: SolidityConvert<U256, u16>, | ||
| poll_index: SolidityConvert<U256, u32>, | ||
| ) -> EvmResult { | ||
| let class: Option<ClassOf<Runtime>> = | ||
| 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<U256, u16>, | ||
| target: Address, | ||
| ) -> EvmResult { | ||
| let class: ClassOf<Runtime> = 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: <Runtime::Lookup as StaticLookup>::Source = | ||
|
|
@@ -259,6 +250,11 @@ where | |
|
|
||
| Ok(()) | ||
| } | ||
| fn u8_to_conviction(conviction: u8) -> MayRevert<Conviction> { | ||
| conviction | ||
| .try_into() | ||
| .map_err(|_| RevertReason::custom("Must be an integer between 0 and 6 included").into()) | ||
| } | ||
| fn u32_to_index(index: u32) -> MayRevert<IndexOf<Runtime>> { | ||
| index | ||
| .try_into() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,18 +19,28 @@ | |
|
|
||
| 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)] | ||
| // mod mock; | ||
| // #[cfg(test)] | ||
| // mod tests; | ||
|
|
||
| type BalanceOf<Runtime> = <<Runtime as pallet_referenda::Config>::Currency as Currency< | ||
| <Runtime as frame_system::Config>::AccountId, | ||
| >>::Balance; | ||
| type TrackIdOf<Runtime> = <<Runtime as pallet_referenda::Config>::Tracks as TracksInfo< | ||
| BalanceOf<Runtime>, | ||
| <Runtime as frame_system::Config>::BlockNumber, | ||
| >>::Id; | ||
|
|
||
| type OriginOf<Runtime> = <<Runtime as frame_system::Config>::Origin as OriginTrait>::PalletsOrigin; | ||
|
|
||
| /// A precompile to wrap the functionality from pallet-referenda. | ||
|
|
@@ -49,7 +59,83 @@ where | |
| <<Runtime as frame_system::Config>::Call as Dispatchable>::Origin: | ||
| From<Option<Runtime::AccountId>>, | ||
| <Runtime as frame_system::Config>::Call: From<ReferendaCall<Runtime>>, | ||
| TrackIdOf<Runtime>: TryFrom<u16>, | ||
| { | ||
| // The accessors are first. They directly return their result. | ||
| #[precompile::public("referendumCount()")] | ||
| #[precompile::view] | ||
| fn referendum_count(handle: &mut impl PrecompileHandle) -> EvmResult<U256> { | ||
| // Fetch data from pallet | ||
| handle.record_cost(RuntimeHelper::<Runtime>::db_read_gas_cost())?; | ||
| let ref_count = ReferendumCount::<Runtime>::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<U256, u16>, | ||
| ) -> EvmResult<U256> { | ||
| // Fetch data from pallet | ||
| handle.record_cost(RuntimeHelper::<Runtime>::db_read_gas_cost())?; | ||
| let track_id: TrackIdOf<Runtime> = track_id | ||
| .converted() | ||
| .try_into() | ||
| .map_err(|_| RevertReason::value_is_too_large("Track id type").into()) | ||
| .in_field("track")?; | ||
| let deciding_count = DecidingCount::<Runtime>::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<U256, u32>, | ||
| // ) -> EvmResult<U256> { | ||
| // // Fetch data from pallet | ||
| // handle.record_cost(RuntimeHelper::<Runtime>::db_read_gas_cost())?; | ||
| // let referendum_info = ReferendumInfoFor::<Runtime>::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<U256, u32>, | ||
| ) -> EvmResult<U256> { | ||
| // Fetch data from pallet | ||
| handle.record_cost(RuntimeHelper::<Runtime>::db_read_gas_cost())?; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Iterating over tracks has some cost. I'll make a follow up ticket. The accurate approach is to benchmark the iteration and charge that weight => gas instead of charging 1 db read. |
||
| let referendum_info = ReferendumInfoFor::<Runtime>::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: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.