diff --git a/Cargo.toml b/Cargo.toml index fa9442d1..bb942d69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,7 +89,7 @@ abci = [ "reqwest", ] merk-verify = ["merk/verify"] -merk-full = ["merk/full", "ics23"] +merk-full = ["merk/full", "merk-verify", "ics23"] state-sync = [] feat-ibc = ["ibc", "ics23", "prost-types", "ibc-proto", "tendermint"] @@ -104,4 +104,4 @@ required-features = ["abci", "merk-full", "feat-ibc"] name = "app" crate-type = ["bin"] path = "examples/app/main.rs" -required-features = ["feat-ibc", "merk-verify"] +required-features = ["abci", "merk-full", "feat-ibc"] diff --git a/src/coins/staking/mod.rs b/src/coins/staking/mod.rs index 49f3e541..0269da10 100644 --- a/src/coins/staking/mod.rs +++ b/src/coins/staking/mod.rs @@ -500,13 +500,14 @@ impl Staking { validator.jail_forever(); validator.slash(self.slash_fraction_double_sign, false)? }; - let multiplier = (Decimal::one() - self.slash_fraction_double_sign)?; for entry in redelegations.iter() { let del_address = entry.delegator_address; for redelegation in entry.outbound_redelegations.iter() { let mut validator = self.validators.get_mut(redelegation.address.into())?; let mut delegator = validator.get_mut(del_address.into())?; - delegator.slash_redelegation((multiplier * redelegation.amount)?.amount()?)?; + delegator.slash_redelegation( + (self.slash_fraction_double_sign * redelegation.amount)?.amount()?, + )?; } } self.update_vp(val_address) diff --git a/src/coins/staking/tests.rs b/src/coins/staking/tests.rs index 98d859a8..deec4a9e 100644 --- a/src/coins/staking/tests.rs +++ b/src/coins/staking/tests.rs @@ -33,8 +33,8 @@ fn setup_state() -> Result> { unbonding_seconds: UNBONDING_SECONDS, max_validators: 100, max_offline_blocks: 50_000, - slash_fraction_downtime: (Amount::new(1) / Amount::new(2))?, - slash_fraction_double_sign: (Amount::new(1) / Amount::new(2))?, + slash_fraction_downtime: (Amount::new(1) / Amount::new(3))?, + slash_fraction_double_sign: (Amount::new(1) / Amount::new(3))?, min_self_delegation_min: 1, ..Default::default() }; @@ -541,12 +541,12 @@ fn undelegate_slash_before_unbond() -> Result<()> { assert_eq!(ctx.updates.get(&[0; 32]).unwrap().power, 0); assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 0); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 50); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 67); Context::add(Time::from_seconds(10)); staking.end_block_step(&Default::default())?; let balance: Amount = simp_balance(&staking.get(val_0)?.get(staker)?.liquid); - assert_eq!(balance, 50); + assert_eq!(balance, 67); Ok(()) } @@ -595,7 +595,7 @@ fn undelegate_slash_after_unbond() -> Result<()> { assert_eq!(ctx.updates.get(&[0; 32]).unwrap().power, 0); assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 0); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 50); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 67); staking.end_block_step(&Default::default())?; let balance: Amount = simp_balance(&staking.get(val_0)?.get(staker)?.liquid); @@ -702,10 +702,10 @@ fn redelegate_slash_before_unbond() -> Result<()> { let val_1 = Address::from_pubkey([1; 33]); assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 0); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 50); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 67); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 50); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 150); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 67); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 167); Ok(()) } @@ -766,7 +766,7 @@ fn redelegate_slash_after_unbond() -> Result<()> { assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 0); assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 100); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 50); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 67); assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 200); Ok(()) @@ -848,23 +848,23 @@ fn redelegation_slash() -> Result<()> { let val_1 = Address::from_pubkey([1; 33]); let val_2 = Address::from_pubkey([2; 33]); - assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 65); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 20); - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 165); + assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 70); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 27); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 170); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 165); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 70); - assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 265); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 170); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 93); + assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 270); staking.punish_double_sign(Address::from_pubkey([0; 33]))?; staking.end_block_step(&Default::default())?; - assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 32); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 20); - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 140); + assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 47); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 27); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 153); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 82); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 70); - assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 240); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 113); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 93); + assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 253); Ok(()) } @@ -915,7 +915,7 @@ fn redelegation_double_slash() -> Result<()> { staking.end_block_step(&Default::default())?; assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 0); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 25); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 45); Ok(()) } @@ -996,13 +996,13 @@ fn redelegation_slash_with_unbond() -> Result<()> { let val_1 = Address::from_pubkey([1; 33]); let val_2 = Address::from_pubkey([2; 33]); - assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 65); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 20); - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 165); + assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 70); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 27); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 170); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 165); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 70); - assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 265); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 170); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 93); + assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 270); staking.unbond(val_2, staker, Amount::from(100))?; staking.end_block_step(&Default::default())?; @@ -1010,13 +1010,13 @@ fn redelegation_slash_with_unbond() -> Result<()> { staking.punish_double_sign(Address::from_pubkey([0; 33]))?; staking.end_block_step(&Default::default())?; - assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 32); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 20); - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 40); + assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 47); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 27); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 53); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 82); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 70); - assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 140); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 113); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 93); + assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 153); Context::add(Time::from_seconds(10)); staking.end_block_step(&Default::default())?; @@ -1102,13 +1102,13 @@ fn redelegation_slash_with_slash_unbond_overflow() -> Result<()> { let val_1 = Address::from_pubkey([1; 33]); let val_2 = Address::from_pubkey([2; 33]); - assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 65); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 20); - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 165); + assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 70); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 27); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 170); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 165); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 70); - assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 265); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 170); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 93); + assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 270); for _ in 0..15 { staking.unbond(val_2, staker, Amount::from(10))?; @@ -1116,23 +1116,23 @@ fn redelegation_slash_with_slash_unbond_overflow() -> Result<()> { staking.end_block_step(&Default::default())?; - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 15); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 20); staking.punish_double_sign(Address::from_pubkey([0; 33]))?; staking.end_block_step(&Default::default())?; - assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 32); - assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 20); - assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 0); + assert_eq!(staking.get(val_0)?.get(staker)?.staked.amount()?, 47); + assert_eq!(staking.get(val_1)?.get(staker)?.staked.amount()?, 27); + assert_eq!(staking.get(val_2)?.get(staker)?.staked.amount()?, 3); - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 82); - assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 70); - assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 100); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 113); + assert_eq!(staking.get_mut(val_1)?.delegators.balance()?.amount()?, 93); + assert_eq!(staking.get_mut(val_2)?.delegators.balance()?.amount()?, 103); Context::add(Time::from_seconds(10)); staking.end_block_step(&Default::default())?; - assert_eq!(simp_balance(&staking.get(val_2)?.get(staker)?.liquid), 140); + assert_eq!(simp_balance(&staking.get(val_2)?.get(staker)?.liquid), 150); Ok(()) } @@ -1204,7 +1204,7 @@ fn min_delegation_fall_below() -> Result<()> { staking.end_block_step(&Default::default())?; staking.punish_downtime(Address::from_pubkey([0; 33]))?; - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 50); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 67); Context::add(Time::from_seconds(10)); staking.end_block_step(&Default::default())?; @@ -1219,8 +1219,8 @@ fn min_delegation_fall_below() -> Result<()> { staking.end_block_step(&Default::default())?; - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 75); - assert_eq!(ctx.updates.get(&[0; 32]).unwrap().power, 75); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 92); + assert_eq!(ctx.updates.get(&[0; 32]).unwrap().power, 92); Ok(()) } @@ -1314,13 +1314,13 @@ fn punish_downtime_jailed() -> Result<()> { staking.end_block_step(&Default::default())?; staking.punish_downtime(Address::from_pubkey([0; 33]))?; - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 50); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 67); staking.end_block_step(&Default::default())?; staking.punish_double_sign(val_0)?; staking.end_block_step(&Default::default())?; - assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 25); + assert_eq!(staking.get_mut(val_0)?.delegators.balance()?.amount()?, 44); Ok(()) } diff --git a/src/ibc/client_contexts.rs b/src/ibc/client_contexts.rs index 2222d5a1..1503e8f6 100644 --- a/src/ibc/client_contexts.rs +++ b/src/ibc/client_contexts.rs @@ -191,6 +191,10 @@ impl ClientExecutionContext for IbcContext { &mut self, consensus_state_path: ibc::core::host::types::path::ClientConsensusStatePath, ) -> Result<(), ContextError> { + let epoch_height = format!( + "{}-{}", + consensus_state_path.revision_number, consensus_state_path.revision_height + ); self.clients .get_mut(consensus_state_path.client_id.clone().into()) .map_err(|_| ClientError::ClientSpecific { @@ -200,7 +204,7 @@ impl ClientExecutionContext for IbcContext { client_id: consensus_state_path.client_id.clone(), })? .consensus_states - .remove(consensus_state_path.revision_height.to_string().into()) + .remove(epoch_height.into()) .map_err(|_| ClientError::ClientSpecific { description: "Unable to delete consensus state".to_string(), })?; diff --git a/src/merk/store.rs b/src/merk/store.rs index 753a5f08..07fb4be1 100644 --- a/src/merk/store.rs +++ b/src/merk/store.rs @@ -302,6 +302,7 @@ impl ABCIStore for MerkStore { self.write(metadata)?; self.merk.as_mut().unwrap().flush()?; + #[cfg(feature = "state-sync")] let recent = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() @@ -393,6 +394,7 @@ impl ABCIStore for MerkStore { && calc_app_hash(snapshot.hash.to_vec().as_slice()) == req.app_hash { self.target_snapshot = Some(snapshot); + self.restorer = None; res.set_result(abci::response_offer_snapshot::Result::Accept); } }