Skip to content

Commit 3cacdd4

Browse files
committed
Merge branch 'brent/fix-slashing-client-query' (#1533)
* brent/fix-slashing-client-query: [ci] wasm checksums update changelog: #1533 pos/lib: fix slashing in `make_(un)bond_details`
2 parents 3474742 + eb3a1b0 commit 3cacdd4

4 files changed

Lines changed: 88 additions & 68 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- The slashed token amounts contained inside the bond and unbond information
2+
returned by the PoS library fn bonds_and_unbonds are fixed and properly
3+
computed. ([#1533](https://github.com/anoma/namada/pull/1533))

proof_of_stake/src/lib.rs

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use storage::{
5353
bonds_for_source_prefix, bonds_prefix, consensus_keys_key,
5454
decimal_mult_amount, get_validator_address_from_bond, into_tm_voting_power,
5555
is_bond_key, is_unbond_key, is_validator_slashes_key,
56-
last_block_proposer_key, mult_change_to_amount, params_key, slashes_prefix,
56+
last_block_proposer_key, params_key, slashes_prefix,
5757
unbonds_for_source_prefix, unbonds_prefix, validator_address_raw_hash_key,
5858
validator_last_slash_key, validator_max_commission_rate_change_key,
5959
BondDetails, BondsAndUnbondsDetail, BondsAndUnbondsDetails,
@@ -2584,6 +2584,7 @@ where
25842584
let validator = bond_id.validator.clone();
25852585
let (bonds, _unbonds) = bonds_and_unbonds.entry(bond_id).or_default();
25862586
bonds.push(make_bond_details(
2587+
params,
25872588
&validator,
25882589
change,
25892590
start,
@@ -2647,6 +2648,7 @@ where
26472648
.filter(|(_start, change)| *change > token::Change::default())
26482649
.map(|(start, change)| {
26492650
make_bond_details(
2651+
params,
26502652
&validator,
26512653
change,
26522654
start,
@@ -2679,8 +2681,8 @@ where
26792681
Ok(HashMap::from_iter([(bond_id, details)]))
26802682
}
26812683

2682-
// TODO: check carefully for validity
26832684
fn make_bond_details(
2685+
params: &PosParams,
26842686
validator: &Address,
26852687
change: token::Change,
26862688
start: Epoch,
@@ -2693,36 +2695,37 @@ fn make_bond_details(
26932695
.cloned()
26942696
.unwrap_or_default();
26952697
let amount = token::Amount::from_change(change);
2696-
let slashed_amount =
2697-
slashes
2698-
.iter()
2699-
.fold(None, |acc: Option<token::Amount>, slash| {
2700-
if slash.epoch >= start {
2701-
let validator_slashes =
2702-
applied_slashes.entry(validator.clone()).or_default();
2703-
if !prev_applied_slashes
2704-
.iter()
2705-
.any(|s| s.clone() == slash.clone())
2706-
{
2707-
validator_slashes.push(slash.clone());
2708-
}
2709-
return Some(
2710-
acc.unwrap_or_default()
2711-
+ mult_change_to_amount(slash.rate, change),
2712-
);
2713-
}
2714-
acc
2715-
});
2716-
let slashed_amount =
2717-
slashed_amount.map(|slashed| cmp::min(amount, slashed));
2698+
let mut slash_rates_by_epoch = BTreeMap::<Epoch, Decimal>::new();
2699+
2700+
let validator_slashes =
2701+
applied_slashes.entry(validator.clone()).or_default();
2702+
for slash in slashes {
2703+
if slash.epoch >= start {
2704+
let cur_rate = slash_rates_by_epoch.entry(slash.epoch).or_default();
2705+
*cur_rate = cmp::min(Decimal::ONE, *cur_rate + slash.rate);
2706+
2707+
if !prev_applied_slashes.iter().any(|s| s == slash) {
2708+
validator_slashes.push(slash.clone());
2709+
}
2710+
}
2711+
}
2712+
2713+
let slashed_amount = if slash_rates_by_epoch.is_empty() {
2714+
None
2715+
} else {
2716+
let amount_after_slashing = token::Amount::from_change(
2717+
get_slashed_amount(params, amount, &slash_rates_by_epoch).unwrap(),
2718+
);
2719+
Some(amount - amount_after_slashing)
2720+
};
2721+
27182722
BondDetails {
27192723
start,
27202724
amount,
27212725
slashed_amount,
27222726
}
27232727
}
27242728

2725-
// TODO: check carefully for validity
27262729
fn make_unbond_details(
27272730
params: &PosParams,
27282731
validator: &Address,
@@ -2736,37 +2739,38 @@ fn make_unbond_details(
27362739
.get(validator)
27372740
.cloned()
27382741
.unwrap_or_default();
2739-
// TODO: checks bounds for considering valid unbond with slash!
2740-
let slashed_amount =
2741-
slashes
2742-
.iter()
2743-
.fold(None, |acc: Option<token::Amount>, slash| {
2744-
if slash.epoch >= start
2745-
&& slash.epoch
2746-
< withdraw
2747-
.checked_sub(Epoch(
2748-
params.unbonding_len
2749-
+ params.cubic_slashing_window_length,
2750-
))
2751-
.unwrap_or_default()
2752-
{
2753-
let validator_slashes =
2754-
applied_slashes.entry(validator.clone()).or_default();
2755-
if !prev_applied_slashes
2756-
.iter()
2757-
.any(|s| s.clone() == slash.clone())
2758-
{
2759-
validator_slashes.push(slash.clone());
2760-
}
2761-
return Some(
2762-
acc.unwrap_or_default()
2763-
+ decimal_mult_amount(slash.rate, amount),
2764-
);
2765-
}
2766-
acc
2767-
});
2768-
let slashed_amount =
2769-
slashed_amount.map(|slashed| cmp::min(amount, slashed));
2742+
let mut slash_rates_by_epoch = BTreeMap::<Epoch, Decimal>::new();
2743+
2744+
let validator_slashes =
2745+
applied_slashes.entry(validator.clone()).or_default();
2746+
for slash in slashes {
2747+
if slash.epoch >= start
2748+
&& slash.epoch
2749+
< withdraw
2750+
.checked_sub(Epoch(
2751+
params.unbonding_len
2752+
+ params.cubic_slashing_window_length,
2753+
))
2754+
.unwrap_or_default()
2755+
{
2756+
let cur_rate = slash_rates_by_epoch.entry(slash.epoch).or_default();
2757+
*cur_rate = cmp::min(Decimal::ONE, *cur_rate + slash.rate);
2758+
2759+
if !prev_applied_slashes.iter().any(|s| s == slash) {
2760+
validator_slashes.push(slash.clone());
2761+
}
2762+
}
2763+
}
2764+
2765+
let slashed_amount = if slash_rates_by_epoch.is_empty() {
2766+
None
2767+
} else {
2768+
let amount_after_slashing = token::Amount::from_change(
2769+
get_slashed_amount(params, amount, &slash_rates_by_epoch).unwrap(),
2770+
);
2771+
Some(amount - amount_after_slashing)
2772+
};
2773+
27702774
UnbondDetails {
27712775
start,
27722776
withdraw,

proof_of_stake/src/tests.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,10 +988,23 @@ fn test_slashes_with_unbonding_aux(
988988
let token = staking_token_address(&s);
989989
let val_balance_pre = read_balance(&s, &token, val_addr).unwrap();
990990

991+
let bond_id = BondId {
992+
source: val_addr.clone(),
993+
validator: val_addr.clone(),
994+
};
995+
let binding =
996+
super::bonds_and_unbonds(&s, None, Some(val_addr.clone())).unwrap();
997+
let details = binding.get(&bond_id).unwrap();
998+
let exp_withdraw_from_details = details.unbonds[0].amount
999+
- details.unbonds[0].slashed_amount.unwrap_or_default();
1000+
9911001
withdraw_tokens(&mut s, None, val_addr, current_epoch).unwrap();
9921002

9931003
let val_balance_post = read_balance(&s, &token, val_addr).unwrap();
9941004
let withdrawn_tokens = val_balance_post - val_balance_pre;
1005+
println!("Withdrew {withdrawn_tokens} tokens");
1006+
1007+
assert_eq!(exp_withdraw_from_details, withdrawn_tokens);
9951008

9961009
let slash_rate_0 = validator_slashes_handle(val_addr)
9971010
.get(&s, 0)
@@ -1003,7 +1016,7 @@ fn test_slashes_with_unbonding_aux(
10031016
.unwrap()
10041017
.unwrap()
10051018
.rate;
1006-
println!("Slash 0 rate {slash_rate_0}, slash 1 {slash_rate_1}");
1019+
println!("Slash 0 rate {slash_rate_0}, slash 1 rate {slash_rate_1}");
10071020

10081021
let expected_withdrawn_amount = decimal_mult_amount(
10091022
dec!(1) - slash_rate_1,

wasm/checksums.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
{
2-
"tx_bond.wasm": "tx_bond.ebf9ce3a97a3576453a5022014caf995521de10f6b0f21c77aa997d295b51582.wasm",
3-
"tx_change_validator_commission.wasm": "tx_change_validator_commission.2621d62e0b88638931dd7e8535225bda8e76cfed23bdb82ae5bac4ac28d68d6b.wasm",
4-
"tx_ibc.wasm": "tx_ibc.6d26fe5abea04632386e446588667cad1666c38c8cdd5da104f4a8da2a285523.wasm",
5-
"tx_init_account.wasm": "tx_init_account.422badd147072d19c37485bb9af7c59384146ee6178a42f57d90a108d777daa7.wasm",
6-
"tx_init_proposal.wasm": "tx_init_proposal.f6d80d0b0528489cbdd4a5d585de28c4960ca3763fab44db3036e144c5f9743e.wasm",
7-
"tx_init_validator.wasm": "tx_init_validator.7048a2978cc9d86b5208ded834332f21f5154e88b5785b7ad6222283ad3882b5.wasm",
8-
"tx_reveal_pk.wasm": "tx_reveal_pk.de69f0787e0bf5947444259a75ebaa2ecbed37532b3cbd33a9ddfb27f43e6ea2.wasm",
9-
"tx_transfer.wasm": "tx_transfer.53abc1752f23dda8c085d42e808d971515b90d3781617d45386538c8cc2ff8ba.wasm",
10-
"tx_unbond.wasm": "tx_unbond.b467b2952ad2adf9c29fea70c8fb1131c860a8b17a08172828a3060633881d5c.wasm",
11-
"tx_unjail_validator.wasm": "tx_unjail_validator.dc43d738b7ee148a1996dfba92408cca91c6e281d7989507101515eb03eaddfd.wasm",
2+
"tx_bond.wasm": "tx_bond.e3a64e4026c81610b62d4b8fa5e8a5c24ac279d110eb402ccffce5d79db07b93.wasm",
3+
"tx_change_validator_commission.wasm": "tx_change_validator_commission.c81cf8b64f13edce96fd6924c979c101c6199596101ce694f47b206b3673da06.wasm",
4+
"tx_ibc.wasm": "tx_ibc.e8bee97364213334475df66e9a0e23dcf3154ea60294aac72642c3d74c942073.wasm",
5+
"tx_init_account.wasm": "tx_init_account.c17afaeec08c6f90757980bd60fa0d77b4b36b9d0c68ecc71bda222b2f204a86.wasm",
6+
"tx_init_proposal.wasm": "tx_init_proposal.4f10ec824404193f9fc37088aecc7f53564f535191fcd54ab6fbd0bf14a64b28.wasm",
7+
"tx_init_validator.wasm": "tx_init_validator.55e3e1b8222d1b43a15a0ed1488fb2e9eacbaadf5513277a1d8003083b7c2af7.wasm",
8+
"tx_reveal_pk.wasm": "tx_reveal_pk.f5ab2c096a8253c3db83c344724388811f925c884156e18a6c3a634d07ee7640.wasm",
9+
"tx_transfer.wasm": "tx_transfer.1d98257dc00b851c616c1c9e8ab978a6eac0cedebdda22ae3270b47aaf5b164c.wasm",
10+
"tx_unbond.wasm": "tx_unbond.64494eb5a012b5d9515329ff471efed49e6b0eefe6f281ef04a7dbbd344d6234.wasm",
11+
"tx_unjail_validator.wasm": "tx_unjail_validator.624e2dd02883cc21f5738ec11542e1732eea4943ddf683b44d0644b3914c427d.wasm",
1212
"tx_update_vp.wasm": "tx_update_vp.cefd67a267f34d8e93b207a39de9e920616f3d4e5e629086bbcb88b079ce6856.wasm",
1313
"tx_vote_proposal.wasm": "tx_vote_proposal.71da34c54ece175129519120bd597b0226896827cfe0e1c76f435489cd899617.wasm",
14-
"tx_withdraw.wasm": "tx_withdraw.0c8948a6bca1e233f0a89a31ab6caee645da59efd0092178759cf24e84dd5241.wasm",
14+
"tx_withdraw.wasm": "tx_withdraw.37634f6111c4decc45901c20bd4640cceca68ddc51da70adb9bfdfb539c05259.wasm",
1515
"vp_implicit.wasm": "vp_implicit.3acce29720aa7fedb75e7408c09b6bbd6e3a20e0afa7a0f20d58864d8fc3c111.wasm",
1616
"vp_masp.wasm": "vp_masp.cd7fae1152e765ad4e3985fbdd0b8b2cb1cea13e2fff812291ebaf484f8676c9.wasm",
1717
"vp_testnet_faucet.wasm": "vp_testnet_faucet.1dc87f66e7a378df435a20f97592e3a7746a3ccb322ca11889f11822d312ee22.wasm",

0 commit comments

Comments
 (0)