@@ -33,6 +33,7 @@ use rlp::{Decodable, UntrustedRlp};
33
33
use self :: action_data:: { Candidates , Delegation , IntermediateRewards , Jail , ReleaseResult , StakeAccount , Stakeholders } ;
34
34
use self :: actions:: Action ;
35
35
pub use self :: distribute:: fee_distribute;
36
+ use consensus:: stake:: action_data:: Banned ;
36
37
37
38
const CUSTOM_ACTION_HANDLER_ID : u64 = 2 ;
38
39
@@ -209,16 +210,18 @@ fn transfer_ccs(state: &mut TopLevelState, sender: &Address, receiver: &Address,
209
210
}
210
211
211
212
fn delegate_ccs ( state : & mut TopLevelState , sender : & Address , delegatee : & Address , quantity : u64 ) -> StateResult < ( ) > {
212
- // TODO: remove parent hash from validator set.
213
- // TODO: handle banned account
214
- // TODO: handle jailed account
213
+ let banned = Banned :: load_from_state ( state) ?;
214
+ if banned. is_banned ( & delegatee) {
215
+ return Err ( RuntimeError :: FailedToHandleCustomAction ( "Delegatee is banned" . to_string ( ) ) . into ( ) )
216
+ }
215
217
let candidates = Candidates :: load_from_state ( state) ?;
216
218
let jail = Jail :: load_from_state ( state) ?;
217
219
if candidates. get_candidate ( delegatee) . is_none ( ) && jail. get_prisoner ( delegatee) . is_none ( ) {
218
220
return Err (
219
221
RuntimeError :: FailedToHandleCustomAction ( "Can delegate to who is a candidate or a prisoner" . into ( ) ) . into ( )
220
222
)
221
223
}
224
+
222
225
let mut delegator = StakeAccount :: load_from_state ( state, sender) ?;
223
226
let mut delegation = Delegation :: load_from_state ( state, & sender) ?;
224
227
@@ -253,7 +256,10 @@ fn self_nominate(
253
256
) -> StateResult < ( ) > {
254
257
// TODO: proper handling of get_current_term
255
258
// TODO: proper handling of NOMINATE_EXPIRATION
256
- // TODO: check banned accounts
259
+ let blacklist = Banned :: load_from_state ( state) ?;
260
+ if blacklist. is_banned ( & sender) {
261
+ return Err ( RuntimeError :: FailedToHandleCustomAction ( "Account is blacklisted" . to_string ( ) ) . into ( ) )
262
+ }
257
263
258
264
let mut jail = Jail :: load_from_state ( & state) ?;
259
265
let total_deposit = match jail. try_release ( sender, current_term) {
@@ -383,6 +389,30 @@ pub fn jail(state: &mut TopLevelState, address: &Address, custody_until: u64, ki
383
389
Ok ( ( ) )
384
390
}
385
391
392
+ #[ allow( dead_code) ]
393
+ pub fn ban ( state : & mut TopLevelState , criminal : Address ) -> StateResult < ( ) > {
394
+ // TODO: remove pending rewards.
395
+ // TODO: remove from validators.
396
+ // TODO: give criminal's deposits to the informant
397
+ // TODO: give criminal's rewards to diligent validators
398
+ let mut candidates = Candidates :: load_from_state ( state) ?;
399
+ let mut banned = Banned :: load_from_state ( state) ?;
400
+ let mut jailed = Jail :: load_from_state ( state) ?;
401
+
402
+ candidates. remove ( & criminal) ;
403
+ jailed. remove ( & criminal) ;
404
+ banned. add ( criminal) ;
405
+
406
+ jailed. save_to_state ( state) ?;
407
+ banned. save_to_state ( state) ?;
408
+ candidates. save_to_state ( state) ?;
409
+
410
+ // Revert delegations
411
+ revert_delegations ( state, & [ criminal] ) ?;
412
+
413
+ Ok ( ( ) )
414
+ }
415
+
386
416
fn revert_delegations ( state : & mut TopLevelState , reverted_delegatees : & [ Address ] ) -> StateResult < ( ) > {
387
417
let stakeholders = Stakeholders :: load_from_state ( state) ?;
388
418
for stakeholder in stakeholders. iter ( ) {
@@ -1207,4 +1237,64 @@ mod tests {
1207
1237
let account = StakeAccount :: load_from_state ( & state, & delegator) . unwrap ( ) ;
1208
1238
assert_eq ! ( account. balance, 100 - 40 , "Delegation should be preserved" ) ;
1209
1239
}
1240
+
1241
+ #[ test]
1242
+ fn test_ban ( ) {
1243
+ let criminal = Address :: random ( ) ;
1244
+ let delegator = Address :: random ( ) ;
1245
+
1246
+ let mut state = helpers:: get_temp_state ( ) ;
1247
+ state. add_balance ( & criminal, 1000 ) . unwrap ( ) ;
1248
+
1249
+ let stake = {
1250
+ let mut genesis_stakes = HashMap :: new ( ) ;
1251
+ genesis_stakes. insert ( delegator, 100 ) ;
1252
+ Stake :: new ( genesis_stakes)
1253
+ } ;
1254
+ stake. init ( & mut state) . unwrap ( ) ;
1255
+
1256
+ self_nominate ( & mut state, & criminal, 100 , 0 , 10 ) . unwrap ( ) ;
1257
+ let action = Action :: DelegateCCS {
1258
+ address : criminal,
1259
+ quantity : 40 ,
1260
+ } ;
1261
+ stake. execute ( & action. rlp_bytes ( ) , & mut state, & delegator) . unwrap ( ) ;
1262
+
1263
+ let result = ban ( & mut state, criminal) ;
1264
+ assert ! ( result. is_ok( ) ) ;
1265
+
1266
+ let banned = Banned :: load_from_state ( & state) . unwrap ( ) ;
1267
+ assert ! ( banned. is_banned( & criminal) ) ;
1268
+
1269
+ let candidates = Candidates :: load_from_state ( & state) . unwrap ( ) ;
1270
+ assert_eq ! ( candidates. len( ) , 0 ) ;
1271
+
1272
+ assert_eq ! ( state. balance( & criminal) . unwrap( ) , 900 , "Should lose deposit" ) ;
1273
+
1274
+ let delegation = Delegation :: load_from_state ( & state, & delegator) . unwrap ( ) ;
1275
+ assert_eq ! ( delegation. get_quantity( & criminal) , 0 , "Delegation should be reverted" ) ;
1276
+
1277
+ let account_delegator = StakeAccount :: load_from_state ( & state, & delegator) . unwrap ( ) ;
1278
+ assert_eq ! ( account_delegator. balance, 100 , "Delegation should be reverted" ) ;
1279
+ }
1280
+
1281
+ #[ test]
1282
+ fn ban_should_remove_prisoner_from_jail ( ) {
1283
+ let criminal = Address :: random ( ) ;
1284
+
1285
+ let mut state = helpers:: get_temp_state ( ) ;
1286
+ let stake = Stake :: new ( HashMap :: new ( ) ) ;
1287
+ stake. init ( & mut state) . unwrap ( ) ;
1288
+
1289
+ self_nominate ( & mut state, & criminal, 0 , 0 , 10 ) . unwrap ( ) ;
1290
+ let custody_until = 10 ;
1291
+ let kicked_at = 20 ;
1292
+ jail ( & mut state, & criminal, custody_until, kicked_at) . unwrap ( ) ;
1293
+
1294
+ let result = ban ( & mut state, criminal) ;
1295
+ assert ! ( result. is_ok( ) ) ;
1296
+
1297
+ let jail = Jail :: load_from_state ( & state) . unwrap ( ) ;
1298
+ assert_eq ! ( jail. get_prisoner( & criminal) , None , "Should be removed from the jail" ) ;
1299
+ }
1210
1300
}
0 commit comments