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

Limit the number of transactions in pending set #8777

Merged
merged 18 commits into from
Jun 12, 2018
Merged

Conversation

tomusdrw
Copy link
Collaborator

@tomusdrw tomusdrw commented Jun 4, 2018

With large pools and in case the node is not --force-sealing the pending set was actually being computed in the sync thread (propagate transactions on timeout). That could cause a significant delay, since there was nothing in the cache and the pool was pretty huge, but for propagation we never needed more than 64 first transactions.

  • This PR introduces max_len argument to avoid constructing too large pending sets.
  • Additionally we introduce UnorderedIterator that can be computed faster than the priority one. This for now is only used for parity_allTransactions RPC, but in future could be used in places where we don't really care that much about strict ordering (RPC filters maybe)

CC @folsen

Partially related: #8696

@tomusdrw tomusdrw added A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust. labels Jun 4, 2018
Copy link
Contributor

@folsen folsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, have tested this on my machine to confirm it fixes the slow RPC issue with very large --tx-queue-size

@5chdn 5chdn added this to the 1.12 milestone Jun 4, 2018
Copy link
Contributor

@jimpo jimpo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not too familiar with the codebase, but LGTM overall. All comments are minor.

let tx0 = txq.import(b.tx().nonce(0).gas_price(5).new()).unwrap();
let tx1 = txq.import(b.tx().nonce(1).gas_price(5).new()).unwrap();
let tx2 = txq.import(b.tx().nonce(2).new()).unwrap();
let tx3 =txq.import(b.tx().nonce(3).gas_price(4).new()).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Space after =.

// gap
txq.import(b.tx().sender(1).nonce(5).new()).unwrap();

let tx9 = txq.import(b.tx().sender(2).nonce(0).new()).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit odd that this is tx9 (no gap in tx numbering), whereas there's a gap in numbering between tx3 and tx5.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because tx3 and tx5 are coming from the same sender and tx9 is from a different one.

I guess tx1_1 would be a bit more appropriate to describe all the details. Can change it if you believe it makes things clearer.

@@ -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 sync timer");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/sync/peers/ in the expect message

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 sync 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 sync timer");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expect message should be changed probably.

@@ -261,15 +280,27 @@ impl TransactionQueue {
scoring::NonceAndGasPrice,
Listener,
>) -> T,
{
debug!(target: "txqueue", "Re-computing pending set for block: {}", block_number);
let _timer = ::trace_time::PerfTimer::new("pool::collect_pending");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to use the trace_time! macro?

return pending;
}

let pending: Vec<_> = self.collect_pending(client, block_number, current_timestamp, nonce_cap, |i| i.collect());
// In case we don't have a cached set, but we don't care about order
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to test this case, and assert unordered results and that the cache is left alone.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test added.

Copy link
Collaborator

@debris debris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with the context, but LGTM

@debris debris added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Jun 5, 2018
@5chdn 5chdn added A7-looksgoodtestsfail 🤖 Pull request is reviewed well, but cannot be merged due to tests failing. and removed A8-looksgood 🦄 Pull request is reviewed well. labels Jun 6, 2018
@5chdn
Copy link
Contributor

5chdn commented Jun 8, 2018

Does not compile.

   Compiling parity-rpc v1.12.0 (file:///builds/parity/parity/rpc)
error[E0050]: method `ready_transactions` has 2 parameters but the declaration in trait `ethcore::miner::MinerService::ready_transactions` has 4
   --> rpc/src/v1/tests/helpers/miner_service.rs:211:42
    |
211 |     fn ready_transactions<C>(&self, _chain: &C) -> Vec<Arc<VerifiedTransaction>> {
    |                                             ^^ expected 4 parameters, found 2
    |
    = note: `ready_transactions` from trait: `fn(&Self, &C, usize, ethcore::miner::PendingOrdering) -> std::vec::Vec<std::sync::Arc<miner::pool::VerifiedTransaction>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0050`.
error: Could not compile `parity-rpc`.

@dvdplm
Copy link
Collaborator

dvdplm commented Jun 11, 2018

Does not compile.

Confirmed. And while the above is easy enough to fix (fn ready_transactions<C>(&self, _chain: &C, max_len: usize, ordering: PendingOrdering) -> Vec<Arc<VerifiedTransaction>>) there are other errors after it; they seem to stem from the TestBlockChainClient and ChainNotificationHandler not working well together anymore: the tests assume a new_transcations() method that is not available.

Also needs a ethcore = { path = "../ethcore", features = ["test-helpers"] } in Cargo.toml for test helpers to be compiled.

@debris debris added A8-looksgood 🦄 Pull request is reviewed well. and removed A7-looksgoodtestsfail 🤖 Pull request is reviewed well, but cannot be merged due to tests failing. labels Jun 12, 2018
@debris debris merged commit 4938d5d into master Jun 12, 2018
@debris debris deleted the td-txpropagation branch June 12, 2018 06:22
dvdplm added a commit that referenced this pull request Jun 12, 2018
* master:
  Tx permission contract improvement (#8400)
  Limit the number of transactions in pending set (#8777)
  Use sealing.enabled to emit eth_mining information (#8844)
  Don't allocate in expect_valid_rlp unless necessary (#8867)
  Fix Cli Return Code on --help for ethkey, ethstore & whisper (#8863)
tavakyan referenced this pull request in C4Coin/c4coin-parity Jun 14, 2018
* 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.
ordian added a commit to ordian/parity that referenced this pull request Jun 20, 2018
…rp_sync_on_light_client

* 'master' of https://github.com/paritytech/parity: (29 commits)
  Block 0 is valid in queries (openethereum#8891)
  fixed osx permissions (openethereum#8901)
  Atomic create new files with permissions to owner in ethstore (openethereum#8896)
  Add ETC Cooperative-run load balanced parity node (openethereum#8892)
  Add support for --chain tobalaba (openethereum#8870)
  fix some warns on nightly (openethereum#8889)
  Add new ovh bootnodes and fix port for foundation bootnode 3.2 (openethereum#8886)
  SecretStore: service pack 1 (openethereum#8435)
  Handle removed logs in filter changes and add geth compatibility field (openethereum#8796)
  fixed ipc leak, closes openethereum#8774 (openethereum#8876)
  scripts: remove md5 checksums (openethereum#8884)
  hardware_wallet/Ledger `Sign messages` + some refactoring (openethereum#8868)
  Check whether we need resealing in miner and unwrap has_account in account_provider (openethereum#8853)
  docker: Fix alpine build (openethereum#8878)
  Remove mac os installers etc (openethereum#8875)
  README.md: update the list of dependencies (openethereum#8864)
  Fix concurrent access to signer queue (openethereum#8854)
  Tx permission contract improvement (openethereum#8400)
  Limit the number of transactions in pending set (openethereum#8777)
  Use sealing.enabled to emit eth_mining information (openethereum#8844)
  ...
@andresilva andresilva mentioned this pull request Jul 7, 2018
12 tasks
tomusdrw added a commit that referenced this pull request Jul 12, 2018
* 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.
@tomusdrw tomusdrw mentioned this pull request Jul 13, 2018
12 tasks
5chdn added a commit that referenced this pull request Jul 17, 2018
* parity-version: stabelize 1.11

* parity-version: bump stable to 1.11.7

* Don't fetch snapshot chunks at random (#9088)

* Offload cull to IoWorker.

* 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.

* Make sure to produce full blocks.

* Update hidapi, fixes #7542 (#9108)

* docker: add cmake dependency (#9111)

* Fix miner tests.

* Revert "Make sure to produce full blocks."

This reverts commit b12d592.

* Update light client hardcoded headers (#9098)

* Insert Kovan hardcoded headers until #7690241

* Insert Kovan hardcoded headers until block 7690241

* Insert Ropsten hardcoded headers until #3612673

* Insert Mainnet hardcoded headers until block 5941249

* Make sure to produce full blocks. (#9115)

* Insert ETC (classic) hardcoded headers until block #6170625 (#9121)

* fix verification in ethcore-sync collect_blocks (#9135)

* `evm bench` fix broken dependencies (#9134)

* `evm bench` use valid dependencies

Benchmarks of the `evm` used stale versions of a couple a crates that
this commit fixes!

* fix warnings
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants