Skip to content

Commit 896fe44

Browse files
committed
Introduce Users struct in miner.rs
Users limits the lifetime of the inner lock.
1 parent 5be333d commit 896fe44

File tree

1 file changed

+52
-25
lines changed

1 file changed

+52
-25
lines changed

core/src/miner/miner.rs

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ use rlp::Encodable;
3939
use std::borrow::Borrow;
4040
use std::collections::HashSet;
4141
use std::convert::TryInto;
42-
use std::iter::FromIterator;
4342
use std::ops::Range;
4443
use std::sync::atomic::{AtomicBool, Ordering};
4544
use std::sync::Arc;
@@ -94,8 +93,46 @@ pub struct Miner {
9493
sealing_enabled: AtomicBool,
9594

9695
accounts: Arc<AccountProvider>,
97-
malicious_users: RwLock<HashSet<Public>>,
98-
immune_users: RwLock<HashSet<Public>>,
96+
malicious_users: Users,
97+
immune_users: Users,
98+
}
99+
100+
struct Users {
101+
users: RwLock<HashSet<Public>>,
102+
}
103+
104+
impl Users {
105+
pub fn new() -> Self {
106+
Self {
107+
users: RwLock::new(HashSet::new()),
108+
}
109+
}
110+
111+
pub fn cloned(&self) -> Vec<Public> {
112+
self.users.read().iter().map(Clone::clone).collect()
113+
}
114+
115+
pub fn contains(&self, public: &Public) -> bool {
116+
self.users.read().contains(public)
117+
}
118+
119+
pub fn insert(&self, public: Public) -> bool {
120+
self.users.write().insert(public)
121+
}
122+
123+
pub fn insert_users(&self, publics: impl Iterator<Item = Public>) {
124+
let mut users = self.users.write();
125+
for public in publics {
126+
users.insert(public);
127+
}
128+
}
129+
130+
pub fn remove_users<'a>(&self, publics: impl Iterator<Item = &'a Public>) {
131+
let mut users = self.users.write();
132+
for public in publics {
133+
users.remove(public);
134+
}
135+
}
99136
}
100137

101138
struct Params {
@@ -177,8 +214,8 @@ impl Miner {
177214
options,
178215
sealing_enabled: AtomicBool::new(true),
179216
accounts,
180-
malicious_users: RwLock::new(HashSet::new()),
181-
immune_users: RwLock::new(HashSet::new()),
217+
malicious_users: Users::new(),
218+
immune_users: Users::new(),
182219
}
183220
}
184221

@@ -211,7 +248,7 @@ impl Miner {
211248
// FIXME: Refactoring is needed. recover_public is calling in verify_transaction_unordered.
212249
let signer_public = tx.signer_public();
213250
if default_origin.is_local() {
214-
self.immune_users.write().insert(signer_public);
251+
self.immune_users.insert(signer_public);
215252
}
216253

217254
let origin = if self.accounts.has_account(&signer_public).unwrap_or_default() {
@@ -220,15 +257,14 @@ impl Miner {
220257
default_origin
221258
};
222259

223-
if self.malicious_users.read().contains(&signer_public) {
260+
if self.malicious_users.contains(&signer_public) {
224261
// FIXME: just to skip, think about another way.
225262
return Ok(())
226263
}
227264
if client.transaction_block(&TransactionId::Hash(hash)).is_some() {
228265
cdebug!(MINER, "Rejected transaction {:?}: already in the blockchain", hash);
229266
return Err(HistoryError::TransactionAlreadyImported.into())
230267
}
231-
let immune_users = self.immune_users.read();
232268
let tx: VerifiedTransaction = tx
233269
.verify_basic()
234270
.map_err(From::from)
@@ -239,8 +275,8 @@ impl Miner {
239275
.and_then(|_| Ok(tx.try_into()?))
240276
.map_err(|e| {
241277
match e {
242-
Error::Syntax(_) if !origin.is_local() && !immune_users.contains(&signer_public) => {
243-
self.malicious_users.write().insert(signer_public);
278+
Error::Syntax(_) if !origin.is_local() && !self.immune_users.contains(&signer_public) => {
279+
self.malicious_users.insert(signer_public);
244280
}
245281
_ => {}
246282
}
@@ -356,7 +392,7 @@ impl Miner {
356392

357393
for tx in transactions {
358394
let signer_public = tx.signer_public();
359-
if self.malicious_users.read().contains(&signer_public) {
395+
if self.malicious_users.contains(&signer_public) {
360396
invalid_transactions.push(tx.hash());
361397
continue
362398
}
@@ -730,32 +766,23 @@ impl MinerService for Miner {
730766
}
731767

732768
fn get_malicious_users(&self) -> Vec<Public> {
733-
Vec::from_iter(self.malicious_users.read().iter().map(Clone::clone))
769+
self.malicious_users.cloned()
734770
}
735771

736772
fn release_malicious_users(&self, prisoners: Vec<Public>) {
737-
let mut malicious_users = self.malicious_users.write();
738-
for prisoner in &prisoners {
739-
malicious_users.remove(prisoner);
740-
}
773+
self.malicious_users.remove_users(prisoners.iter())
741774
}
742775

743776
fn imprison_malicious_users(&self, prisoners: Vec<Public>) {
744-
let mut malicious_users = self.malicious_users.write();
745-
for prisoner in prisoners {
746-
malicious_users.insert(prisoner);
747-
}
777+
self.malicious_users.insert_users(prisoners.into_iter());
748778
}
749779

750780
fn get_immune_users(&self) -> Vec<Public> {
751-
Vec::from_iter(self.immune_users.read().iter().map(Clone::clone))
781+
self.immune_users.cloned()
752782
}
753783

754784
fn register_immune_users(&self, immune_users: Vec<Public>) {
755-
let mut immune_users_lock = self.immune_users.write();
756-
for user in immune_users {
757-
immune_users_lock.insert(user);
758-
}
785+
self.immune_users.insert_users(immune_users.into_iter())
759786
}
760787
}
761788

0 commit comments

Comments
 (0)