Skip to content

Commit 34341d1

Browse files
committed
Remove lock in VoteCollector
1 parent 56bacfb commit 34341d1

File tree

1 file changed

+21
-28
lines changed

1 file changed

+21
-28
lines changed

core/src/consensus/tendermint/vote_collector.rs

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use std::collections::{BTreeMap, HashMap, HashSet};
1818
use std::iter::Iterator;
1919

2020
use ckey::SchnorrSignature;
21-
use parking_lot::RwLock;
2221
use primitives::H256;
2322
use rlp::{Encodable, RlpStream};
2423

@@ -29,7 +28,7 @@ use crate::consensus::BitSet;
2928
/// Storing all Proposals, Prevotes and Precommits.
3029
#[derive(Debug)]
3130
pub struct VoteCollector {
32-
votes: RwLock<BTreeMap<VoteStep, StepCollector>>,
31+
votes: BTreeMap<VoteStep, StepCollector>,
3332
}
3433

3534
#[derive(Debug, Default)]
@@ -113,29 +112,27 @@ impl Default for VoteCollector {
113112
// Insert dummy entry to fulfill invariant: "only messages newer than the oldest are inserted".
114113
collector.insert(Default::default(), Default::default());
115114
VoteCollector {
116-
votes: RwLock::new(collector),
115+
votes: collector,
117116
}
118117
}
119118
}
120119

121120
impl VoteCollector {
122121
/// Insert vote if it is newer than the oldest one.
123-
pub fn vote(&self, message: ConsensusMessage) -> Option<DoubleVote> {
124-
self.votes.write().entry(*message.round()).or_insert_with(Default::default).insert(message)
122+
pub fn vote(&mut self, message: ConsensusMessage) -> Option<DoubleVote> {
123+
self.votes.entry(*message.round()).or_insert_with(Default::default).insert(message)
125124
}
126125

127126
/// Checks if the message should be ignored.
128127
pub fn is_old_or_known(&self, message: &ConsensusMessage) -> bool {
129-
let read_guard = self.votes.read();
130-
131-
let is_known = read_guard.get(&message.round()).map_or(false, |c| c.messages.contains(message));
128+
let is_known = self.votes.get(&message.round()).map_or(false, |c| c.messages.contains(message));
132129
if is_known {
133130
cdebug!(ENGINE, "Known message: {:?}.", message);
134131
return true
135132
}
136133

137134
// The reason not using `message.round() <= oldest` is to allow precommit messages on Commit step.
138-
let is_old = read_guard.keys().next().map_or(true, |oldest| message.round() < oldest);
135+
let is_old = self.votes.keys().next().map_or(true, |oldest| message.round() < oldest);
139136
if is_old {
140137
cdebug!(ENGINE, "Old message {:?}.", message);
141138
return true
@@ -145,11 +142,10 @@ impl VoteCollector {
145142
}
146143

147144
/// Throws out messages older than message, leaves message as marker for the oldest.
148-
pub fn throw_out_old(&self, vote_round: &VoteStep) {
149-
let mut guard = self.votes.write();
150-
let new_collector = guard.split_off(vote_round);
145+
pub fn throw_out_old(&mut self, vote_round: &VoteStep) {
146+
let new_collector = self.votes.split_off(vote_round);
151147
assert!(!new_collector.is_empty());
152-
*guard = new_collector;
148+
self.votes = new_collector;
153149
}
154150

155151
/// Collects the signatures and the indices for the given round and hash.
@@ -159,8 +155,7 @@ impl VoteCollector {
159155
round: &VoteStep,
160156
block_hash: &H256,
161157
) -> (Vec<SchnorrSignature>, Vec<usize>) {
162-
let guard = self.votes.read();
163-
guard
158+
self.votes
164159
.get(round)
165160
.and_then(|c| c.block_votes.get(&Some(*block_hash)))
166161
.map(|votes| {
@@ -173,24 +168,23 @@ impl VoteCollector {
173168

174169
/// Returns the first signature and the index of its signer for a given round and hash if exists.
175170
pub fn round_signature(&self, round: &VoteStep, block_hash: &H256) -> Option<SchnorrSignature> {
176-
let guard = self.votes.read();
177-
guard
171+
self.votes
178172
.get(round)
179173
.and_then(|c| c.block_votes.get(&Some(*block_hash)))
180174
.and_then(|votes| votes.values().next().cloned())
181175
}
182176

183177
/// Count votes which agree with the given message.
184178
pub fn aligned_votes(&self, message: &ConsensusMessage) -> BitSet {
185-
if let Some(votes) = self.votes.read().get(&message.round()) {
179+
if let Some(votes) = self.votes.get(&message.round()) {
186180
votes.count_block(&message.block_hash())
187181
} else {
188182
Default::default()
189183
}
190184
}
191185

192186
pub fn block_round_votes(&self, round: &VoteStep, block_hash: &Option<H256>) -> BitSet {
193-
if let Some(votes) = self.votes.read().get(round) {
187+
if let Some(votes) = self.votes.get(round) {
194188
votes.count_block(block_hash)
195189
} else {
196190
Default::default()
@@ -199,30 +193,29 @@ impl VoteCollector {
199193

200194
/// Count all votes collected for a given round.
201195
pub fn round_votes(&self, vote_round: &VoteStep) -> BitSet {
202-
if let Some(votes) = self.votes.read().get(vote_round) {
196+
if let Some(votes) = self.votes.get(vote_round) {
203197
votes.count()
204198
} else {
205199
Default::default()
206200
}
207201
}
208202

209203
pub fn get_block_hashes(&self, round: &VoteStep) -> Vec<H256> {
210-
let guard = self.votes.read();
211-
guard.get(round).map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect()).unwrap_or_else(Vec::new)
204+
self.votes
205+
.get(round)
206+
.map(|c| c.block_votes.keys().cloned().filter_map(|x| x).collect())
207+
.unwrap_or_else(Vec::new)
212208
}
213209

214210
pub fn get_all(&self) -> Vec<ConsensusMessage> {
215-
self.votes.read().iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect()
211+
self.votes.iter().flat_map(|(_round, collector)| collector.messages.iter()).cloned().collect()
216212
}
217213

218214
pub fn get_all_votes_in_round(&self, round: &VoteStep) -> Vec<ConsensusMessage> {
219-
let guard = self.votes.read();
220-
let c = guard.get(round);
221-
c.map(|c| c.messages.iter().cloned().collect()).unwrap_or_default()
215+
self.votes.get(round).map(|c| c.messages.iter().cloned().collect()).unwrap_or_default()
222216
}
223217

224218
pub fn get_all_votes_and_indices_in_round(&self, round: &VoteStep) -> Vec<(usize, ConsensusMessage)> {
225-
let guard = self.votes.read();
226-
guard.get(round).map(|c| c.voted.iter().map(|(k, v)| (*k, v.clone())).collect()).unwrap_or_default()
219+
self.votes.get(round).map(|c| c.voted.iter().map(|(k, v)| (*k, v.clone())).collect()).unwrap_or_default()
227220
}
228221
}

0 commit comments

Comments
 (0)