(most of) parity RPC for light client

This commit is contained in:
Robert Habermeier
2017-02-17 21:38:43 +01:00
parent 3b023c82b7
commit 9316eb4ad3
11 changed files with 587 additions and 89 deletions

View File

@@ -322,6 +322,16 @@ impl LightProtocol {
.map(|peer| peer.lock().status.clone())
}
/// Get number of (connected, active) peers.
pub fn peer_count(&self) -> (usize, usize) {
let num_pending = self.pending_peers.read().len();
let peers = self.peers.read();
(
num_pending + peers.len(),
peers.values().filter(|p| !p.lock().pending_requests.is_empty()).count(),
)
}
/// Check the maximum amount of requests of a specific type
/// which a peer would be able to serve. Returns zero if the
/// peer is unknown or has no buffer flow parameters.

View File

@@ -110,6 +110,14 @@ impl RequestSet {
pub fn collect_ids<F>(&self) -> F where F: FromIterator<ReqId> {
self.ids.keys().cloned().collect()
}
/// Number of requests in the set.
pub fn len(&self) -> usize {
self.ids.len()
}
/// Whether the set is empty.
pub fn is_empty(&self) -> bool { self.len() == 0 }
}
#[cfg(test)]

View File

@@ -245,6 +245,31 @@ impl TransactionQueue {
.collect()
}
/// Get all transactions not ready to be propagated.
/// `best_block_number` and `best_block_timestamp` are used to filter out conditionally
/// propagated transactions.
///
/// Returned transactions are batched by sender, in order of ascending nonce.
pub fn future_transactions(&self, best_block_number: u64, best_block_timestamp: u64) -> Vec<PendingTransaction> {
self.by_account.values()
.flat_map(|acct_txs| {
acct_txs.current.iter().skip_while(|tx| match tx.condition {
None => true,
Some(Condition::Number(blk_num)) => blk_num <= best_block_number,
Some(Condition::Timestamp(time)) => time <= best_block_timestamp,
}).chain(acct_txs.future.values()).map(|info| info.hash)
})
.filter_map(|hash| match self.by_hash.get(&hash) {
Some(tx) => Some(tx.clone()),
None => {
warn!(target: "txqueue", "Inconsistency detected between `by_hash` and `by_account`: {} not stored.",
hash);
None
}
})
.collect()
}
/// Addresses for which we store transactions.
pub fn queued_senders(&self) -> Vec<Address> {
self.by_account.keys().cloned().collect()
@@ -471,4 +496,22 @@ mod tests {
assert!(txq.transaction(&hash).is_none());
}
#[test]
fn future_transactions() {
let sender = Address::default();
let mut txq = TransactionQueue::default();
for i in (0..1).chain(3..10) {
let mut tx = Transaction::default();
tx.nonce = i.into();
let tx = tx.fake_sign(sender);
txq.import(tx.into()).unwrap();
}
assert_eq!(txq.future_transactions(0, 0).len(), 7);
assert_eq!(txq.next_nonce(&sender).unwrap(), 1.into());
}
}