Skip to content

Commit 65a0072

Browse files
committed
Introduce Users struct
Users limits the lifetime of the inner lock.
1 parent 89d9edd commit 65a0072

File tree

1 file changed

+49
-30
lines changed

1 file changed

+49
-30
lines changed

core/src/miner/miner.rs

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
use std::collections::HashSet;
1818
use std::iter::once;
19-
use std::iter::FromIterator;
2019
use std::ops::Range;
2120
use std::sync::atomic::{AtomicBool, Ordering};
2221
use std::sync::Arc;
@@ -125,8 +124,39 @@ pub struct Miner {
125124

126125
accounts: Option<Arc<AccountProvider>>,
127126
notifiers: Notifiers,
128-
malicious_users: RwLock<HashSet<Address>>,
129-
immune_users: RwLock<HashSet<Address>>,
127+
malicious_users: Users,
128+
immune_users: Users,
129+
}
130+
131+
struct Users {
132+
users: RwLock<HashSet<Address>>,
133+
}
134+
135+
impl Users {
136+
pub fn new() -> Self {
137+
Self {
138+
users: RwLock::new(HashSet::new()),
139+
}
140+
}
141+
142+
pub fn cloned(&self) -> Vec<Address> {
143+
self.users.read().iter().map(Clone::clone).collect()
144+
}
145+
146+
pub fn contains(&self, address: &Address) -> bool {
147+
self.users.read().contains(address)
148+
}
149+
150+
pub fn insert(&self, address: Address) -> bool {
151+
self.users.write().insert(address)
152+
}
153+
154+
pub fn remove_users<'a>(&self, addresses: impl Iterator<Item = &'a Address>) {
155+
let mut users = self.users.write();
156+
for address in addresses {
157+
users.remove(address);
158+
}
159+
}
130160
}
131161

132162
struct Notifiers {
@@ -279,8 +309,8 @@ impl Miner {
279309
sealing_enabled: AtomicBool::new(true),
280310
accounts,
281311
notifiers: Notifiers::new(notifiers),
282-
malicious_users: RwLock::new(HashSet::new()),
283-
immune_users: RwLock::new(HashSet::new()),
312+
malicious_users: Users::new(),
313+
immune_users: Users::new(),
284314
}
285315
}
286316

@@ -365,7 +395,7 @@ impl Miner {
365395
let signer_public = tx.recover_public()?;
366396
let signer_address = public_to_address(&signer_public);
367397
if default_origin.is_local() {
368-
self.immune_users.write().insert(signer_address);
398+
self.immune_users.insert(signer_address);
369399
}
370400

371401
let origin = self
@@ -378,7 +408,7 @@ impl Miner {
378408
})
379409
.unwrap_or(default_origin);
380410

381-
if self.malicious_users.read().contains(&signer_address) {
411+
if self.malicious_users.contains(&signer_address) {
382412
// FIXME: just to skip, think about another way.
383413
return Ok(())
384414
}
@@ -389,7 +419,6 @@ impl Miner {
389419
if !self.is_allowed_transaction(&tx.action) {
390420
cdebug!(MINER, "Rejected transaction {:?}: {:?} is not allowed transaction", hash, tx.action);
391421
}
392-
let immune_users = self.immune_users.read();
393422
let tx = tx
394423
.verify_basic()
395424
.map_err(From::from)
@@ -400,8 +429,8 @@ impl Miner {
400429
.and_then(|_| CodeChainMachine::verify_transaction_seal(tx, &fake_header))
401430
.map_err(|e| {
402431
match e {
403-
Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => {
404-
self.malicious_users.write().insert(signer_address);
432+
Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_address) => {
433+
self.malicious_users.insert(signer_address);
405434
}
406435
_ => {}
407436
}
@@ -412,8 +441,8 @@ impl Miner {
412441
// This check goes here because verify_transaction takes SignedTransaction parameter
413442
self.engine.machine().verify_transaction(&tx, &fake_header, client, false).map_err(|e| {
414443
match e {
415-
Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => {
416-
self.malicious_users.write().insert(signer_address);
444+
Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_address) => {
445+
self.malicious_users.insert(signer_address);
417446
}
418447
_ => {}
419448
}
@@ -608,11 +637,10 @@ impl Miner {
608637
let tx_total = transactions.len();
609638
let mut invalid_tx_users = HashSet::new();
610639

611-
let immune_users = self.immune_users.read();
612640
for tx in transactions {
613641
let signer_public = tx.signer_public();
614642
let signer_address = public_to_address(&signer_public);
615-
if self.malicious_users.read().contains(&signer_address) {
643+
if self.malicious_users.contains(&signer_address) {
616644
invalid_transactions.push(tx.hash());
617645
continue
618646
}
@@ -646,9 +674,9 @@ impl Miner {
646674
.read()
647675
.is_local_transaction(hash)
648676
.expect("The tx is clearly fetched from the mempool")
649-
&& !immune_users.contains(&signer_address)
677+
&& !self.immune_users.contains(&signer_address)
650678
{
651-
self.malicious_users.write().insert(signer_address);
679+
self.malicious_users.insert(signer_address);
652680
}
653681
}
654682
_ => {}
@@ -1205,32 +1233,23 @@ impl MinerService for Miner {
12051233
}
12061234

12071235
fn get_malicious_users(&self) -> Vec<Address> {
1208-
Vec::from_iter(self.malicious_users.read().iter().map(Clone::clone))
1236+
self.malicious_users.cloned()
12091237
}
12101238

12111239
fn release_malicious_users(&self, prisoner_vec: Vec<Address>) {
1212-
let mut malicious_users = self.malicious_users.write();
1213-
for address in prisoner_vec {
1214-
malicious_users.remove(&address);
1215-
}
1240+
self.malicious_users.remove_users(prisoner_vec.iter());
12161241
}
12171242

12181243
fn imprison_malicious_users(&self, prisoner_vec: Vec<Address>) {
1219-
let mut malicious_users = self.malicious_users.write();
1220-
for address in prisoner_vec {
1221-
malicious_users.insert(address);
1222-
}
1244+
self.malicious_users.remove_users(prisoner_vec.iter());
12231245
}
12241246

12251247
fn get_immune_users(&self) -> Vec<Address> {
1226-
Vec::from_iter(self.immune_users.read().iter().map(Clone::clone))
1248+
self.immune_users.cloned()
12271249
}
12281250

12291251
fn register_immune_users(&self, immune_user_vec: Vec<Address>) {
1230-
let mut immune_users = self.immune_users.write();
1231-
for address in immune_user_vec {
1232-
immune_users.insert(address);
1233-
}
1252+
self.immune_users.remove_users(immune_user_vec.iter())
12341253
}
12351254
}
12361255

0 commit comments

Comments
 (0)