Skip to content

Commit dc9a0cf

Browse files
Seulgi Kimmergify[bot]
authored andcommitted
Handle nomination expiration properly
1 parent d471768 commit dc9a0cf

File tree

3 files changed

+57
-19
lines changed

3 files changed

+57
-19
lines changed

core/src/consensus/solo/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ impl ConsensusEngine for Solo<CodeChainMachine> {
120120
for (address, reward) in rewards {
121121
self.machine.add_balance(block, &address, reward)?;
122122
}
123-
self.machine.increase_term_id(block, last_term_finished_block_num)?;
123+
124+
stake::on_term_close(block.state_mut(), last_term_finished_block_num)?;
124125
Ok(())
125126
}
126127

core/src/consensus/stake/mod.rs

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::collections::HashMap;
2323

2424
use ccrypto::Blake;
2525
use ckey::{public_to_address, recover, Address, Public, Signature};
26-
use cstate::{ActionHandler, StateResult, TopLevelState, TopState};
26+
use cstate::{ActionHandler, StateResult, TopLevelState, TopState, TopStateView};
2727
use ctypes::errors::{RuntimeError, SyntaxError};
2828
use ctypes::util::unexpected::Mismatch;
2929
use ctypes::{CommonParams, Header};
@@ -96,7 +96,20 @@ impl ActionHandler for Stake {
9696
Action::SelfNominate {
9797
deposit,
9898
metadata,
99-
} => self_nominate(state, sender, sender_public, deposit, 0, 0, metadata),
99+
} => {
100+
let (current_term, nomination_ends_at) = {
101+
let metadata = state.metadata()?.expect("Metadata must exist");
102+
const DEFAULT_NOMINATION_EXPIRATION: u64 = 24;
103+
let current_term = metadata.current_term_id();
104+
let expiration = metadata
105+
.params()
106+
.map(CommonParams::nomination_expiration)
107+
.unwrap_or(DEFAULT_NOMINATION_EXPIRATION);
108+
let nomination_ends_at = current_term + expiration;
109+
(current_term, nomination_ends_at)
110+
};
111+
self_nominate(state, sender, sender_public, deposit, current_term, nomination_ends_at, metadata)
112+
}
100113
Action::ChangeParams {
101114
metadata_seq,
102115
params,
@@ -188,8 +201,6 @@ fn self_nominate(
188201
nomination_ends_at: u64,
189202
metadata: Bytes,
190203
) -> StateResult<()> {
191-
// TODO: proper handling of get_current_term
192-
// TODO: proper handling of NOMINATE_EXPIRATION
193204
let blacklist = Banned::load_from_state(state)?;
194205
if blacklist.is_banned(&sender) {
195206
return Err(RuntimeError::FailedToHandleCustomAction("Account is blacklisted".to_string()).into())
@@ -281,8 +292,8 @@ fn change_params(
281292
Ok(())
282293
}
283294

284-
#[allow(dead_code)]
285-
pub fn on_term_close(state: &mut TopLevelState, current_term: u64) -> StateResult<()> {
295+
pub fn on_term_close(state: &mut TopLevelState, last_term_finished_block_num: u64) -> StateResult<()> {
296+
let current_term = state.metadata()?.expect("The metadata must exist").current_term_id();
286297
// TODO: total_slash = slash_unresponsive(headers, pending_rewards)
287298
// TODO: pending_rewards.update(signature_reward(blocks, total_slash))
288299

@@ -309,6 +320,8 @@ pub fn on_term_close(state: &mut TopLevelState, current_term: u64) -> StateResul
309320
revert_delegations(state, &reverted)?;
310321

311322
// TODO: validators, validator_order = elect()
323+
324+
state.increase_term_id(last_term_finished_block_num)?;
312325
Ok(())
313326
}
314327

@@ -846,12 +859,23 @@ mod tests {
846859
assert!(result.is_err(), "Cannot self-nominate without a sufficient balance");
847860
}
848861

862+
fn increase_term_id_until(state: &mut TopLevelState, term_id: u64) {
863+
let mut block_num = state.metadata().unwrap().unwrap().last_term_finished_block_num() + 1;
864+
while state.metadata().unwrap().unwrap().current_term_id() != term_id {
865+
assert_eq!(Ok(()), state.increase_term_id(block_num));
866+
block_num += 1;
867+
}
868+
}
869+
849870
#[test]
850871
fn self_nominate_returns_deposits_after_expiration() {
851872
let address_pubkey = Public::random();
852873
let address = public_to_address(&address_pubkey);
853874

854875
let mut state = helpers::get_temp_state();
876+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
877+
increase_term_id_until(&mut state, 29);
878+
855879
state.add_balance(&address, 1000).unwrap();
856880

857881
let stake = Stake::new(HashMap::new());
@@ -860,7 +884,7 @@ mod tests {
860884
// TODO: change with stake.execute()
861885
self_nominate(&mut state, &address, &address_pubkey, 200, 0, 30, b"".to_vec()).unwrap();
862886

863-
let result = on_term_close(&mut state, 29);
887+
let result = on_term_close(&mut state, pseudo_term_to_block_num_calculator(29));
864888
assert_eq!(result, Ok(()));
865889

866890
assert_eq!(state.balance(&address).unwrap(), 800, "Should keep nomination before expiration");
@@ -876,7 +900,7 @@ mod tests {
876900
"Keep deposit before expiration",
877901
);
878902

879-
let result = on_term_close(&mut state, 30);
903+
let result = on_term_close(&mut state, pseudo_term_to_block_num_calculator(30));
880904
assert_eq!(result, Ok(()));
881905

882906
assert_eq!(state.balance(&address).unwrap(), 1000, "Return deposit after expiration");
@@ -892,6 +916,8 @@ mod tests {
892916
let delegator = public_to_address(&address_pubkey);
893917

894918
let mut state = helpers::get_temp_state();
919+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
920+
increase_term_id_until(&mut state, 29);
895921
state.add_balance(&address, 1000).unwrap();
896922

897923
let stake = {
@@ -910,15 +936,15 @@ mod tests {
910936
};
911937
stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey).unwrap();
912938

913-
let result = on_term_close(&mut state, 29);
939+
let result = on_term_close(&mut state, pseudo_term_to_block_num_calculator(29));
914940
assert_eq!(result, Ok(()));
915941

916942
let account = StakeAccount::load_from_state(&state, &delegator).unwrap();
917943
assert_eq!(account.balance, 100 - 40);
918944
let delegation = Delegation::load_from_state(&state, &delegator).unwrap();
919945
assert_eq!(delegation.get_quantity(&address), 40, "Should keep delegation before expiration");
920946

921-
let result = on_term_close(&mut state, 30);
947+
let result = on_term_close(&mut state, pseudo_term_to_block_num_calculator(30));
922948
assert_eq!(result, Ok(()));
923949

924950
let account = StakeAccount::load_from_state(&state, &delegator).unwrap();
@@ -971,6 +997,7 @@ mod tests {
971997
let address = public_to_address(&address_pubkey);
972998

973999
let mut state = helpers::get_temp_state();
1000+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
9741001
state.add_balance(&address, 1000).unwrap();
9751002

9761003
let stake = Stake::new(HashMap::new());
@@ -1000,7 +1027,7 @@ mod tests {
10001027
current_term,
10011028
custody_until
10021029
);
1003-
on_term_close(&mut state, current_term).unwrap();
1030+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term)).unwrap();
10041031
}
10051032
}
10061033

@@ -1010,6 +1037,7 @@ mod tests {
10101037
let address = public_to_address(&address_pubkey);
10111038

10121039
let mut state = helpers::get_temp_state();
1040+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
10131041
state.add_balance(&address, 1000).unwrap();
10141042

10151043
let stake = Stake::new(HashMap::new());
@@ -1024,7 +1052,7 @@ mod tests {
10241052
.unwrap();
10251053
jail(&mut state, &address, custody_until, released_at).unwrap();
10261054
for current_term in 0..=custody_until {
1027-
on_term_close(&mut state, current_term).unwrap();
1055+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term)).unwrap();
10281056
}
10291057

10301058
let current_term = custody_until + 1;
@@ -1064,6 +1092,7 @@ mod tests {
10641092
let address = public_to_address(&address_pubkey);
10651093

10661094
let mut state = helpers::get_temp_state();
1095+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
10671096
state.add_balance(&address, 1000).unwrap();
10681097

10691098
let stake = Stake::new(HashMap::new());
@@ -1078,7 +1107,7 @@ mod tests {
10781107
jail(&mut state, &address, custody_until, released_at).unwrap();
10791108

10801109
for current_term in 0..released_at {
1081-
on_term_close(&mut state, current_term).unwrap();
1110+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term)).unwrap();
10821111

10831112
let candidates = Candidates::load_from_state(&state).unwrap();
10841113
assert_eq!(candidates.get_candidate(&address), None);
@@ -1087,7 +1116,7 @@ mod tests {
10871116
assert!(jail.get_prisoner(&address).is_some());
10881117
}
10891118

1090-
on_term_close(&mut state, released_at).unwrap();
1119+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(released_at)).unwrap();
10911120

10921121
let candidates = Candidates::load_from_state(&state).unwrap();
10931122
assert_eq!(candidates.get_candidate(&address), None, "A prisoner should not become a candidate");
@@ -1106,6 +1135,7 @@ mod tests {
11061135
let delegator = public_to_address(&delegator_pubkey);
11071136

11081137
let mut state = helpers::get_temp_state();
1138+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
11091139
state.add_balance(&address, 1000).unwrap();
11101140

11111141
let stake = {
@@ -1131,7 +1161,7 @@ mod tests {
11311161
let result = stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey);
11321162
assert!(result.is_ok());
11331163

1134-
on_term_close(&mut state, current_term).unwrap();
1164+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term)).unwrap();
11351165
}
11361166

11371167
let action = Action::DelegateCCS {
@@ -1150,6 +1180,7 @@ mod tests {
11501180
let delegator = public_to_address(&delegator_pubkey);
11511181

11521182
let mut state = helpers::get_temp_state();
1183+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
11531184
state.add_balance(&address, 1000).unwrap();
11541185

11551186
let stake = {
@@ -1174,7 +1205,7 @@ mod tests {
11741205
stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey).unwrap();
11751206

11761207
for current_term in 0..=released_at {
1177-
on_term_close(&mut state, current_term).unwrap();
1208+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term)).unwrap();
11781209
}
11791210

11801211
let delegation = Delegation::load_from_state(&state, &delegator).unwrap();
@@ -1192,6 +1223,7 @@ mod tests {
11921223
let delegator = public_to_address(&delegator_pubkey);
11931224

11941225
let mut state = helpers::get_temp_state();
1226+
assert_eq!(Ok(()), state.update_params(0, CommonParams::default_for_test()));
11951227
state.add_balance(&address, 1000).unwrap();
11961228

11971229
let stake = {
@@ -1214,7 +1246,7 @@ mod tests {
12141246
};
12151247
stake.execute(&action.rlp_bytes(), &mut state, &delegator, &delegator_pubkey).unwrap();
12161248
for current_term in 0..custody_until {
1217-
on_term_close(&mut state, current_term).unwrap();
1249+
on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term)).unwrap();
12181250
}
12191251

12201252
let current_term = custody_until + 1;
@@ -1298,4 +1330,8 @@ mod tests {
12981330
let jail = Jail::load_from_state(&state).unwrap();
12991331
assert_eq!(jail.get_prisoner(&criminal), None, "Should be removed from the jail");
13001332
}
1333+
1334+
fn pseudo_term_to_block_num_calculator(term_id: u64) -> u64 {
1335+
term_id * 10 + 1
1336+
}
13011337
}

core/src/consensus/tendermint/engine.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,9 @@ impl ConsensusEngine for Tendermint {
202202
self.machine.add_balance(block, &address, reward)?;
203203
}
204204

205-
self.machine.increase_term_id(block, last_term_finished_block_num)?;
206205
stake::move_current_to_previous_intermediate_rewards(&mut block.state_mut())?;
206+
stake::on_term_close(block.state_mut(), last_term_finished_block_num)?;
207+
207208
Ok(())
208209
}
209210

0 commit comments

Comments
 (0)