Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
Problem: (Fix #1459) Missing bonded from in staking change
Browse files Browse the repository at this point in the history
Solution: Add bonded_from back to staking change
  • Loading branch information
calvinlauyh committed Apr 22, 2020
1 parent 391e90d commit 8d0cd08
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 20 deletions.
4 changes: 2 additions & 2 deletions chain-abci/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ fn generate_tx_staking_change_event(tx_action: TxAction) -> Option<abci::Event>
}
},
TxAction::Public(tx_public_action) => match tx_public_action {
TxPublicAction::Unbond { unbond, .. } => {
Some(StakingEvent::Unbond(&unbond.0, unbond.1).into())
TxPublicAction::Unbond { unbond, unbonded_from, .. } => {
Some(StakingEvent::Unbond(&unbond.0, unbond.1, unbonded_from).into())
}
TxPublicAction::NodeJoin(staking_address, council_node) => {
Some(StakingEvent::NodeJoin(&staking_address, council_node).into())
Expand Down
57 changes: 45 additions & 12 deletions chain-abci/src/app/staking_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use chain_core::state::account::{CouncilNode, PunishmentKind, StakedStateAddress

pub(crate) enum StakingEvent<'a> {
Deposit(&'a StakedStateAddress, Coin),
Unbond(&'a StakedStateAddress, Coin),
Unbond(&'a StakedStateAddress, Coin, Timespec),
Withdraw(&'a StakedStateAddress, Coin),
NodeJoin(&'a StakedStateAddress, CouncilNode),
Reward(&'a StakedStateAddress, Coin),
Expand All @@ -27,8 +27,8 @@ impl<'a> From<StakingEvent<'a>> for Event {
StakingEvent::Deposit(staking_address, deposit_amount) => {
builder.deposit(staking_address, deposit_amount)
}
StakingEvent::Unbond(staking_address, unbond_amount) => {
builder.unbond(staking_address, unbond_amount)
StakingEvent::Unbond(staking_address, unbond_amount, unbonded_from) => {
builder.unbond(staking_address, unbond_amount, unbonded_from)
}
StakingEvent::Withdraw(staking_address, withdraw_amount) => {
builder.withdraw(staking_address, withdraw_amount)
Expand Down Expand Up @@ -80,7 +80,12 @@ impl StakingEventBuilder {
);
}

fn unbond(&mut self, staking_address: &StakedStateAddress, unbond_amount: Coin) {
fn unbond(
&mut self,
staking_address: &StakedStateAddress,
unbond_amount: Coin,
unbonded_from: Timespec,
) {
self.attributes
.push(staking_address_attribute(staking_address));
self.attributes.push(StakingEventOpType::Unbond.into());
Expand All @@ -89,6 +94,7 @@ impl StakingEventBuilder {
StakingDiffField(vec![
StakingDiff::Bonded(StakingCoinChange::Decrease, unbond_amount),
StakingDiff::Unbonded(StakingCoinChange::Increase, unbond_amount),
StakingDiff::UnbondedFrom(unbonded_from),
])
.into(),
);
Expand Down Expand Up @@ -268,6 +274,7 @@ impl fmt::Display for StakingDiffField {
enum StakingDiff {
Bonded(StakingCoinChange, Coin),
Unbonded(StakingCoinChange, Coin),
UnbondedFrom(Timespec),
NodeJoin(CouncilNode),
JailedUntil(Timespec),
}
Expand Down Expand Up @@ -296,6 +303,12 @@ impl Serialize for StakingDiff {
)?;
state.end()
}
StakingDiff::UnbondedFrom(unbonded_from) => {
let mut state = serializer.serialize_struct("UnbondedFrom", 2)?;
state.serialize_field("key", "UnbondedFrom")?;
state.serialize_field("value", &unbonded_from)?;
state.end()
}
StakingDiff::NodeJoin(node) => {
let mut state = serializer.serialize_struct("NodeJoin", 2)?;
state.serialize_field("key", "CouncilNode")?;
Expand All @@ -305,7 +318,7 @@ impl Serialize for StakingDiff {
StakingDiff::JailedUntil(jailed_until) => {
let mut state = serializer.serialize_struct("JailedUntil", 2)?;
state.serialize_field("key", "JailedUntil")?;
state.serialize_field("value", &jailed_until.to_string())?;
state.serialize_field("value", &jailed_until)?;
state.end()
}
}
Expand Down Expand Up @@ -393,6 +406,21 @@ mod tests {
}
}

mod unbonded_from {
use super::*;

#[test]
fn to_string_should_serialize_to_json() {
let any_unbonded_from: Timespec = 1587071014;
let staking_diff = StakingDiff::UnbondedFrom(any_unbonded_from);

assert_eq!(
staking_diff.to_string(),
"{\"key\":\"UnbondedFrom\",\"value\":1587071014}",
);
}
}

mod node_join {
use super::*;

Expand Down Expand Up @@ -429,7 +457,7 @@ mod tests {

assert_eq!(
staking_diff.to_string(),
"{\"key\":\"JailedUntil\",\"value\":\"1587071014\"}",
"{\"key\":\"JailedUntil\",\"value\":1587071014}",
);
}
}
Expand Down Expand Up @@ -459,10 +487,13 @@ mod tests {
fn should_create_unbond_event() {
let any_staking_address = any_staking_address();
let any_amount = Coin::unit();
let any_unbonded_from: Timespec = 1587071014;

let event: Event = StakingEvent::Unbond(&any_staking_address, any_amount).into();
let event: Event =
StakingEvent::Unbond(&any_staking_address, any_amount, any_unbonded_from)
.into();

assert_unbonded_event(event, &any_staking_address, any_amount);
assert_unbonded_event(event, &any_staking_address, any_amount, any_unbonded_from);
}
}

Expand Down Expand Up @@ -619,6 +650,7 @@ mod tests {
event: Event,
staking_address: &StakedStateAddress,
unbond_amount: Coin,
unbonded_from: Timespec,
) {
assert_eq!(
event.field_type,
Expand All @@ -640,14 +672,15 @@ mod tests {
StakingEventOpType::Unbond.to_string(),
);

let staking_diff_bonded_attribute = event.attributes.get(2).unwrap();
let staking_diff_attribute = event.attributes.get(2).unwrap();
let expected_value = format!(
"[{{\"key\":\"Bonded\",\"value\":\"-{}\"}},{{\"key\":\"Unbonded\",\"value\":\"{}\"}}]",
"[{{\"key\":\"Bonded\",\"value\":\"-{}\"}},{{\"key\":\"Unbonded\",\"value\":\"{}\"}},{{\"key\":\"UnbondedFrom\",\"value\":{}}}]",
u64::from(unbond_amount),
u64::from(unbond_amount),
unbonded_from,
);
assert_kv_pair(
staking_diff_bonded_attribute,
staking_diff_attribute,
TendermintEventKey::StakingDiff.to_string(),
expected_value,
);
Expand Down Expand Up @@ -795,7 +828,7 @@ mod tests {
let staking_diff_attribute = event.attributes.get(2).unwrap();
let expected_timespec = timespec.to_string();
let expected_value = format!(
"[{{\"key\":\"JailedUntil\",\"value\":\"{}\"}}]",
"[{{\"key\":\"JailedUntil\",\"value\":{}}}]",
expected_timespec
);
assert_kv_pair(
Expand Down
8 changes: 5 additions & 3 deletions chain-abci/src/staking/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl StakingTable {
block_time: Timespec,
block_height: BlockHeight,
tx: &UnbondTx,
) -> Result<(), PublicTxError> {
) -> Result<Timespec, PublicTxError> {
let mut staking = self.get_or_default(heap, &tx.from_staked_account);
if tx.nonce != staking.nonce {
return Err(PublicTxError::IncorrectNonce);
Expand All @@ -160,12 +160,14 @@ impl StakingTable {
self.sub_bonded(block_time, block_height, tx.value, &mut staking)
.map_err(UnbondError::CoinError)?;
staking.unbonded = unbonded;
staking.unbonded_from = block_time.saturating_add(unbonding_period);

let unbonded_from = block_time.saturating_add(unbonding_period);
staking.unbonded_from = unbonded_from;
staking.inc_nonce();
set_staking(heap, staking, self.minimal_required_staking);
#[cfg(debug_assertions)]
self.check_invariants(heap);
Ok(())
Ok(unbonded_from)
}

/// Handle withdraw tx
Expand Down
8 changes: 5 additions & 3 deletions chain-abci/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,15 @@ pub enum TxPublicAction {
Unbond {
fee: Fee,
unbond: (StakedStateAddress, Coin),
unbonded_from: Timespec,
},
NodeJoin(StakedStateAddress, CouncilNode),
Unjail(StakedStateAddress),
}

impl TxPublicAction {
fn unbond(fee: Fee, unbond: (StakedStateAddress, Coin)) -> Self {
Self::Unbond { fee, unbond }
fn unbond(fee: Fee, unbond: (StakedStateAddress, Coin), unbonded_from: Timespec) -> Self {
Self::Unbond { fee, unbond, unbonded_from }
}
fn node_join(staking_address: StakedStateAddress, council_node: CouncilNode) -> Self {
Self::NodeJoin(staking_address, council_node)
Expand Down Expand Up @@ -292,7 +293,7 @@ pub fn process_public_tx(
if address != maintx.from_staked_account {
return Err(PublicTxError::StakingWitnessNotMatch);
}
staking_table.unbond(
let unbonded_from = staking_table.unbond(
staking_store,
chain_info.unbonding_period as Timespec,
chain_info.block_time,
Expand All @@ -303,6 +304,7 @@ pub fn process_public_tx(
Ok(TxPublicAction::unbond(
chain_info.min_fee_computed,
(address, maintx.value),
unbonded_from,
))
}
// TODO: delay checking witness, as address is contained in Tx?
Expand Down

0 comments on commit 8d0cd08

Please sign in to comment.