Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit faf6f1f

Browse files
IntegralTeamseunlanlege
authored andcommitted
Merge Notifier and TransactionsPoolNotifier (#10591)
* Merge `Notifier` and `TransactionsPoolNotifier` * fix tests
1 parent 425dcd4 commit faf6f1f

File tree

8 files changed

+138
-139
lines changed

8 files changed

+138
-139
lines changed

ethcore/light/src/transaction_queue.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,23 +129,22 @@ pub enum ImportDestination {
129129
Future,
130130
}
131131

132-
type Listener = Box<Fn(&[H256]) + Send + Sync>;
133-
134132
/// Light transaction queue. See module docs for more details.
135133
#[derive(Default)]
136134
pub struct TransactionQueue {
137135
by_account: HashMap<Address, AccountTransactions>,
138136
by_hash: H256FastMap<PendingTransaction>,
139-
listeners: Vec<Listener>,
140-
tx_statuses_listeners: Vec<mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>>,
137+
pending_listeners: Vec<mpsc::UnboundedSender<Arc<Vec<H256>>>>,
138+
full_listeners: Vec<mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>>,
141139
}
142140

143141
impl fmt::Debug for TransactionQueue {
144142
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
145143
fmt.debug_struct("TransactionQueue")
146144
.field("by_account", &self.by_account)
147145
.field("by_hash", &self.by_hash)
148-
.field("listeners", &self.listeners.len())
146+
.field("pending_listeners", &self.pending_listeners.len())
147+
.field("full_listeners", &self.pending_listeners.len())
149148
.finish()
150149
}
151150
}
@@ -360,30 +359,40 @@ impl TransactionQueue {
360359
}
361360

362361
/// Add a transaction queue listener.
363-
pub fn add_listener(&mut self, f: Listener) {
364-
self.listeners.push(f);
362+
pub fn pending_transactions_receiver(&mut self) -> mpsc::UnboundedReceiver<Arc<Vec<H256>>> {
363+
let (sender, receiver) = mpsc::unbounded();
364+
self.pending_listeners.push(sender);
365+
receiver
365366
}
366367

367368
/// Add a transaction queue listener.
368-
pub fn tx_statuses_receiver(&mut self) -> mpsc::UnboundedReceiver<Arc<Vec<(H256, TxStatus)>>> {
369+
pub fn full_transactions_receiver(&mut self) -> mpsc::UnboundedReceiver<Arc<Vec<(H256, TxStatus)>>> {
369370
let (sender, receiver) = mpsc::unbounded();
370-
self.tx_statuses_listeners.push(sender);
371+
self.full_listeners.push(sender);
371372
receiver
372373
}
373374

374375
/// Notifies all listeners about new pending transaction.
375376
fn notify(&mut self, hashes: &[H256], status: TxStatus) {
376-
for listener in &self.listeners {
377-
listener(hashes)
377+
if status == TxStatus::Added {
378+
let to_pending_send: Arc<Vec<H256>> = Arc::new(
379+
hashes
380+
.into_iter()
381+
.map(|hash| hash.clone())
382+
.collect()
383+
);
384+
self.pending_listeners.retain(|listener| listener.unbounded_send(to_pending_send.clone()).is_ok());
385+
378386
}
379387

380-
let to_send: Arc<Vec<(H256, TxStatus)>> = Arc::new(
388+
let to_full_send: Arc<Vec<(H256, TxStatus)>> = Arc::new(
381389
hashes
382390
.into_iter()
383-
.map(|hash| (hash.clone(), status)).collect()
391+
.map(|hash| (hash.clone(), status))
392+
.collect()
384393
);
385394

386-
self.tx_statuses_listeners.retain(| listener| listener.unbounded_send(to_send.clone()).is_ok());
395+
self.full_listeners.retain(|listener| listener.unbounded_send(to_full_send.clone()).is_ok());
387396
}
388397
}
389398

ethcore/src/miner/miner.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,14 +260,16 @@ impl Miner {
260260
}
261261

262262
/// Set a callback to be notified about imported transactions' hashes.
263-
pub fn add_transactions_listener(&self, f: Box<Fn(&[H256]) + Send + Sync>) {
264-
self.transaction_queue.add_listener(f);
263+
pub fn pending_transactions_receiver(&self) -> mpsc::UnboundedReceiver<Arc<Vec<H256>>> {
264+
let (sender, receiver) = mpsc::unbounded();
265+
self.transaction_queue.add_pending_listener(sender);
266+
receiver
265267
}
266268

267-
/// Set a callback to be notified
268-
pub fn tx_pool_receiver(&self) -> mpsc::UnboundedReceiver<Arc<Vec<(H256, TxStatus)>>> {
269+
/// Set a callback to be notified about imported transactions' hashes.
270+
pub fn full_transactions_receiver(&self) -> mpsc::UnboundedReceiver<Arc<Vec<(H256, TxStatus)>>> {
269271
let (sender, receiver) = mpsc::unbounded();
270-
self.transaction_queue.add_tx_pool_listener(sender);
272+
self.transaction_queue.add_full_listener(sender);
271273
receiver
272274
}
273275

miner/src/pool/listener.rs

Lines changed: 37 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -26,50 +26,6 @@ use txpool::{self, VerifiedTransaction};
2626
use pool::VerifiedTransaction as Transaction;
2727
use pool::TxStatus;
2828

29-
type Listener = Box<Fn(&[H256]) + Send + Sync>;
30-
31-
/// Manages notifications to pending transaction listeners.
32-
#[derive(Default)]
33-
pub struct Notifier {
34-
listeners: Vec<Listener>,
35-
pending: Vec<H256>,
36-
}
37-
38-
impl fmt::Debug for Notifier {
39-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
40-
fmt.debug_struct("Notifier")
41-
.field("listeners", &self.listeners.len())
42-
.field("pending", &self.pending)
43-
.finish()
44-
}
45-
}
46-
47-
impl Notifier {
48-
/// Add new listener to receive notifications.
49-
pub fn add(&mut self, f: Listener) {
50-
self.listeners.push(f)
51-
}
52-
53-
/// Notify listeners about all currently pending transactions.
54-
pub fn notify(&mut self) {
55-
if self.pending.is_empty() {
56-
return;
57-
}
58-
59-
for l in &self.listeners {
60-
(l)(&self.pending);
61-
}
62-
63-
self.pending.clear();
64-
}
65-
}
66-
67-
impl txpool::Listener<Transaction> for Notifier {
68-
fn added(&mut self, tx: &Arc<Transaction>, _old: Option<&Arc<Transaction>>) {
69-
self.pending.push(*tx.hash());
70-
}
71-
}
72-
7329
/// Transaction pool logger.
7430
#[derive(Default, Debug)]
7531
pub struct Logger;
@@ -121,14 +77,20 @@ impl txpool::Listener<Transaction> for Logger {
12177
/// Transactions pool notifier
12278
#[derive(Default)]
12379
pub struct TransactionsPoolNotifier {
124-
listeners: Vec<mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>>,
80+
full_listeners: Vec<mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>>,
81+
pending_listeners: Vec<mpsc::UnboundedSender<Arc<Vec<H256>>>>,
12582
tx_statuses: Vec<(H256, TxStatus)>,
12683
}
12784

12885
impl TransactionsPoolNotifier {
129-
/// Add new listener to receive notifications.
130-
pub fn add(&mut self, f: mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>) {
131-
self.listeners.push(f);
86+
/// Add new full listener to receive notifications.
87+
pub fn add_full_listener(&mut self, f: mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>) {
88+
self.full_listeners.push(f);
89+
}
90+
91+
/// Add new pending listener to receive notifications.
92+
pub fn add_pending_listener(&mut self, f: mpsc::UnboundedSender<Arc<Vec<H256>>>) {
93+
self.pending_listeners.push(f);
13294
}
13395

13496
/// Notify listeners about all currently transactions.
@@ -137,16 +99,25 @@ impl TransactionsPoolNotifier {
13799
return;
138100
}
139101

140-
let to_send = Arc::new(std::mem::replace(&mut self.tx_statuses, Vec::new()));
141-
self.listeners
142-
.retain(|listener| listener.unbounded_send(to_send.clone()).is_ok());
102+
let to_pending_send: Arc<Vec<H256>> = Arc::new(
103+
self.tx_statuses.clone()
104+
.into_iter()
105+
.map(|(hash, _)| hash)
106+
.collect()
107+
);
108+
self.pending_listeners.retain(|listener| listener.unbounded_send(to_pending_send.clone()).is_ok());
109+
110+
let to_full_send = Arc::new(std::mem::replace(&mut self.tx_statuses, Vec::new()));
111+
self.full_listeners
112+
.retain(|listener| listener.unbounded_send(to_full_send.clone()).is_ok());
143113
}
144114
}
145115

146116
impl fmt::Debug for TransactionsPoolNotifier {
147117
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
148118
fmt.debug_struct("TransactionsPoolNotifier")
149-
.field("listeners", &self.listeners.len())
119+
.field("full_listeners", &self.full_listeners.len())
120+
.field("pending_listeners", &self.pending_listeners.len())
150121
.finish()
151122
}
152123
}
@@ -180,33 +151,36 @@ impl txpool::Listener<Transaction> for TransactionsPoolNotifier {
180151
#[cfg(test)]
181152
mod tests {
182153
use super::*;
183-
use parking_lot::Mutex;
184154
use types::transaction;
185155
use txpool::Listener;
156+
use futures::{Stream, Future};
186157
use ethereum_types::Address;
187158

188159
#[test]
189160
fn should_notify_listeners() {
190161
// given
191-
let received = Arc::new(Mutex::new(vec![]));
192-
let r = received.clone();
193-
let listener = Box::new(move |hashes: &[H256]| {
194-
*r.lock() = hashes.iter().map(|x| *x).collect();
195-
});
162+
let (full_sender, full_receiver) = mpsc::unbounded();
163+
let (pending_sender, pending_receiver) = mpsc::unbounded();
196164

197-
let mut tx_listener = Notifier::default();
198-
tx_listener.add(listener);
165+
let mut tx_listener = TransactionsPoolNotifier::default();
166+
tx_listener.add_full_listener(full_sender);
167+
tx_listener.add_pending_listener(pending_sender);
199168

200169
// when
201170
let tx = new_tx();
202171
tx_listener.added(&tx, None);
203-
assert_eq!(*received.lock(), vec![]);
204172

205173
// then
206174
tx_listener.notify();
175+
let (full_res , _full_receiver)= full_receiver.into_future().wait().unwrap();
176+
let (pending_res , _pending_receiver)= pending_receiver.into_future().wait().unwrap();
177+
assert_eq!(
178+
full_res,
179+
Some(Arc::new(vec![(serde_json::from_str::<H256>("\"0x13aff4201ac1dc49daf6a7cf07b558ed956511acbaabf9502bdacc353953766d\"").unwrap(), TxStatus::Added)]))
180+
);
207181
assert_eq!(
208-
*received.lock(),
209-
vec!["13aff4201ac1dc49daf6a7cf07b558ed956511acbaabf9502bdacc353953766d".parse().unwrap()]
182+
pending_res,
183+
Some(Arc::new(vec![serde_json::from_str::<H256>("\"0x13aff4201ac1dc49daf6a7cf07b558ed956511acbaabf9502bdacc353953766d\"").unwrap()]))
210184
);
211185
}
212186

miner/src/pool/queue.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use pool::{
3333
};
3434
use pool::local_transactions::LocalTransactionsList;
3535

36-
type Listener = (LocalTransactionsList, (listener::Notifier, (listener::Logger, listener::TransactionsPoolNotifier)));
36+
type Listener = (LocalTransactionsList, (listener::TransactionsPoolNotifier, listener::Logger));
3737
type Pool = txpool::Pool<pool::VerifiedTransaction, scoring::NonceAndGasPrice, Listener>;
3838

3939
/// Max cache time in milliseconds for pending transactions.
@@ -305,8 +305,6 @@ impl TransactionQueue {
305305
// Notify about imported transactions.
306306
(self.pool.write().listener_mut().1).0.notify();
307307

308-
((self.pool.write().listener_mut().1).1).1.notify();
309-
310308
if results.iter().any(|r| r.is_ok()) {
311309
self.cached_pending.write().clear();
312310
}
@@ -499,7 +497,7 @@ impl TransactionQueue {
499497
/// removes them from the pool.
500498
/// That method should be used if invalid transactions are detected
501499
/// or you want to cancel a transaction.
502-
pub fn remove<'a, T: IntoIterator<Item = &'a H256>>(
500+
pub fn remove<'a, T: IntoIterator<Item=&'a H256>>(
503501
&self,
504502
hashes: T,
505503
is_invalid: bool,
@@ -571,16 +569,16 @@ impl TransactionQueue {
571569
self.pool.read().listener().0.all_transactions().iter().map(|(a, b)| (*a, b.clone())).collect()
572570
}
573571

574-
/// Add a callback to be notified about all transactions entering the pool.
575-
pub fn add_listener(&self, f: Box<Fn(&[H256]) + Send + Sync>) {
572+
/// Add a listener to be notified about all transactions the pool
573+
pub fn add_pending_listener(&self, f: mpsc::UnboundedSender<Arc<Vec<H256>>>) {
576574
let mut pool = self.pool.write();
577-
(pool.listener_mut().1).0.add(f);
575+
(pool.listener_mut().1).0.add_pending_listener(f);
578576
}
579577

580578
/// Add a listener to be notified about all transactions the pool
581-
pub fn add_tx_pool_listener(&self, f: mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>) {
579+
pub fn add_full_listener(&self, f: mpsc::UnboundedSender<Arc<Vec<(H256, TxStatus)>>>) {
582580
let mut pool = self.pool.write();
583-
((pool.listener_mut().1).1).1.add(f);
581+
(pool.listener_mut().1).0.add_full_listener(f);
584582
}
585583

586584
/// Check if pending set is cached.

parity/rpc_apis.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,9 @@ impl FullDependencies {
329329
}
330330
Api::EthPubSub => {
331331
if !for_generic_pubsub {
332+
let pool_receiver = self.miner.pending_transactions_receiver();
332333
let mut client =
333-
EthPubSubClient::new(self.client.clone(), self.executor.clone());
334+
EthPubSubClient::new(self.client.clone(), self.executor.clone(), pool_receiver);
334335
let weak_client = Arc::downgrade(&self.client);
335336

336337
client.add_sync_notifier(self.sync.sync_notification(), move |state| {
@@ -345,14 +346,6 @@ impl FullDependencies {
345346
})
346347
});
347348

348-
let h = client.handler();
349-
self.miner
350-
.add_transactions_listener(Box::new(move |hashes| {
351-
if let Some(h) = h.upgrade() {
352-
h.notify_new_transactions(hashes);
353-
}
354-
}));
355-
356349
if let Some(h) = client.handler().upgrade() {
357350
self.client.add_notify(h);
358351
}
@@ -361,7 +354,7 @@ impl FullDependencies {
361354
}
362355
Api::ParityTransactionsPool => {
363356
if !for_generic_pubsub {
364-
let receiver = self.miner.tx_pool_receiver();
357+
let receiver = self.miner.full_transactions_receiver();
365358
let client = TransactionsPoolClient::new(self.executor.clone(), receiver);
366359
handler.extend_with(TransactionsPoolClient::to_delegate(client));
367360
}
@@ -583,13 +576,16 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
583576
}
584577
}
585578
Api::EthPubSub => {
579+
let receiver = self.transaction_queue.write().pending_transactions_receiver();
580+
586581
let mut client = EthPubSubClient::light(
587582
self.client.clone(),
588583
self.on_demand.clone(),
589584
self.sync.clone(),
590585
self.cache.clone(),
591586
self.executor.clone(),
592587
self.gas_price_percentile,
588+
receiver
593589
);
594590

595591
let weak_client = Arc::downgrade(&self.client);
@@ -607,19 +603,11 @@ impl<C: LightChainClient + 'static> LightDependencies<C> {
607603
});
608604

609605
self.client.add_listener(client.handler() as Weak<_>);
610-
let h = client.handler();
611-
self.transaction_queue
612-
.write()
613-
.add_listener(Box::new(move |transactions| {
614-
if let Some(h) = h.upgrade() {
615-
h.notify_new_transactions(transactions);
616-
}
617-
}));
618606
handler.extend_with(EthPubSub::to_delegate(client));
619607
}
620608
Api::ParityTransactionsPool => {
621609
if !for_generic_pubsub {
622-
let receiver = self.transaction_queue.write().tx_statuses_receiver();
610+
let receiver = self.transaction_queue.write().full_transactions_receiver();
623611
let client = TransactionsPoolClient::new(self.executor.clone(), receiver);
624612
handler.extend_with(TransactionsPoolClient::to_delegate(client));
625613
}

0 commit comments

Comments
 (0)