Skip to content

Commit

Permalink
Rework voting across epochs on Ethereum tallies
Browse files Browse the repository at this point in the history
Instead of accounting for votes on Ethereum tallies based on the average
voting power available across all epochs the tally took place in, we
account for the maximum voting power found across all these epochs.
  • Loading branch information
sug0 committed Sep 7, 2023
1 parent 62184e7 commit d232bca
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 337 deletions.
10 changes: 5 additions & 5 deletions ethereum_bridge/src/protocol/transactions/bridge_pool_roots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use namada_core::ledger::storage::{DBIter, StorageHasher, WlStorage, DB};
use namada_core::ledger::storage_api::StorageWrite;
use namada_core::types::address::Address;
use namada_core::types::storage::BlockHeight;
use namada_core::types::token::Amount;
use namada_core::types::transaction::TxResult;
use namada_core::types::vote_extensions::bridge_pool_roots::MultiSignedVext;
use namada_core::types::voting_power::FractionalVotingPower;
use namada_proof_of_stake::pos_queries::PosQueries;

use crate::protocol::transactions::utils::GetVoters;
Expand Down Expand Up @@ -140,7 +140,7 @@ fn apply_update<D, H>(
wl_storage: &mut WlStorage<D, H>,
mut update: BridgePoolRoot,
seen_by: Votes,
voting_powers: &HashMap<(Address, BlockHeight), FractionalVotingPower>,
voting_powers: &HashMap<(Address, BlockHeight), Amount>,
) -> Result<(ChangedKeys, bool)>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
Expand Down Expand Up @@ -199,8 +199,8 @@ mod test_apply_bp_roots_to_storage {
use namada_core::types::ethereum_events::Uint;
use namada_core::types::keccak::{keccak_hash, KeccakHash};
use namada_core::types::storage::Key;
use namada_core::types::token::Amount;
use namada_core::types::vote_extensions::bridge_pool_roots;
use namada_core::types::voting_power::FractionalVotingPower;
use namada_proof_of_stake::parameters::PosParams;
use namada_proof_of_stake::write_pos_params;

Expand Down Expand Up @@ -431,7 +431,7 @@ mod test_apply_bp_roots_to_storage {
.read::<EpochedVotingPower>(&bp_root_key.voting_power())
.expect("Test failed")
.expect("Test failed")
.average_voting_power(&wl_storage);
.fractional_stake(&wl_storage);
assert_eq!(
voting_power,
FractionalVotingPower::new_u64(5, 12).unwrap()
Expand All @@ -450,7 +450,7 @@ mod test_apply_bp_roots_to_storage {
.read::<EpochedVotingPower>(&bp_root_key.voting_power())
.expect("Test failed")
.expect("Test failed")
.average_voting_power(&wl_storage);
.fractional_stake(&wl_storage);
assert_eq!(voting_power, FractionalVotingPower::new_u64(5, 6).unwrap());
}

Expand Down
28 changes: 12 additions & 16 deletions ethereum_bridge/src/protocol/transactions/ethereum_events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use namada_core::ledger::storage::{DBIter, WlStorage, DB};
use namada_core::types::address::Address;
use namada_core::types::ethereum_events::EthereumEvent;
use namada_core::types::storage::{BlockHeight, Epoch, Key};
use namada_core::types::token::Amount;
use namada_core::types::transaction::TxResult;
use namada_core::types::vote_extensions::ethereum_events::MultiSignedEthEvent;
use namada_core::types::voting_power::FractionalVotingPower;
use namada_proof_of_stake::pos_queries::PosQueries;

use super::ChangedKeys;
Expand Down Expand Up @@ -86,7 +86,7 @@ where
pub(super) fn apply_updates<D, H>(
wl_storage: &mut WlStorage<D, H>,
updates: HashSet<EthMsgUpdate>,
voting_powers: HashMap<(Address, BlockHeight), FractionalVotingPower>,
voting_powers: HashMap<(Address, BlockHeight), Amount>,
) -> Result<ChangedKeys>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
Expand Down Expand Up @@ -133,7 +133,7 @@ where
fn apply_update<D, H>(
wl_storage: &mut WlStorage<D, H>,
update: EthMsgUpdate,
voting_powers: &HashMap<(Address, BlockHeight), FractionalVotingPower>,
voting_powers: &HashMap<(Address, BlockHeight), Amount>,
) -> Result<(ChangedKeys, bool)>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
Expand Down Expand Up @@ -284,7 +284,8 @@ mod tests {
use namada_core::types::ethereum_events::{
EthereumEvent, TransferToNamada,
};
use namada_core::types::token::{balance_key, minted_balance_key, Amount};
use namada_core::types::token::{balance_key, minted_balance_key};
use namada_core::types::voting_power::FractionalVotingPower;

use super::*;
use crate::protocol::transactions::utils::GetVoters;
Expand All @@ -305,7 +306,7 @@ mod tests {
#[test]
/// Test applying a `TransfersToNamada` batch containing a single transfer
fn test_apply_single_transfer() -> Result<()> {
let sole_validator = address::testing::gen_established_address();
let (sole_validator, validator_stake) = test_utils::default_validator();
let receiver = address::testing::established_address_2();

let amount = arbitrary_amount();
Expand All @@ -326,10 +327,9 @@ mod tests {
let updates = HashSet::from_iter(vec![update]);
let voting_powers = HashMap::from_iter(vec![(
(sole_validator.clone(), BlockHeight(100)),
FractionalVotingPower::WHOLE,
validator_stake,
)]);
let mut wl_storage = TestWlStorage::default();
test_utils::bootstrap_ethereum_bridge(&mut wl_storage);
let (mut wl_storage, _) = test_utils::setup_default_storage();
test_utils::whitelist_tokens(
&mut wl_storage,
[(
Expand Down Expand Up @@ -377,7 +377,7 @@ mod tests {
let voting_power = wl_storage
.read::<EpochedVotingPower>(&eth_msg_keys.voting_power())?
.expect("Test failed")
.average_voting_power(&wl_storage);
.fractional_stake(&wl_storage);
assert_eq!(voting_power, FractionalVotingPower::WHOLE);

let epoch_bytes =
Expand Down Expand Up @@ -414,7 +414,6 @@ mod tests {
test_utils::setup_storage_with_validators(HashMap::from_iter(
vec![(sole_validator.clone(), Amount::native_whole(100))],
));
test_utils::bootstrap_ethereum_bridge(&mut wl_storage);
test_utils::whitelist_tokens(
&mut wl_storage,
[(
Expand Down Expand Up @@ -488,7 +487,6 @@ mod tests {
(validator_b, Amount::native_whole(100)),
]),
);
test_utils::bootstrap_ethereum_bridge(&mut wl_storage);
let receiver = address::testing::established_address_1();

let event = EthereumEvent::TransfersToNamada {
Expand Down Expand Up @@ -590,7 +588,7 @@ mod tests {
let voting_power = wl_storage
.read::<EpochedVotingPower>(&eth_msg_keys.voting_power())?
.expect("Test failed")
.average_voting_power(&wl_storage);
.fractional_stake(&wl_storage);
assert_eq!(voting_power, FractionalVotingPower::HALF);

Ok(())
Expand Down Expand Up @@ -664,7 +662,6 @@ mod tests {
(validator_b, Amount::native_whole(100)),
]),
);
test_utils::bootstrap_ethereum_bridge(&mut wl_storage);
let receiver = address::testing::established_address_1();

let event = EthereumEvent::TransfersToNamada {
Expand Down Expand Up @@ -793,7 +790,6 @@ mod tests {
(validator_b.clone(), Amount::native_whole(100)),
]),
);
test_utils::bootstrap_ethereum_bridge(&mut wl_storage);

let receiver = address::testing::established_address_1();
let event = EthereumEvent::TransfersToNamada {
Expand Down Expand Up @@ -821,7 +817,7 @@ mod tests {
(KeyKind::VotingPower, Some(power)) => {
let power = EpochedVotingPower::try_from_slice(&power)
.expect("Test failed")
.average_voting_power(&wl_storage);
.fractional_stake(&wl_storage);
assert_eq!(power, FractionalVotingPower::HALF);
}
(_, Some(_)) => {}
Expand Down Expand Up @@ -851,7 +847,7 @@ mod tests {
(KeyKind::VotingPower, Some(power)) => {
let power = EpochedVotingPower::try_from_slice(&power)
.expect("Test failed")
.average_voting_power(&wl_storage);
.fractional_stake(&wl_storage);
assert_eq!(power, FractionalVotingPower::HALF);
}
(_, Some(_)) => {}
Expand Down
98 changes: 14 additions & 84 deletions ethereum_bridge/src/protocol/transactions/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use namada_core::ledger::storage::{DBIter, StorageHasher, WlStorage, DB};
use namada_core::types::address::Address;
use namada_core::types::storage::BlockHeight;
use namada_core::types::token;
use namada_core::types::voting_power::FractionalVotingPower;
use namada_proof_of_stake::pos_queries::PosQueries;
use namada_proof_of_stake::types::WeightedValidator;

Expand All @@ -25,7 +24,7 @@ pub(super) trait GetVoters {
pub(super) fn get_voting_powers<D, H, P>(
wl_storage: &WlStorage<D, H>,
proof: P,
) -> eyre::Result<HashMap<(Address, BlockHeight), FractionalVotingPower>>
) -> eyre::Result<HashMap<(Address, BlockHeight), token::Amount>>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
Expand Down Expand Up @@ -85,23 +84,21 @@ where
pub(super) fn get_voting_powers_for_selected(
all_consensus: &BTreeMap<BlockHeight, BTreeSet<WeightedValidator>>,
selected: HashSet<(Address, BlockHeight)>,
) -> eyre::Result<HashMap<(Address, BlockHeight), FractionalVotingPower>> {
let total_voting_powers =
sum_voting_powers_for_block_heights(all_consensus);
) -> eyre::Result<HashMap<(Address, BlockHeight), token::Amount>> {
let voting_powers = selected
.into_iter()
.map(
|(addr, height)| -> eyre::Result<(
(Address, BlockHeight),
FractionalVotingPower,
token::Amount,
)> {
let consensus_validators =
all_consensus.get(&height).ok_or_else(|| {
eyre!(
"No consensus validators found for height {height}"
)
})?;
let individual_voting_power = consensus_validators
let voting_power = consensus_validators
.iter()
.find(|&v| v.address == addr)
.ok_or_else(|| {
Expand All @@ -111,53 +108,24 @@ pub(super) fn get_voting_powers_for_selected(
)
})?
.bonded_stake;
let total_voting_power = total_voting_powers
.get(&height)
.ok_or_else(|| {
eyre!(
"No total voting power provided for height \
{height}"
)
})?
.to_owned();
Ok((
(addr, height),
FractionalVotingPower::new(
individual_voting_power.into(),
total_voting_power.into(),
)?,
voting_power,
))
},
)
.try_collect()?;
Ok(voting_powers)
}

pub(super) fn sum_voting_powers_for_block_heights(
validators: &BTreeMap<BlockHeight, BTreeSet<WeightedValidator>>,
) -> BTreeMap<BlockHeight, token::Amount> {
validators
.iter()
.map(|(h, vs)| (h.to_owned(), sum_voting_powers(vs)))
.collect()
}

pub(super) fn sum_voting_powers(
validators: &BTreeSet<WeightedValidator>,
) -> token::Amount {
validators
.iter()
.map(|validator| validator.bonded_stake)
.sum::<token::Amount>()
}

#[cfg(test)]
mod tests {
use std::collections::HashSet;

use assert_matches::assert_matches;
use namada_core::types::address;
use namada_core::types::ethereum_events::testing::arbitrary_bonded_stake;
use namada_core::types::voting_power::FractionalVotingPower;

use super::*;

Expand Down Expand Up @@ -190,7 +158,7 @@ mod tests {
assert_eq!(voting_powers.len(), 1);
assert_matches!(
voting_powers.get(&(sole_validator, BlockHeight(100))),
Some(v) if *v == FractionalVotingPower::WHOLE
Some(v) if *v == bonded_stake
);
}

Expand Down Expand Up @@ -263,6 +231,7 @@ mod tests {
weighted_validator_2,
]),
)]);
let bonded_stake = bonded_stake_1 + bonded_stake_2;

let result =
get_voting_powers_for_selected(&consensus_validators, validators);
Expand All @@ -272,56 +241,17 @@ mod tests {
Err(error) => panic!("error: {:?}", error),
};
assert_eq!(voting_powers.len(), 2);
let expected_stake =
FractionalVotingPower::new_u64(100, 300).unwrap() * bonded_stake;
assert_matches!(
voting_powers.get(&(validator_1, BlockHeight(100))),
Some(v) if *v == FractionalVotingPower::new_u64(100, 300).unwrap()
Some(v) if *v == expected_stake
);
let expected_stake =
FractionalVotingPower::new_u64(200, 300).unwrap() * bonded_stake;
assert_matches!(
voting_powers.get(&(validator_2, BlockHeight(100))),
Some(v) if *v == FractionalVotingPower::new_u64(200, 300).unwrap()
Some(v) if *v == expected_stake
);
}

#[test]
/// Test summing the voting powers for a set of validators containing only
/// one validator
fn test_sum_voting_powers_sole_validator() {
let sole_validator = address::testing::established_address_1();
let bonded_stake = arbitrary_bonded_stake();
let weighted_sole_validator = WeightedValidator {
bonded_stake,
address: sole_validator,
};
let validators = BTreeSet::from_iter(vec![weighted_sole_validator]);

let total = sum_voting_powers(&validators);

assert_eq!(total, bonded_stake);
}

#[test]
/// Test summing the voting powers for a set of validators containing two
/// validators
fn test_sum_voting_powers_two_validators() {
let validator_1 = address::testing::established_address_1();
let validator_2 = address::testing::established_address_2();
let bonded_stake_1 = token::Amount::from(100);
let bonded_stake_2 = token::Amount::from(200);
let weighted_validator_1 = WeightedValidator {
bonded_stake: bonded_stake_1,
address: validator_1,
};
let weighted_validator_2 = WeightedValidator {
bonded_stake: bonded_stake_2,
address: validator_2,
};
let validators = BTreeSet::from_iter(vec![
weighted_validator_1,
weighted_validator_2,
]);

let total = sum_voting_powers(&validators);

assert_eq!(total, token::Amount::from(300));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use eyre::Result;
use namada_core::ledger::storage::{DBIter, StorageHasher, WlStorage, DB};
use namada_core::types::address::Address;
use namada_core::types::storage::{BlockHeight, Epoch};
use namada_core::types::token::Amount;
#[allow(unused_imports)]
use namada_core::types::transaction::protocol::ProtocolTxType;
use namada_core::types::transaction::TxResult;
use namada_core::types::vote_extensions::validator_set_update;
use namada_core::types::voting_power::FractionalVotingPower;

use super::ChangedKeys;
use crate::protocol::transactions::utils;
Expand Down Expand Up @@ -85,7 +85,7 @@ fn apply_update<D, H>(
ext: validator_set_update::VextDigest,
signing_epoch: Epoch,
epoch_2nd_height: BlockHeight,
voting_powers: HashMap<(Address, BlockHeight), FractionalVotingPower>,
voting_powers: HashMap<(Address, BlockHeight), Amount>,
) -> Result<ChangedKeys>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
Expand Down Expand Up @@ -199,7 +199,6 @@ where
#[cfg(test)]
mod test_valset_upd_state_changes {
use namada_core::types::address;
use namada_core::types::token::Amount;
use namada_core::types::vote_extensions::validator_set_update::VotingPowersMap;
use namada_core::types::voting_power::FractionalVotingPower;
use namada_proof_of_stake::pos_queries::PosQueries;
Expand Down
Loading

0 comments on commit d232bca

Please sign in to comment.