Skip to content

Commit 31dbd9f

Browse files
committed
Introduce Users struct
Users limits the lifetime of the inner lock.
1 parent d3a0a8a commit 31dbd9f

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
@@ -43,7 +43,6 @@ use primitives::{Bytes, H256, U256};
4343
use std::borrow::Borrow;
4444
use std::collections::HashSet;
4545
use std::iter::once;
46-
use std::iter::FromIterator;
4746
use std::ops::Range;
4847
use std::sync::atomic::{AtomicBool, Ordering};
4948
use std::sync::Arc;
@@ -127,8 +126,39 @@ pub struct Miner {
127126

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

134164
struct Notifiers {
@@ -282,8 +312,8 @@ impl Miner {
282312
sealing_enabled: AtomicBool::new(true),
283313
accounts,
284314
notifiers: Notifiers::new(notifiers),
285-
malicious_users: RwLock::new(HashSet::new()),
286-
immune_users: RwLock::new(HashSet::new()),
315+
malicious_users: Users::new(),
316+
immune_users: Users::new(),
287317
}
288318
}
289319

@@ -368,7 +398,7 @@ impl Miner {
368398
let signer_public = tx.recover_public()?;
369399
let signer_address = public_to_address(&signer_public);
370400
if default_origin.is_local() {
371-
self.immune_users.write().insert(signer_address);
401+
self.immune_users.insert(signer_address);
372402
}
373403

374404
let origin = self
@@ -381,7 +411,7 @@ impl Miner {
381411
})
382412
.unwrap_or(default_origin);
383413

384-
if self.malicious_users.read().contains(&signer_address) {
414+
if self.malicious_users.contains(&signer_address) {
385415
// FIXME: just to skip, think about another way.
386416
return Ok(())
387417
}
@@ -392,7 +422,6 @@ impl Miner {
392422
if !self.is_allowed_transaction(&tx.action) {
393423
cdebug!(MINER, "Rejected transaction {:?}: {:?} is not allowed transaction", hash, tx.action);
394424
}
395-
let immune_users = self.immune_users.read();
396425
let tx = tx
397426
.verify_basic()
398427
.map_err(From::from)
@@ -403,8 +432,8 @@ impl Miner {
403432
.and_then(|_| CodeChainMachine::verify_transaction_seal(tx, &fake_header))
404433
.map_err(|e| {
405434
match e {
406-
Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => {
407-
self.malicious_users.write().insert(signer_address);
435+
Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_address) => {
436+
self.malicious_users.insert(signer_address);
408437
}
409438
_ => {}
410439
}
@@ -415,8 +444,8 @@ impl Miner {
415444
// This check goes here because verify_transaction takes SignedTransaction parameter
416445
self.engine.machine().verify_transaction(&tx, &fake_header, client, false).map_err(|e| {
417446
match e {
418-
Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_address) => {
419-
self.malicious_users.write().insert(signer_address);
447+
Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_address) => {
448+
self.malicious_users.insert(signer_address);
420449
}
421450
_ => {}
422451
}
@@ -609,11 +638,10 @@ impl Miner {
609638
let tx_total = transactions.len();
610639
let mut invalid_tx_users = HashSet::new();
611640

612-
let immune_users = self.immune_users.read();
613641
for tx in transactions {
614642
let signer_public = tx.signer_public();
615643
let signer_address = public_to_address(&signer_public);
616-
if self.malicious_users.read().contains(&signer_address) {
644+
if self.malicious_users.contains(&signer_address) {
617645
invalid_transactions.push(tx.hash());
618646
continue
619647
}
@@ -647,9 +675,9 @@ impl Miner {
647675
.read()
648676
.is_local_transaction(hash)
649677
.expect("The tx is clearly fetched from the mempool")
650-
&& !immune_users.contains(&signer_address)
678+
&& !self.immune_users.contains(&signer_address)
651679
{
652-
self.malicious_users.write().insert(signer_address);
680+
self.malicious_users.insert(signer_address);
653681
}
654682
}
655683
_ => {}
@@ -1188,32 +1216,23 @@ impl MinerService for Miner {
11881216
}
11891217

11901218
fn get_malicious_users(&self) -> Vec<Address> {
1191-
Vec::from_iter(self.malicious_users.read().iter().map(Clone::clone))
1219+
self.malicious_users.cloned()
11921220
}
11931221

11941222
fn release_malicious_users(&self, prisoner_vec: Vec<Address>) {
1195-
let mut malicious_users = self.malicious_users.write();
1196-
for address in prisoner_vec {
1197-
malicious_users.remove(&address);
1198-
}
1223+
self.malicious_users.remove_users(prisoner_vec.iter());
11991224
}
12001225

12011226
fn imprison_malicious_users(&self, prisoner_vec: Vec<Address>) {
1202-
let mut malicious_users = self.malicious_users.write();
1203-
for address in prisoner_vec {
1204-
malicious_users.insert(address);
1205-
}
1227+
self.malicious_users.remove_users(prisoner_vec.iter());
12061228
}
12071229

12081230
fn get_immune_users(&self) -> Vec<Address> {
1209-
Vec::from_iter(self.immune_users.read().iter().map(Clone::clone))
1231+
self.immune_users.cloned()
12101232
}
12111233

12121234
fn register_immune_users(&self, immune_user_vec: Vec<Address>) {
1213-
let mut immune_users = self.immune_users.write();
1214-
for address in immune_user_vec {
1215-
immune_users.insert(address);
1216-
}
1235+
self.immune_users.remove_users(immune_user_vec.iter())
12171236
}
12181237
}
12191238

0 commit comments

Comments
 (0)