Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 80bc4a0

Browse files
authored
Make authorship soft deadline configurable. (#10125)
* Make soft deadline configurable. * cargo +nightly fmt --all * Move setter where it belongs.
1 parent e670c04 commit 80bc4a0

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

client/basic-authorship/src/basic_authorship.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use sp_inherents::InherentData;
4242
use sp_runtime::{
4343
generic::BlockId,
4444
traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as HeaderT},
45-
Digest,
45+
Digest, Percent, SaturatedConversion,
4646
};
4747
use std::{marker::PhantomData, pin::Pin, sync::Arc, time};
4848

@@ -58,6 +58,8 @@ use sc_proposer_metrics::MetricsLink as PrometheusMetrics;
5858
/// transferred to other nodes.
5959
pub const DEFAULT_BLOCK_SIZE_LIMIT: usize = 4 * 1024 * 1024 + 512;
6060

61+
const DEFAULT_SOFT_DEADLINE_PERCENT: Percent = Percent::from_percent(50);
62+
6163
/// [`Proposer`] factory.
6264
pub struct ProposerFactory<A, B, C, PR> {
6365
spawn_handle: Box<dyn SpawnNamed>,
@@ -72,6 +74,14 @@ pub struct ProposerFactory<A, B, C, PR> {
7274
/// If no `block_size_limit` is passed to [`sp_consensus::Proposer::propose`], this block size
7375
/// limit will be used.
7476
default_block_size_limit: usize,
77+
/// Soft deadline percentage of hard deadline.
78+
///
79+
/// The value is used to compute soft deadline during block production.
80+
/// The soft deadline indicates where we should stop attempting to add transactions
81+
/// to the block, which exhaust resources. After soft deadline is reached,
82+
/// we switch to a fixed-amount mode, in which after we see `MAX_SKIPPED_TRANSACTIONS`
83+
/// transactions which exhaust resrouces, we will conclude that the block is full.
84+
soft_deadline_percent: Percent,
7585
telemetry: Option<TelemetryHandle>,
7686
/// When estimating the block size, should the proof be included?
7787
include_proof_in_block_size_estimation: bool,
@@ -96,6 +106,7 @@ impl<A, B, C> ProposerFactory<A, B, C, DisableProofRecording> {
96106
transaction_pool,
97107
metrics: PrometheusMetrics::new(prometheus),
98108
default_block_size_limit: DEFAULT_BLOCK_SIZE_LIMIT,
109+
soft_deadline_percent: DEFAULT_SOFT_DEADLINE_PERCENT,
99110
telemetry,
100111
client,
101112
include_proof_in_block_size_estimation: false,
@@ -124,6 +135,7 @@ impl<A, B, C> ProposerFactory<A, B, C, EnableProofRecording> {
124135
transaction_pool,
125136
metrics: PrometheusMetrics::new(prometheus),
126137
default_block_size_limit: DEFAULT_BLOCK_SIZE_LIMIT,
138+
soft_deadline_percent: DEFAULT_SOFT_DEADLINE_PERCENT,
127139
telemetry,
128140
include_proof_in_block_size_estimation: true,
129141
_phantom: PhantomData,
@@ -147,6 +159,22 @@ impl<A, B, C, PR> ProposerFactory<A, B, C, PR> {
147159
pub fn set_default_block_size_limit(&mut self, limit: usize) {
148160
self.default_block_size_limit = limit;
149161
}
162+
163+
/// Set soft deadline percentage.
164+
///
165+
/// The value is used to compute soft deadline during block production.
166+
/// The soft deadline indicates where we should stop attempting to add transactions
167+
/// to the block, which exhaust resources. After soft deadline is reached,
168+
/// we switch to a fixed-amount mode, in which after we see `MAX_SKIPPED_TRANSACTIONS`
169+
/// transactions which exhaust resrouces, we will conclude that the block is full.
170+
///
171+
/// Setting the value too low will significantly limit the amount of transactions
172+
/// we try in case they exhaust resources. Setting the value too high can
173+
/// potentially open a DoS vector, where many "exhaust resources" transactions
174+
/// are being tried with no success, hence block producer ends up creating an empty block.
175+
pub fn set_soft_deadline(&mut self, percent: Percent) {
176+
self.soft_deadline_percent = percent;
177+
}
150178
}
151179

152180
impl<B, Block, C, A, PR> ProposerFactory<A, B, C, PR>
@@ -184,6 +212,7 @@ where
184212
now,
185213
metrics: self.metrics.clone(),
186214
default_block_size_limit: self.default_block_size_limit,
215+
soft_deadline_percent: self.soft_deadline_percent,
187216
telemetry: self.telemetry.clone(),
188217
_phantom: PhantomData,
189218
include_proof_in_block_size_estimation: self.include_proof_in_block_size_estimation,
@@ -229,6 +258,7 @@ pub struct Proposer<B, Block: BlockT, C, A: TransactionPool, PR> {
229258
metrics: PrometheusMetrics,
230259
default_block_size_limit: usize,
231260
include_proof_in_block_size_estimation: bool,
261+
soft_deadline_percent: Percent,
232262
telemetry: Option<TelemetryHandle>,
233263
_phantom: PhantomData<(B, PR)>,
234264
}
@@ -340,7 +370,10 @@ where
340370
// proceed with transactions
341371
// We calculate soft deadline used only in case we start skipping transactions.
342372
let now = (self.now)();
343-
let soft_deadline = now + deadline.saturating_duration_since(now) / 2;
373+
let left = deadline.saturating_duration_since(now);
374+
let left_micros: u64 = left.as_micros().saturated_into();
375+
let soft_deadline =
376+
now + time::Duration::from_micros(self.soft_deadline_percent.mul_floor(left_micros));
344377
let block_timer = time::Instant::now();
345378
let mut skipped = 0;
346379
let mut unqueue_invalid = Vec::new();

0 commit comments

Comments
 (0)