-
Notifications
You must be signed in to change notification settings - Fork 20
feat(network)!: regulate GetBlocks with paired streams #892
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
Changes from 12 commits
ac166f3
71cadad
8ed38ed
491756d
85401ce
8b920aa
7d8d386
4d953aa
23e951c
774cca4
c765f49
122c177
e9697eb
0be3f2b
a9b37a7
b9d59ac
524c347
55b87b6
7704547
5f5895f
0795f81
a2c395b
fb49019
eea1430
9c79b29
238600d
9d7bcae
b570724
1e1fd1c
44f0e7c
7abcfae
5a3e7ef
2e16d3c
547b860
fc2fd44
422d993
9ab5537
172b0b9
25347b4
e7cabd8
c624660
43c4860
79ff7c5
fbf466b
6e2216e
de030de
1ebe594
4b02b80
d9ef1df
c35d9ca
baa0414
88df92f
53ccc72
a9692e6
5d5c8ab
d2300ab
0a5ea1b
aa1d90a
0a6d564
a289325
54d0732
d916e42
30752aa
dd7f0b9
ea9f39a
11beaec
c7481f0
571ce07
7cf0d46
b80ef5f
575abf3
2fd9cac
3b8f8ca
745561b
98d6147
ea5b4cd
8e27724
953b85b
3649cbf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,6 +103,30 @@ pub const DEFAULT_BS_SIZE_DEVIATION_TOLERANCE: u32 = 200; | |
| /// only controls how many bounded body frames a server sends before `BlocksDone`. | ||
| pub const MAX_BS_RESPONSE_BYTES: u32 = DEFAULT_BS_MAX_RESPONSE_BYTES; | ||
|
|
||
| /// Fixed byte-equivalent work charged for each admitted `GetBlocks` request. | ||
| /// | ||
| /// This follows the initial peer-message regulation design. The response-byte | ||
| /// portion is refunded when unused, but this request-processing cost is not. | ||
| pub const GET_BLOCKS_REQUEST_OVERHEAD_BYTES: u64 = 64 * 1024; | ||
| /// Encoded payload bytes in either terminal GetBlocks response message. | ||
| pub const GET_BLOCKS_TERMINAL_PAYLOAD_BYTES: u64 = 9; | ||
|
|
||
| const MIB: u64 = 1024 * 1024; | ||
| const DEFAULT_GET_BLOCKS_PEER_RATE_BYTES_PER_SECOND: u64 = 128 * MIB; | ||
| // These wire caps are `u32`, so widening them to `u64` is lossless. | ||
| const DEFAULT_GET_BLOCKS_PEER_RATE_CAPACITY_BYTES: u64 = MAX_BS_RESPONSE_BYTES as u64 | ||
| + MAX_BS_BLOCKS_PER_REQUEST as u64 | ||
| + GET_BLOCKS_TERMINAL_PAYLOAD_BYTES | ||
| + GET_BLOCKS_REQUEST_OVERHEAD_BYTES; | ||
| const DEFAULT_GET_BLOCKS_PEER_OUTSTANDING_BYTES: u64 = 64 * MIB; | ||
| const DEFAULT_GET_BLOCKS_NODE_RATE_BYTES_PER_SECOND: u64 = 256 * MIB; | ||
| const DEFAULT_GET_BLOCKS_NODE_RATE_CAPACITY_BYTES: u64 = 128 * MIB; | ||
| const DEFAULT_GET_BLOCKS_NODE_OUTSTANDING_BYTES: u64 = 256 * MIB; | ||
| const DEFAULT_GET_BLOCKS_PEER_PENDING_REQUESTS: usize = 64; | ||
| const DEFAULT_GET_BLOCKS_NODE_PENDING_REQUESTS: usize = 1024; | ||
| const DEFAULT_GET_BLOCKS_NODE_ACTIVE_REQUESTS: usize = 64; | ||
| const DEFAULT_GET_BLOCKS_QUERY_TIMEOUT: Duration = Duration::from_secs(8); | ||
|
|
||
| /// Default steady-state cwnd gain, percent of the bandwidth-delay product. 300% ramps a | ||
| /// proven peer up as `1 → 3 → 9 …`; the reliability discount and delay-gradient ceiling | ||
| /// pull it back if the extra concurrency costs drops or standing queue. | ||
|
|
@@ -233,7 +257,9 @@ pub struct ZakuraBlockSyncConfig { | |
| /// Initial per-peer BBR cwnd (cold-start point), in blocks; converges to the | ||
| /// BDP-derived target once the first delivery is measured. | ||
| pub initial_inflight_requests: u32, | ||
| /// Maximum total response bytes this node advertises per `GetBlocks` response. | ||
| /// Maximum serialized block bytes this node advertises per `GetBlocks` response. | ||
| /// Must be at least [`block::MAX_BLOCK_BYTES`] so any single valid block fits. | ||
| /// Message discriminators and the response terminator are reserved separately. | ||
| pub max_response_bytes: u32, | ||
| /// Maximum estimated bytes reserved for outstanding block-body requests: a | ||
| /// DoS/pacing bound on in-flight wire data, released at receipt. Received | ||
|
|
@@ -316,6 +342,61 @@ pub struct ZakuraBlockSyncConfig { | |
| pub floor_bypass_slots: u32, | ||
| /// Block-sync peer caps and queue limits owned by this service. | ||
| pub peer_limits: ServicePeerLimits, | ||
| /// Resource policy for serving inbound `GetBlocks` requests. | ||
| pub get_blocks_regulation: GetBlocksRegulationConfig, | ||
| } | ||
|
|
||
| /// Node and peer bounds applied before GetBlocks state work starts. | ||
| /// | ||
| /// Rate budgets bound bursts and sustained work. Outstanding-byte budgets do | ||
| /// not refill; capacity returns when the last ledger, query, or result owner | ||
| /// drops, or when its queued frame leaves the application-owned transport path. | ||
| #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] | ||
| #[serde(deny_unknown_fields, default)] | ||
| pub struct GetBlocksRegulationConfig { | ||
| /// Byte-equivalent work retained for each admitted request regardless of response size. | ||
| pub request_overhead_bytes: u64, | ||
| /// Sustained byte-equivalent serving allowance for one authenticated peer. | ||
| pub peer_rate_bytes_per_second: u64, | ||
| /// Burst allowance retained across reconnects for one authenticated peer. | ||
| pub peer_rate_capacity_bytes: u64, | ||
|
czarcas7ic marked this conversation as resolved.
Outdated
|
||
| /// Reserved and queued response bytes allowed for one live peer session. | ||
| pub peer_outstanding_bytes: u64, | ||
| /// Sustained aggregate byte-equivalent serving allowance for GetBlocks. | ||
| pub node_rate_bytes_per_second: u64, | ||
| /// Aggregate GetBlocks burst allowance for this node. | ||
| pub node_rate_capacity_bytes: u64, | ||
| /// Admitted GetBlocks response bytes not yet handed off by the transport. | ||
| pub node_outstanding_bytes: u64, | ||
| /// Decoded GetBlocks requests retained while one peer waits for admission. | ||
| pub peer_pending_requests: usize, | ||
| /// Fully retained GetBlocks queue entries across all peers. A full queue | ||
| /// additionally permits one blocked decoded input per live session. | ||
| pub node_pending_requests: usize, | ||
| /// State queries and responses that may remain active across all peers. | ||
| pub node_active_requests: usize, | ||
| /// Response deadline for a state query. Timed-out reads keep their resource | ||
| /// charges until the underlying state work finishes. | ||
| #[serde(with = "humantime_serde")] | ||
| pub query_timeout: Duration, | ||
| } | ||
|
Contributor
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. one of the ideas in 747 was to reuse a lot of these logic instead of making one per message not sure if we can do this for everything but many of these seem like they could be generalized I'm biased, and not sure how feasible it is irl, but the idea of defining the message then adding and configuring the functions then and there seems nice
Contributor
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. This is now reduced to the following config: Because we might want these to differ per message.
Contributor
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. I left this unresolved because I could easily be convinced that maybe we just keep these global as well. |
||
|
|
||
| impl Default for GetBlocksRegulationConfig { | ||
| fn default() -> Self { | ||
| Self { | ||
| request_overhead_bytes: GET_BLOCKS_REQUEST_OVERHEAD_BYTES, | ||
| peer_rate_bytes_per_second: DEFAULT_GET_BLOCKS_PEER_RATE_BYTES_PER_SECOND, | ||
| peer_rate_capacity_bytes: DEFAULT_GET_BLOCKS_PEER_RATE_CAPACITY_BYTES, | ||
| peer_outstanding_bytes: DEFAULT_GET_BLOCKS_PEER_OUTSTANDING_BYTES, | ||
| node_rate_bytes_per_second: DEFAULT_GET_BLOCKS_NODE_RATE_BYTES_PER_SECOND, | ||
| node_rate_capacity_bytes: DEFAULT_GET_BLOCKS_NODE_RATE_CAPACITY_BYTES, | ||
| node_outstanding_bytes: DEFAULT_GET_BLOCKS_NODE_OUTSTANDING_BYTES, | ||
| peer_pending_requests: DEFAULT_GET_BLOCKS_PEER_PENDING_REQUESTS, | ||
| node_pending_requests: DEFAULT_GET_BLOCKS_NODE_PENDING_REQUESTS, | ||
| node_active_requests: DEFAULT_GET_BLOCKS_NODE_ACTIVE_REQUESTS, | ||
| query_timeout: DEFAULT_GET_BLOCKS_QUERY_TIMEOUT, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fn deserialize_ignored_replace_legacy_syncer<'de, D>(deserializer: D) -> Result<bool, D::Error> | ||
|
|
@@ -359,6 +440,7 @@ impl Default for ZakuraBlockSyncConfig { | |
| bbr_cwnd_unit: CwndUnit::Bytes, | ||
| floor_bypass_slots: DEFAULT_BS_FLOOR_BYPASS_SLOTS, | ||
| peer_limits: ServicePeerLimits::default(), | ||
| get_blocks_regulation: GetBlocksRegulationConfig::default(), | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -465,6 +547,7 @@ impl ZakuraBlockSyncConfig { | |
| if self.bbr_probe_rtt_interval <= self.bbr_probe_rtt_duration { | ||
| return Err("bbr_probe_rtt_interval must exceed bbr_probe_rtt_duration"); | ||
| } | ||
| super::serving_regulation::validate_config(self)?; | ||
| Ok(()) | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.