Skip to content
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

Add method removeVoteForTrack to ConvictionVoting precompile #2201

Merged
merged 6 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions precompiles/conviction-voting/ConvictionVoting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ interface ConvictionVoting {
/// @param pollIndex Index of the poll
function removeVote(uint32 pollIndex) external;

/// @dev Remove vote in poll with track
/// @custom:selector dd0988a6
/// @param pollIndex Index of the poll
/// @param trackId Id of the track
function removeSomeVote(uint32 pollIndex, uint16 trackId) external;
4meta5 marked this conversation as resolved.
Show resolved Hide resolved

/// @dev Remove vote in poll for other voter
/// @custom:selector cbcb9276
//// @param target The voter to have vote removed. The removed vote must already be expired.
Expand Down Expand Up @@ -164,6 +170,17 @@ interface ConvictionVoting {
/// @param voter address Address of the voter.
event VoteRemoved(uint32 indexed pollIndex, address voter);

/// @dev An account removed its vote from an ongoing poll.
/// @custom:selector 49fc1dd929f126e1d88cbb9c135625e30c2deba291adeea4740e446098b9957b
/// @param pollIndex uint32 Index of the poll.
/// @param trackId uint32 TrackId of the poll.
/// @param voter address Address of the voter.
event SomeVoteRemoved(
uint32 indexed pollIndex,
uint16 trackId,
address voter
);

/// @dev An account removed a vote from a poll.
/// @custom:selector c1d068675720ab00d0c8792a0cbc7e198c0d2202111f0280f039f2c09c50491b
/// @param pollIndex uint32 Index of the poll.
Expand Down
77 changes: 60 additions & 17 deletions precompiles/conviction-voting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ pub(crate) const SELECTOR_LOG_VOTE_SPLIT_ABSTAINED: [u8; 32] =
/// Solidity selector of the VoteRemove log, which is the Keccak of the Log signature.
pub(crate) const SELECTOR_LOG_VOTE_REMOVED: [u8; 32] = keccak256!("VoteRemoved(uint32,address)");

/// Solidity selector of the SomeVoteRemove log, which is the Keccak of the Log signature.
pub(crate) const SELECTOR_LOG_SOME_VOTE_REMOVED: [u8; 32] =
keccak256!("SomeVoteRemoved(uint32,uint16,address)");

/// Solidity selector of the VoteRemoveOther log, which is the Keccak of the Log signature.
pub(crate) const SELECTOR_LOG_VOTE_REMOVED_OTHER: [u8; 32] =
keccak256!("VoteRemovedOther(uint32,address,address,uint16)");
Expand Down Expand Up @@ -208,27 +212,66 @@ where

#[precompile::public("removeVote(uint32)")]
fn remove_vote(handle: &mut impl PrecompileHandle, poll_index: u32) -> EvmResult {
let caller = handle.context().caller;
let event = log2(
handle.context().address,
SELECTOR_LOG_VOTE_REMOVED,
H256::from_low_u64_be(poll_index as u64), // poll index,
EvmDataWriter::new()
.write::<Address>(Address(caller))
.build(),
);
handle.record_log_costs(&[&event])?;
Self::rm_vote(handle, poll_index, None)
}

let index = Self::u32_to_index(poll_index).in_field("pollIndex")?;
#[precompile::public("removeSomeVote(uint32,uint16)")]
fn remove_some_vote(
handle: &mut impl PrecompileHandle,
poll_index: u32,
track_id: u16,
) -> EvmResult {
Self::rm_vote(handle, poll_index, Some(track_id))
}

log::trace!(
target: "conviction-voting-precompile",
"Removing vote from poll {:?}",
index
);
/// Helper function for common code between remove_vote and remove_some_vote
fn rm_vote(
handle: &mut impl PrecompileHandle,
poll_index: u32,
maybe_track_id: Option<u16>,
) -> EvmResult {
let caller = handle.context().caller;
let index = Self::u32_to_index(poll_index).in_field("pollIndex")?;
let (event, class) = if let Some(track_id) = maybe_track_id {
log::trace!(
target: "conviction-voting-precompile",
"Removing vote from poll {:?}, track {:?}",
index,
track_id,
);
(
log2(
handle.context().address,
SELECTOR_LOG_SOME_VOTE_REMOVED,
H256::from_low_u64_be(poll_index as u64),
EvmDataWriter::new()
.write::<Address>(Address(caller))
.write::<u16>(track_id)
.build(),
),
Some(Self::u16_to_track_id(track_id).in_field("trackId")?),
)
} else {
log::trace!(
target: "conviction-voting-precompile",
"Removing vote from poll {:?}",
index,
);
(
log2(
handle.context().address,
SELECTOR_LOG_VOTE_REMOVED,
H256::from_low_u64_be(poll_index as u64),
EvmDataWriter::new()
.write::<Address>(Address(caller))
.build(),
),
None,
)
};

let origin = Runtime::AddressMapping::into_account_id(caller);
let call = ConvictionVotingCall::<Runtime>::remove_vote { class: None, index };
let call = ConvictionVotingCall::<Runtime>::remove_vote { class, index };

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;

Expand Down
41 changes: 38 additions & 3 deletions precompiles/conviction-voting/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.
use crate::{
mock::*, SELECTOR_LOG_DELEGATED, SELECTOR_LOG_UNDELEGATED, SELECTOR_LOG_UNLOCKED,
SELECTOR_LOG_VOTED, SELECTOR_LOG_VOTE_REMOVED, SELECTOR_LOG_VOTE_REMOVED_OTHER,
SELECTOR_LOG_VOTE_SPLIT, SELECTOR_LOG_VOTE_SPLIT_ABSTAINED,
mock::*, SELECTOR_LOG_DELEGATED, SELECTOR_LOG_SOME_VOTE_REMOVED, SELECTOR_LOG_UNDELEGATED,
SELECTOR_LOG_UNLOCKED, SELECTOR_LOG_VOTED, SELECTOR_LOG_VOTE_REMOVED,
SELECTOR_LOG_VOTE_REMOVED_OTHER, SELECTOR_LOG_VOTE_SPLIT, SELECTOR_LOG_VOTE_SPLIT_ABSTAINED,
};
use precompile_utils::{prelude::*, testing::*, EvmDataWriter};

Expand Down Expand Up @@ -260,6 +260,41 @@ fn remove_vote_logs_work() {
})
}

#[test]
fn remove_some_vote_logs_work() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 100_000)])
.build()
.execute_with(|| {
// Vote..
assert_ok!(standard_vote(true, 100_000.into(), 0.into()));

// ..and remove
let input = PCall::remove_some_vote {
poll_index: ONGOING_POLL_INDEX,
track_id: 0u16,
}
.into();
assert_ok!(RuntimeCall::Evm(evm_call(input)).dispatch(RuntimeOrigin::root()));

// Assert remove vote event is emitted.
assert!(events().contains(
&EvmEvent::Log {
log: log2(
Precompile1,
SELECTOR_LOG_SOME_VOTE_REMOVED,
H256::from_low_u64_be(ONGOING_POLL_INDEX as u64),
EvmDataWriter::new()
.write::<Address>(H160::from(Alice).into()) // caller
.write::<u16>(0u16)
.build(),
),
}
.into()
));
})
}

#[test]
fn remove_other_vote_logs_work() {
ExtBuilder::default()
Expand Down