Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub const EVENT_STANDARD_VERSION: &str = "1.0.0";
pub enum Event<'a> {
Voted {
validator_id: &'a AccountId,
choice: &'a Choice,
vote: &'a Vote,
},
ProposalApproved {
proposal: &'a String,
Expand Down
60 changes: 30 additions & 30 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Timestamp = u64;

#[near(serializers = [json])]
#[serde(rename_all = "lowercase")]
pub enum Choice {
pub enum Vote {
Yes,
No,
}
Expand Down Expand Up @@ -86,16 +86,16 @@ impl Contract {
}
}

/// Method for validators to vote with choice `Yes` or `No`.
/// Method for validators to vote with `Yes` or `No`.
/// The method is called by validator owners.
pub fn vote(&mut self, choice: Choice, staking_pool_id: AccountId) -> Promise {
pub fn vote(&mut self, vote: Vote, staking_pool_id: AccountId) -> Promise {
ext_staking_pool::ext(staking_pool_id.clone())
.with_static_gas(GET_OWNER_ID_GAS)
.get_owner_id()
.then(Self::ext(env::current_account_id()).on_get_pool_owner_id(
env::predecessor_account_id(),
staking_pool_id,
choice,
vote,
))
}

Expand All @@ -105,30 +105,30 @@ impl Contract {
&mut self,
pool_owner_id: AccountId,
staking_pool_id: AccountId,
choice: Choice,
vote: Vote,
#[callback_result] pool_owner_id_result: Result<AccountId, PromiseError>,
) {
if let Ok(actual_owner_id) = pool_owner_id_result {
require!(
pool_owner_id == actual_owner_id,
"Voting is only allowed for the staking pool owner"
);
self.internal_vote(choice, staking_pool_id);
self.internal_vote(vote, staking_pool_id);
} else {
env::panic_str("Failed to get the staking pool owner id");
}
}

/// Internal method for voting.
fn internal_vote(&mut self, choice: Choice, account_id: AccountId) {
fn internal_vote(&mut self, vote: Vote, account_id: AccountId) {
self.ping();

let stake = validator_stake(&account_id);
require!(stake > 0, format!("{} is not a validator", account_id));

let account_stake = match choice {
Choice::Yes => stake,
Choice::No => 0,
let account_stake = match vote {
Vote::Yes => stake,
Vote::No => 0,
};

let voted_stake = self.votes.remove(&account_id).unwrap_or_default();
Expand All @@ -147,7 +147,7 @@ impl Contract {
// emit event
Event::Voted {
validator_id: &account_id,
choice: &choice,
vote: &vote,
}
.emit();
}
Expand Down Expand Up @@ -302,20 +302,20 @@ mod tests {

fn vote_with_account(
contract: &mut Contract,
choice: Choice,
vote: Vote,
staking_pool_id: &AccountId,
account: &AccountId,
) {
contract.on_get_pool_owner_id(
account.clone(),
staking_pool_id.clone(),
choice,
vote,
Ok(pool_owner()),
);
}

fn vote(contract: &mut Contract, choice: Choice, staking_pool_id: &AccountId) {
vote_with_account(contract, choice, staking_pool_id, &pool_owner());
fn vote(contract: &mut Contract, vote: Vote, staking_pool_id: &AccountId) {
vote_with_account(contract, vote, staking_pool_id, &pool_owner());
}

#[test]
Expand All @@ -328,7 +328,7 @@ mod tests {
]);
set_context_and_validators(&context, &validators);
let mut contract = get_contract();
vote(&mut contract, Choice::Yes, &validator(3));
vote(&mut contract, Vote::Yes, &validator(3));
}

#[test]
Expand All @@ -341,7 +341,7 @@ mod tests {
]);
set_context_and_validators(&context, &validators);
let mut contract = get_contract();
vote(&mut contract, Choice::No, &validator(3));
vote(&mut contract, Vote::No, &validator(3));
}

#[test]
Expand All @@ -356,10 +356,10 @@ mod tests {
set_context_and_validators(&context, &validators);
let mut contract = get_contract();
// vote
vote(&mut contract, Choice::Yes, &validator_id);
vote(&mut contract, Vote::Yes, &validator_id);
assert!(contract.get_result().is_some());
// vote again. should panic because voting has ended
vote(&mut contract, Choice::Yes, &validator_id);
vote(&mut contract, Vote::Yes, &validator_id);
}

#[test]
Expand All @@ -375,7 +375,7 @@ mod tests {
let mut contract = get_contract();
// vote with an account that is not the pool owner.
// should panic because only the pool owner can vote.
vote_with_account(&mut contract, Choice::Yes, &validator_id, &accounts(0));
vote_with_account(&mut contract, Vote::Yes, &validator_id, &accounts(0));
}

#[test]
Expand All @@ -387,7 +387,7 @@ mod tests {
for i in 0..201 {
// vote by each validator
let voter = validator(i);
vote(&mut contract, Choice::Yes, &voter);
vote(&mut contract, Vote::Yes, &voter);

// check total voted stake
context.is_view(true);
Expand Down Expand Up @@ -420,7 +420,7 @@ mod tests {
// vote by each validator
let context = get_context_with_epoch_height(&voting_contract_id(), i);
set_context(&context);
vote(&mut contract, Choice::Yes, &validator(i));
vote(&mut contract, Vote::Yes, &validator(i));
// check votes
assert_eq!(contract.get_votes().len() as u64, i + 1);
// check voting result
Expand All @@ -443,7 +443,7 @@ mod tests {
let context = get_context_with_epoch_height(&voting_contract_id(), 1);
set_context_and_validators(&context, &validators);
let mut contract = get_contract();
vote(&mut contract, Choice::Yes, &validator(1));
vote(&mut contract, Vote::Yes, &validator(1));
// ping at epoch 2
validators.insert(validator(1).to_string(), NearToken::from_yoctonear(50));
let context = get_context_with_epoch_height(&voting_contract_id(), 2);
Expand All @@ -453,7 +453,7 @@ mod tests {
}

#[test]
fn test_change_vote_choice() {
fn test_change_vote() {
let validators: HashMap<String, NearToken> = HashMap::from_iter(vec![
(validator(1).to_string(), NearToken::from_yoctonear(10)),
(validator(2).to_string(), NearToken::from_yoctonear(10)),
Expand All @@ -462,17 +462,17 @@ mod tests {
set_context_and_validators(&context, &validators);
let mut contract = get_contract();
// vote YES at epoch 1
vote(&mut contract, Choice::Yes, &validator(1));
vote(&mut contract, Vote::Yes, &validator(1));
assert_eq!(contract.get_votes().len(), 1);
// vote NO at epoch 2
let context = get_context_with_epoch_height(&voting_contract_id(), 2);
set_context_and_validators(&context, &validators);
vote(&mut contract, Choice::No, &validator(1));
vote(&mut contract, Vote::No, &validator(1));
assert!(contract.get_votes().is_empty());
// vote YES at epoch 3
let context = get_context_with_epoch_height(&voting_contract_id(), 3);
set_context_and_validators(&context, &validators);
vote(&mut contract, Choice::Yes, &validator(1));
vote(&mut contract, Vote::Yes, &validator(1));
assert_eq!(contract.get_votes().len(), 1);
}

Expand All @@ -487,7 +487,7 @@ mod tests {
set_context_and_validators(&context, &validators);
let mut contract = get_contract();
// vote at epoch 1
vote(&mut contract, Choice::Yes, &validator(1));
vote(&mut contract, Vote::Yes, &validator(1));
assert_eq!((contract.get_total_voted_stake().0).0, 40);
assert_eq!(contract.get_votes().len(), 1);
// remove validator at epoch 2
Expand Down Expand Up @@ -534,7 +534,7 @@ mod tests {

// vote after deadline
set_context(context.block_timestamp(env::block_timestamp_ms() + 2000 * 1_000_000));
vote(&mut contract, Choice::Yes, &validator(0));
vote(&mut contract, Vote::Yes, &validator(0));
}

#[test]
Expand All @@ -545,7 +545,7 @@ mod tests {

// vote at epoch 1
set_context(&context);
vote(&mut contract, Choice::Yes, &validator(0));
vote(&mut contract, Vote::Yes, &validator(0));

// ping at epoch 2 after deadline
set_context(
Expand Down
26 changes: 13 additions & 13 deletions tests/test_vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async fn test_non_validator_cannot_vote() -> Result<(), Box<dyn std::error::Erro
let user_account = sandbox.dev_create_account().await?;
let outcome = user_account
.call(contract.id(), "vote")
.args_json(json!({"choice": "yes", "staking_pool_id": user_account.id()}))
.args_json(json!({"vote": "yes", "staking_pool_id": user_account.id()}))
.transact()
.await?;
assert!(
Expand All @@ -34,7 +34,7 @@ async fn test_non_validator_cannot_vote() -> Result<(), Box<dyn std::error::Erro
let user_account = sandbox.dev_create_account().await?;
let outcome = user_account
.call(contract.id(), "vote")
.args_json(json!({"choice": "no", "staking_pool_id": user_account.id()}))
.args_json(json!({"vote": "no", "staking_pool_id": user_account.id()}))
.transact()
.await?;
assert!(
Expand Down Expand Up @@ -66,7 +66,7 @@ async fn test_only_pool_owner_can_vote() -> Result<(), Box<dyn std::error::Error

let outcome = alice
.call(voting_contract.id(), "vote")
.args_json(json!({"choice": "yes", "staking_pool_id": staking_pool_contract.id()}))
.args_json(json!({"vote": "yes", "staking_pool_id": staking_pool_contract.id()}))
.transact()
.await?;
assert!(
Expand All @@ -77,7 +77,7 @@ async fn test_only_pool_owner_can_vote() -> Result<(), Box<dyn std::error::Error

let outcome = alice
.call(voting_contract.id(), "vote")
.args_json(json!({"choice": "no", "staking_pool_id": staking_pool_contract.id()}))
.args_json(json!({"vote": "no", "staking_pool_id": staking_pool_contract.id()}))
.transact()
.await?;
assert!(
Expand Down Expand Up @@ -117,7 +117,7 @@ async fn test_simple_vote() -> Result<(), Box<dyn std::error::Error>> {
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contract.id()
}))
.gas(Gas::from_tgas(200))
Expand Down Expand Up @@ -188,7 +188,7 @@ async fn test_many_votes() -> Result<(), Box<dyn std::error::Error>> {
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contract.id()
}))
.gas(Gas::from_tgas(200))
Expand Down Expand Up @@ -250,7 +250,7 @@ async fn test_vote_expiration() -> Result<(), Box<dyn std::error::Error>> {
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contract.id()
}))
.gas(Gas::from_tgas(200))
Expand Down Expand Up @@ -299,7 +299,7 @@ async fn test_vote_no_after_vote_yes() -> Result<(), Box<dyn std::error::Error>>
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contracts[0].id()
}))
.gas(Gas::from_tgas(200))
Expand All @@ -318,7 +318,7 @@ async fn test_vote_no_after_vote_yes() -> Result<(), Box<dyn std::error::Error>>
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "no",
"vote": "no",
"staking_pool_id": staking_pool_contracts[0].id()
}))
.gas(Gas::from_tgas(200))
Expand Down Expand Up @@ -370,7 +370,7 @@ async fn test_vote_yes_after_vote_no() -> Result<(), Box<dyn std::error::Error>>
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "no",
"vote": "no",
"staking_pool_id": staking_pool_contracts[0].id()
}))
.gas(Gas::from_tgas(200))
Expand All @@ -389,7 +389,7 @@ async fn test_vote_yes_after_vote_no() -> Result<(), Box<dyn std::error::Error>>
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contracts[0].id()
}))
.gas(Gas::from_tgas(200))
Expand Down Expand Up @@ -441,7 +441,7 @@ async fn test_unstake_after_voting() -> Result<(), Box<dyn std::error::Error>> {
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contracts[0].id()
}))
.gas(Gas::from_tgas(200))
Expand Down Expand Up @@ -478,7 +478,7 @@ async fn test_unstake_after_voting() -> Result<(), Box<dyn std::error::Error>> {
let outcome = owner
.call(voting_contract.id(), "vote")
.args_json(json!({
"choice": "yes",
"vote": "yes",
"staking_pool_id": staking_pool_contracts[1].id()
}))
.gas(Gas::from_tgas(200))
Expand Down