Skip to content

Commit

Permalink
Merge branch 'brent/fix-slashing-client-query' (#1533)
Browse files Browse the repository at this point in the history
* brent/fix-slashing-client-query:
  [ci] wasm checksums update
  changelog: #1533
  pos/lib: fix slashing in `make_(un)bond_details`
  • Loading branch information
tzemanovic committed Jun 12, 2023
2 parents 3474742 + eb3a1b0 commit 3cacdd4
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- The slashed token amounts contained inside the bond and unbond information
returned by the PoS library fn bonds_and_unbonds are fixed and properly
computed. ([#1533](https://github.com/anoma/namada/pull/1533))
116 changes: 60 additions & 56 deletions proof_of_stake/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use storage::{
bonds_for_source_prefix, bonds_prefix, consensus_keys_key,
decimal_mult_amount, get_validator_address_from_bond, into_tm_voting_power,
is_bond_key, is_unbond_key, is_validator_slashes_key,
last_block_proposer_key, mult_change_to_amount, params_key, slashes_prefix,
last_block_proposer_key, params_key, slashes_prefix,
unbonds_for_source_prefix, unbonds_prefix, validator_address_raw_hash_key,
validator_last_slash_key, validator_max_commission_rate_change_key,
BondDetails, BondsAndUnbondsDetail, BondsAndUnbondsDetails,
Expand Down Expand Up @@ -2584,6 +2584,7 @@ where
let validator = bond_id.validator.clone();
let (bonds, _unbonds) = bonds_and_unbonds.entry(bond_id).or_default();
bonds.push(make_bond_details(
params,
&validator,
change,
start,
Expand Down Expand Up @@ -2647,6 +2648,7 @@ where
.filter(|(_start, change)| *change > token::Change::default())
.map(|(start, change)| {
make_bond_details(
params,
&validator,
change,
start,
Expand Down Expand Up @@ -2679,8 +2681,8 @@ where
Ok(HashMap::from_iter([(bond_id, details)]))
}

// TODO: check carefully for validity
fn make_bond_details(
params: &PosParams,
validator: &Address,
change: token::Change,
start: Epoch,
Expand All @@ -2693,36 +2695,37 @@ fn make_bond_details(
.cloned()
.unwrap_or_default();
let amount = token::Amount::from_change(change);
let slashed_amount =
slashes
.iter()
.fold(None, |acc: Option<token::Amount>, slash| {
if slash.epoch >= start {
let validator_slashes =
applied_slashes.entry(validator.clone()).or_default();
if !prev_applied_slashes
.iter()
.any(|s| s.clone() == slash.clone())
{
validator_slashes.push(slash.clone());
}
return Some(
acc.unwrap_or_default()
+ mult_change_to_amount(slash.rate, change),
);
}
acc
});
let slashed_amount =
slashed_amount.map(|slashed| cmp::min(amount, slashed));
let mut slash_rates_by_epoch = BTreeMap::<Epoch, Decimal>::new();

let validator_slashes =
applied_slashes.entry(validator.clone()).or_default();
for slash in slashes {
if slash.epoch >= start {
let cur_rate = slash_rates_by_epoch.entry(slash.epoch).or_default();
*cur_rate = cmp::min(Decimal::ONE, *cur_rate + slash.rate);

if !prev_applied_slashes.iter().any(|s| s == slash) {
validator_slashes.push(slash.clone());
}
}
}

let slashed_amount = if slash_rates_by_epoch.is_empty() {
None
} else {
let amount_after_slashing = token::Amount::from_change(
get_slashed_amount(params, amount, &slash_rates_by_epoch).unwrap(),
);
Some(amount - amount_after_slashing)
};

BondDetails {
start,
amount,
slashed_amount,
}
}

// TODO: check carefully for validity
fn make_unbond_details(
params: &PosParams,
validator: &Address,
Expand All @@ -2736,37 +2739,38 @@ fn make_unbond_details(
.get(validator)
.cloned()
.unwrap_or_default();
// TODO: checks bounds for considering valid unbond with slash!
let slashed_amount =
slashes
.iter()
.fold(None, |acc: Option<token::Amount>, slash| {
if slash.epoch >= start
&& slash.epoch
< withdraw
.checked_sub(Epoch(
params.unbonding_len
+ params.cubic_slashing_window_length,
))
.unwrap_or_default()
{
let validator_slashes =
applied_slashes.entry(validator.clone()).or_default();
if !prev_applied_slashes
.iter()
.any(|s| s.clone() == slash.clone())
{
validator_slashes.push(slash.clone());
}
return Some(
acc.unwrap_or_default()
+ decimal_mult_amount(slash.rate, amount),
);
}
acc
});
let slashed_amount =
slashed_amount.map(|slashed| cmp::min(amount, slashed));
let mut slash_rates_by_epoch = BTreeMap::<Epoch, Decimal>::new();

let validator_slashes =
applied_slashes.entry(validator.clone()).or_default();
for slash in slashes {
if slash.epoch >= start
&& slash.epoch
< withdraw
.checked_sub(Epoch(
params.unbonding_len
+ params.cubic_slashing_window_length,
))
.unwrap_or_default()
{
let cur_rate = slash_rates_by_epoch.entry(slash.epoch).or_default();
*cur_rate = cmp::min(Decimal::ONE, *cur_rate + slash.rate);

if !prev_applied_slashes.iter().any(|s| s == slash) {
validator_slashes.push(slash.clone());
}
}
}

let slashed_amount = if slash_rates_by_epoch.is_empty() {
None
} else {
let amount_after_slashing = token::Amount::from_change(
get_slashed_amount(params, amount, &slash_rates_by_epoch).unwrap(),
);
Some(amount - amount_after_slashing)
};

UnbondDetails {
start,
withdraw,
Expand Down
15 changes: 14 additions & 1 deletion proof_of_stake/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -988,10 +988,23 @@ fn test_slashes_with_unbonding_aux(
let token = staking_token_address(&s);
let val_balance_pre = read_balance(&s, &token, val_addr).unwrap();

let bond_id = BondId {
source: val_addr.clone(),
validator: val_addr.clone(),
};
let binding =
super::bonds_and_unbonds(&s, None, Some(val_addr.clone())).unwrap();
let details = binding.get(&bond_id).unwrap();
let exp_withdraw_from_details = details.unbonds[0].amount
- details.unbonds[0].slashed_amount.unwrap_or_default();

withdraw_tokens(&mut s, None, val_addr, current_epoch).unwrap();

let val_balance_post = read_balance(&s, &token, val_addr).unwrap();
let withdrawn_tokens = val_balance_post - val_balance_pre;
println!("Withdrew {withdrawn_tokens} tokens");

assert_eq!(exp_withdraw_from_details, withdrawn_tokens);

let slash_rate_0 = validator_slashes_handle(val_addr)
.get(&s, 0)
Expand All @@ -1003,7 +1016,7 @@ fn test_slashes_with_unbonding_aux(
.unwrap()
.unwrap()
.rate;
println!("Slash 0 rate {slash_rate_0}, slash 1 {slash_rate_1}");
println!("Slash 0 rate {slash_rate_0}, slash 1 rate {slash_rate_1}");

let expected_withdrawn_amount = decimal_mult_amount(
dec!(1) - slash_rate_1,
Expand Down
22 changes: 11 additions & 11 deletions wasm/checksums.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"tx_bond.wasm": "tx_bond.ebf9ce3a97a3576453a5022014caf995521de10f6b0f21c77aa997d295b51582.wasm",
"tx_change_validator_commission.wasm": "tx_change_validator_commission.2621d62e0b88638931dd7e8535225bda8e76cfed23bdb82ae5bac4ac28d68d6b.wasm",
"tx_ibc.wasm": "tx_ibc.6d26fe5abea04632386e446588667cad1666c38c8cdd5da104f4a8da2a285523.wasm",
"tx_init_account.wasm": "tx_init_account.422badd147072d19c37485bb9af7c59384146ee6178a42f57d90a108d777daa7.wasm",
"tx_init_proposal.wasm": "tx_init_proposal.f6d80d0b0528489cbdd4a5d585de28c4960ca3763fab44db3036e144c5f9743e.wasm",
"tx_init_validator.wasm": "tx_init_validator.7048a2978cc9d86b5208ded834332f21f5154e88b5785b7ad6222283ad3882b5.wasm",
"tx_reveal_pk.wasm": "tx_reveal_pk.de69f0787e0bf5947444259a75ebaa2ecbed37532b3cbd33a9ddfb27f43e6ea2.wasm",
"tx_transfer.wasm": "tx_transfer.53abc1752f23dda8c085d42e808d971515b90d3781617d45386538c8cc2ff8ba.wasm",
"tx_unbond.wasm": "tx_unbond.b467b2952ad2adf9c29fea70c8fb1131c860a8b17a08172828a3060633881d5c.wasm",
"tx_unjail_validator.wasm": "tx_unjail_validator.dc43d738b7ee148a1996dfba92408cca91c6e281d7989507101515eb03eaddfd.wasm",
"tx_bond.wasm": "tx_bond.e3a64e4026c81610b62d4b8fa5e8a5c24ac279d110eb402ccffce5d79db07b93.wasm",
"tx_change_validator_commission.wasm": "tx_change_validator_commission.c81cf8b64f13edce96fd6924c979c101c6199596101ce694f47b206b3673da06.wasm",
"tx_ibc.wasm": "tx_ibc.e8bee97364213334475df66e9a0e23dcf3154ea60294aac72642c3d74c942073.wasm",
"tx_init_account.wasm": "tx_init_account.c17afaeec08c6f90757980bd60fa0d77b4b36b9d0c68ecc71bda222b2f204a86.wasm",
"tx_init_proposal.wasm": "tx_init_proposal.4f10ec824404193f9fc37088aecc7f53564f535191fcd54ab6fbd0bf14a64b28.wasm",
"tx_init_validator.wasm": "tx_init_validator.55e3e1b8222d1b43a15a0ed1488fb2e9eacbaadf5513277a1d8003083b7c2af7.wasm",
"tx_reveal_pk.wasm": "tx_reveal_pk.f5ab2c096a8253c3db83c344724388811f925c884156e18a6c3a634d07ee7640.wasm",
"tx_transfer.wasm": "tx_transfer.1d98257dc00b851c616c1c9e8ab978a6eac0cedebdda22ae3270b47aaf5b164c.wasm",
"tx_unbond.wasm": "tx_unbond.64494eb5a012b5d9515329ff471efed49e6b0eefe6f281ef04a7dbbd344d6234.wasm",
"tx_unjail_validator.wasm": "tx_unjail_validator.624e2dd02883cc21f5738ec11542e1732eea4943ddf683b44d0644b3914c427d.wasm",
"tx_update_vp.wasm": "tx_update_vp.cefd67a267f34d8e93b207a39de9e920616f3d4e5e629086bbcb88b079ce6856.wasm",
"tx_vote_proposal.wasm": "tx_vote_proposal.71da34c54ece175129519120bd597b0226896827cfe0e1c76f435489cd899617.wasm",
"tx_withdraw.wasm": "tx_withdraw.0c8948a6bca1e233f0a89a31ab6caee645da59efd0092178759cf24e84dd5241.wasm",
"tx_withdraw.wasm": "tx_withdraw.37634f6111c4decc45901c20bd4640cceca68ddc51da70adb9bfdfb539c05259.wasm",
"vp_implicit.wasm": "vp_implicit.3acce29720aa7fedb75e7408c09b6bbd6e3a20e0afa7a0f20d58864d8fc3c111.wasm",
"vp_masp.wasm": "vp_masp.cd7fae1152e765ad4e3985fbdd0b8b2cb1cea13e2fff812291ebaf484f8676c9.wasm",
"vp_testnet_faucet.wasm": "vp_testnet_faucet.1dc87f66e7a378df435a20f97592e3a7746a3ccb322ca11889f11822d312ee22.wasm",
Expand Down

0 comments on commit 3cacdd4

Please sign in to comment.