Limit the number of transactions in pending set (#8777)
* Unordered iterator. * Use unordered and limited set if full not required. * Split timeout work into smaller timers. * Avoid collecting all pending transactions when mining * Remove println. * Use priority ordering in eth-filter. * Fix ethcore-miner tests and tx propagation. * Review grumbles addressed. * Add test for unordered not populating the cache. * Fix ethcore tests. * Fix light tests. * Fix ethcore-sync tests. * Fix RPC tests.
This commit is contained in:
committed by
Marek Kotewicz
parent
4817b94d0b
commit
4938d5dde5
@@ -359,6 +359,10 @@ impl SyncProvider for EthSync {
|
||||
}
|
||||
}
|
||||
|
||||
const PEERS_TIMER: TimerToken = 0;
|
||||
const SYNC_TIMER: TimerToken = 1;
|
||||
const TX_TIMER: TimerToken = 2;
|
||||
|
||||
struct SyncProtocolHandler {
|
||||
/// Shared blockchain client.
|
||||
chain: Arc<BlockChainClient>,
|
||||
@@ -373,7 +377,9 @@ struct SyncProtocolHandler {
|
||||
impl NetworkProtocolHandler for SyncProtocolHandler {
|
||||
fn initialize(&self, io: &NetworkContext) {
|
||||
if io.subprotocol_name() != WARP_SYNC_PROTOCOL_ID {
|
||||
io.register_timer(0, Duration::from_secs(1)).expect("Error registering sync timer");
|
||||
io.register_timer(PEERS_TIMER, Duration::from_millis(700)).expect("Error registering peers timer");
|
||||
io.register_timer(SYNC_TIMER, Duration::from_millis(1100)).expect("Error registering sync timer");
|
||||
io.register_timer(TX_TIMER, Duration::from_millis(1300)).expect("Error registering transactions timer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,12 +405,17 @@ impl NetworkProtocolHandler for SyncProtocolHandler {
|
||||
}
|
||||
}
|
||||
|
||||
fn timeout(&self, io: &NetworkContext, _timer: TimerToken) {
|
||||
fn timeout(&self, io: &NetworkContext, timer: TimerToken) {
|
||||
trace_time!("sync::timeout");
|
||||
let mut io = NetSyncIo::new(io, &*self.chain, &*self.snapshot_service, &self.overlay);
|
||||
self.sync.write().maintain_peers(&mut io);
|
||||
self.sync.write().maintain_sync(&mut io);
|
||||
self.sync.write().propagate_new_transactions(&mut io);
|
||||
match timer {
|
||||
PEERS_TIMER => self.sync.write().maintain_peers(&mut io),
|
||||
SYNC_TIMER => self.sync.write().maintain_sync(&mut io),
|
||||
TX_TIMER => {
|
||||
self.sync.write().propagate_new_transactions(&mut io);
|
||||
},
|
||||
_ => warn!("Unknown timer {} triggered.", timer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,10 @@ const MAX_NEW_HASHES: usize = 64;
|
||||
const MAX_NEW_BLOCK_AGE: BlockNumber = 20;
|
||||
// maximal packet size with transactions (cannot be greater than 16MB - protocol limitation).
|
||||
const MAX_TRANSACTION_PACKET_SIZE: usize = 8 * 1024 * 1024;
|
||||
// Maximal number of transactions queried from miner to propagate.
|
||||
// This set is used to diff with transactions known by the peer and
|
||||
// we will send a difference of length up to `MAX_TRANSACTIONS_TO_PROPAGATE`.
|
||||
const MAX_TRANSACTIONS_TO_QUERY: usize = 4096;
|
||||
// Maximal number of transactions in sent in single packet.
|
||||
const MAX_TRANSACTIONS_TO_PROPAGATE: usize = 64;
|
||||
// Min number of blocks to be behind for a snapshot sync
|
||||
@@ -1143,7 +1147,7 @@ pub mod tests {
|
||||
use super::{PeerInfo, PeerAsking};
|
||||
use ethcore::header::*;
|
||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient, ChainInfo, BlockInfo};
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::miner::{MinerService, PendingOrdering};
|
||||
use private_tx::NoopPrivateTxHandler;
|
||||
|
||||
pub fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes {
|
||||
@@ -1355,7 +1359,7 @@ pub mod tests {
|
||||
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
||||
io.chain.miner.chain_new_blocks(io.chain, &[], &[], &[], &good_blocks, false);
|
||||
sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks, &[], &[]);
|
||||
assert_eq!(io.chain.miner.ready_transactions(io.chain).len(), 1);
|
||||
assert_eq!(io.chain.miner.ready_transactions(io.chain, 10, PendingOrdering::Priority).len(), 1);
|
||||
}
|
||||
// We need to update nonce status (because we say that the block has been imported)
|
||||
for h in &[good_blocks[0]] {
|
||||
@@ -1371,7 +1375,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
// then
|
||||
assert_eq!(client.miner.ready_transactions(&client).len(), 1);
|
||||
assert_eq!(client.miner.ready_transactions(&client, 10, PendingOrdering::Priority).len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -33,6 +33,7 @@ use super::{
|
||||
MAX_PEERS_PROPAGATION,
|
||||
MAX_TRANSACTION_PACKET_SIZE,
|
||||
MAX_TRANSACTIONS_TO_PROPAGATE,
|
||||
MAX_TRANSACTIONS_TO_QUERY,
|
||||
MIN_PEERS_PROPAGATION,
|
||||
CONSENSUS_DATA_PACKET,
|
||||
NEW_BLOCK_HASHES_PACKET,
|
||||
@@ -114,7 +115,7 @@ impl SyncPropagator {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let transactions = io.chain().ready_transactions();
|
||||
let transactions = io.chain().ready_transactions(MAX_TRANSACTIONS_TO_QUERY);
|
||||
if transactions.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user