tx relay v2: more improvements - #450
Conversation
cf3ae82 to
231bb48
Compare
|
Depends on monero-project#11065 for a correct max blob size check before parsing tx blobs. |
Boog900
left a comment
There was a problem hiding this comment.
These changes look great and should help the issues with tx relay v2 a lot, especially removing the locks. I think removing the bans is not great but while tx relay v2 seems unstable it's not a bad idea.
The nonce idea is also a great and cheap way to track requests.
The code looks good.
| //--------------------------------------------------------------- | ||
| bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx) | ||
| { | ||
| CHECK_AND_ASSERT_MES(tx_blob.size() <= get_max_tx_size(), false, "Tx blob too big"); |
There was a problem hiding this comment.
I think this needs the arg to ignore the limit that's on the PR here: monero-project#11065
There was a problem hiding this comment.
Yep yep, I'm just going to cherry-pick that change and build on top of it
Simple API to check max blob size before parsing. This is useful when reading blobs from untrusted sources. @selsta pointed out that coinbase txs can technically be larger than get_max_tx_size(), otherwise we could enforce it on all txs.
231bb48 to
4077247
Compare
1. Remove unnecessary locking from the functions that strictly read the db for pool txs (`tx_memory_pool::get_transaction` and `tx_memory_pool::have_tx`). 2. Don't ban peers if they miss too many tx requests (drop connection, but don't ban). 3. Implement a nonce in the p2p tx hash / tx notify messages, so that we can track exact request -> response. 4. Remove the lock synchronizing `handle_notify_new_transactions` and the 5. Request txs from peers as soon as our local capacity to accept more txs 6. Fix bugged logic in `handle_notify_tx_pool_hash` that starts the timer 7. Fix bugged logic in `handle_notify_tx_pool_hash` that could result in us attempting to request **more** than the allowed max, and thus not requesting some tx hashes correctly. 8. Use boost multi-index's `.modify()` to update elems in the `request_manager`, rather than updating the iterator in place. 9. Align fluff timer flush_time for tx relay v2.
4077247 to
777ed68
Compare
| // Add all the missing to our request queue, and then kick off the request | ||
| auto txs_req = m_request_manager.enqueue_requests(missing_tx_hashes, context.m_connection_id); | ||
| this->send_txs_request(context, std::move(txs_req)); | ||
| this->fly_available_requests_in_queue(); |
There was a problem hiding this comment.
Do we need this fly_available_requests_in_queue here? AFAICT this will only do something if the m_request_manager.remove_request(tx_hash) above is hit but, as the comment says, that should never really be hit.
Overview
We've observed a higher frequency of connection bans (and bad perf) stemming from some issues surrounding tx relay v2. See #373.
2 core issues:
Plus some other bugs contributing to the bans.
This PR aims to eliminate the most severe offending sections of code leading to these concerns.
It also introduces a new field in the p2p tx hash / tx notifier message that both request/response side would be expected to have.
Credit to @selsta and @Boog900 for collaborating on some of the items mentioned in this PR.
This PR's major changes
Remove unnecessary locking from the functions that strictly read the db for pool txs (
tx_memory_pool::get_transactionandtx_memory_pool::have_tx).handle_notify_tx_pool_hashorhandle_request_tx_pool_txs.Don't ban peers if they miss too many tx requests (drop connection, but don't ban).
Implement a nonce in the p2p tx hash / tx notify messages, so that we can track exact request -> response.
Remove the lock synchronizing
handle_notify_new_transactionsand the check tx request loop which runs in the idle loop.check_tx_request_queueloop doesn't think a tx is stale while the node is actually still verifying it alongside a larger batch of txs it received, thus kicking a node that actually already responded with the tx.processingthe tx request after parsing all the incoming tx blobs, and beforehandle_incoming_tx.processingtxs to be "stale" requests in the call toremove_stale_requests.handle_incoming_txwhich then gets expanded so it's non-const, but the benefit of not locking here seems well worth it. It also avoids locking when parsing, which does seem nice.Request txs from peers as soon as our local capacity to accept more txs from peers becomes available, rather than just in the
check_tx_request_queueloop.fly_available_requests_in_queue.remove_request.Fix bugged logic in
handle_notify_tx_pool_hashthat starts the timer while still having more db reads.Fix bugged logic in
handle_notify_tx_pool_hashthat could result in us attempting to request more than the allowed max, and thus not requesting some tx hashes after marking them in-flight.check_tx_request_queueloop.Use boost multi-index's
.modify()to update elems in therequest_manager, rather than updating the iterator in place.dont_rm_processing_txs_enqueue_overageunit test fails w/o this.modify()to handle unexpected failures, see the comment.Align fluff timer
flush_timefor tx relay v2.context.flush_timecould get continuously pushed back even if there are v2 txs sitting in queue waiting to get flushed.