-
Notifications
You must be signed in to change notification settings - Fork 26
fix(p2p): correlate NOTIFY responses with prior requests; cap flash heights #198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 3 commits
27d94d9
bf8c16d
0bad311
1217c16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -156,7 +156,7 @@ namespace cryptonote | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (context.m_need_flash_sync) | ||||||||||||||||||||||||||||||||||
| if (context.m_need_flash_sync && context.m_requested_flash_heights.empty()) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| NOTIFY_REQUEST_BLOCK_FLASHES::request r{}; | ||||||||||||||||||||||||||||||||||
| auto curr_height = m_core.get_current_blockchain_height(); | ||||||||||||||||||||||||||||||||||
|
|
@@ -189,7 +189,15 @@ namespace cryptonote | |||||||||||||||||||||||||||||||||
| context.m_need_flash_sync = false; | ||||||||||||||||||||||||||||||||||
| if (!r.heights.empty()) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| // Cap the outbound request to the protocol object limit. A peer that enforces | ||||||||||||||||||||||||||||||||||
| // CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT (see handle_request_block_flashes) drops the | ||||||||||||||||||||||||||||||||||
| // connection on an oversized list, so never send more than the limit in one request. Heights | ||||||||||||||||||||||||||||||||||
| // beyond the cap stay flagged in m_flash_state and are re-requested when the peer next | ||||||||||||||||||||||||||||||||||
| // advertises a changed flash set. | ||||||||||||||||||||||||||||||||||
| if (r.heights.size() > CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT) | ||||||||||||||||||||||||||||||||||
| r.heights.resize(CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT); | ||||||||||||||||||||||||||||||||||
| MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_BLOCK_FLASHES: requesting flash tx lists for " << r.heights.size() << " blocks"); | ||||||||||||||||||||||||||||||||||
| context.m_requested_flash_heights.insert(r.heights.begin(), r.heights.end()); | ||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Cap outbound flash-height requests to the same 500-item protocol limit.
Suggested fix- context.m_need_flash_sync = false;
+ bool more_flash_heights_pending = false;
+ context.m_need_flash_sync = false;
if (!r.heights.empty())
{
+ if (r.heights.size() > CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT)
+ {
+ r.heights.resize(CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT);
+ more_flash_heights_pending = true;
+ }
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_BLOCK_FLASHES: requesting flash tx lists for " << r.heights.size() << " blocks");
context.m_requested_flash_heights.insert(r.heights.begin(), r.heights.end());
+ context.m_need_flash_sync = more_flash_heights_pending;
post_notify<NOTIFY_REQUEST_BLOCK_FLASHES>(r, context);
MLOG_PEER_STATE("requesting block flashes");
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Capped the sender to match the receiver limit. Overflow heights stay flagged in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
However, the overflow is not currently guaranteed a follow-up: on the next unchanged flash advertisement, an existing A follow-up should be scheduled only after the current batch is resolved, while ensuring the next request excludes heights already in |
||||||||||||||||||||||||||||||||||
| post_notify<NOTIFY_REQUEST_BLOCK_FLASHES>(r, context); | ||||||||||||||||||||||||||||||||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||
| MLOG_PEER_STATE("requesting block flashes"); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
@@ -1218,6 +1226,15 @@ namespace cryptonote | |||||||||||||||||||||||||||||||||
| MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_GET_BLOCKS (" << arg.blocks.size() << " blocks)"); | ||||||||||||||||||||||||||||||||||
| MLOG_PEER_STATE("received blocks"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (context.m_state != cryptonote_connection_context::state_synchronizing | ||||||||||||||||||||||||||||||||||
| || !context.m_last_request_time | ||||||||||||||||||||||||||||||||||
| || context.m_requested_objects.empty()) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| LOG_ERROR_CCONTEXT("Received NOTIFY_RESPONSE_GET_BLOCKS without a pending block request, dropping connection"); | ||||||||||||||||||||||||||||||||||
| drop_connection(context, false, false); | ||||||||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| auto request_time = *context.m_last_request_time; | ||||||||||||||||||||||||||||||||||
| context.m_last_request_time.reset(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
|
@@ -2427,6 +2444,15 @@ skip: | |||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_CHAIN_ENTRY: m_block_ids.size()=" << arg.m_block_ids.size() | ||||||||||||||||||||||||||||||||||
| << ", m_start_height=" << arg.start_height << ", m_total_height=" << arg.total_height); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (context.m_state != cryptonote_connection_context::state_synchronizing | ||||||||||||||||||||||||||||||||||
| || !context.m_last_request_time | ||||||||||||||||||||||||||||||||||
| || !context.m_requested_objects.empty()) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| LOG_ERROR_CCONTEXT("Received NOTIFY_RESPONSE_CHAIN_ENTRY without a pending chain-entry request, dropping connection"); | ||||||||||||||||||||||||||||||||||
| drop_connection(context, false, false); | ||||||||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| MLOG_PEER_STATE("received chain"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| context.m_last_request_time.reset(); | ||||||||||||||||||||||||||||||||||
|
|
@@ -2500,6 +2526,14 @@ skip: | |||||||||||||||||||||||||||||||||
| int t_cryptonote_protocol_handler<t_core>::handle_request_block_flashes(int command, NOTIFY_REQUEST_BLOCK_FLASHES::request& arg, cryptonote_connection_context& context) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_BLOCK_FLASHES: heights.size()=" << arg.heights.size()); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (arg.heights.size() > CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| LOG_ERROR_CCONTEXT("Too many heights (" << arg.heights.size() << ") in NOTIFY_REQUEST_BLOCK_FLASHES, dropping connection"); | ||||||||||||||||||||||||||||||||||
| drop_connection(context, false, false); | ||||||||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| NOTIFY_RESPONSE_BLOCK_FLASHES::request r; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| r.txs = m_core.get_pool().get_mined_flashes({arg.heights.begin(), arg.heights.end()}); | ||||||||||||||||||||||||||||||||||
|
|
@@ -2514,6 +2548,14 @@ skip: | |||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_BLOCK_FLASHES: txs.size()=" << arg.txs.size()); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (context.m_requested_flash_heights.empty()) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| LOG_ERROR_CCONTEXT("Received NOTIFY_RESPONSE_BLOCK_FLASHES without a pending request, dropping connection"); | ||||||||||||||||||||||||||||||||||
| drop_connection(context, false, false); | ||||||||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| context.m_requested_flash_heights.clear(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| m_core.get_pool().keep_missing_flashes(arg.txs); | ||||||||||||||||||||||||||||||||||
| if (arg.txs.empty()) | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Re-arm flash synchronization after a capped request completes.
The cap leaves overflow heights flagged in
m_flash_state, but the current path does not guarantee a follow-up request. Afterhandle_response_block_flashes()clearsm_requested_flash_heights, an unchanged advertisement reaches theelse continuepath inprocess_payload_sync_data()and does not setm_need_flash_syncagain. Heights discovered while another request is pending can be stranded in the same way.Preserve deferred work and schedule a callback after the current response, or re-arm
m_need_flash_syncfor needed heights that are not part of the completed request.Also applies to: 192-200, 2551-2558
🤖 Prompt for AI Agents