Skip to content

Commit c770aca

Browse files
gabriele-0201rphmeier
authored andcommitted
node: force block after max skipped block
1 parent f2ecc51 commit c770aca

File tree

6 files changed

+66
-5
lines changed

6 files changed

+66
-5
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk", bran
7878
sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
7979
sc-cli = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
8080
sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
81+
sc-client-db = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
8182
sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
8283
sc-executor = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
8384
sc-network = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
@@ -93,6 +94,7 @@ sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk",
9394
sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
9495
sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
9596
sp-keystore = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
97+
sp-storage = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
9698
sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
9799
substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
98100
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }

sugondat/chain/node/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ sc-basic-authorship = { workspace = true }
3737
sc-chain-spec = { workspace = true }
3838
sc-cli = { workspace = true }
3939
sc-client-api = { workspace = true }
40+
sc-client-db = { workspace = true }
4041
sc-consensus = { workspace = true }
4142
sc-executor = { workspace = true }
4243
sc-network = { workspace = true }
@@ -60,6 +61,7 @@ sp-io = { workspace = true, default-features = false }
6061
sp-inherents = { workspace = true, default-features = true }
6162
sp-runtime = { workspace = true, default-features = false }
6263
sp-session = { workspace = true, default-features = true }
64+
sp-storage = { workspace = true, default-features = true }
6365
sp-timestamp = { workspace = true }
6466
sp-transaction-pool = { workspace = true, default-features = true }
6567
substrate-frame-rpc-system = { workspace = true }

sugondat/chain/node/src/proposer.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
//! 2. There is an incoming downward message from the relay chain.
77
//! 3. There is a go-ahead signal for a parachain code upgrade.
88
//! 4. The block is the first block of the parachain. Useful for testing.
9+
//! 5. The chain is not producing blocks for more than the maximum allowed number of skipped blocks
910
//!
1011
//! If any of these conditions are met, then the block is authored.
1112
1213
use anyhow::anyhow;
14+
use parity_scale_codec::Decode;
1315

16+
use sc_client_api::backend::StorageProvider;
1417
use sc_transaction_pool_api::TransactionPool;
1518
use sp_api::StorageProof;
1619
use sp_consensus::Proposal;
@@ -30,29 +33,36 @@ use std::time::Duration;
3033
use crate::service::ParachainClient;
3134

3235
/// Proposes blocks, but only under certain conditions. See module docs.
33-
pub struct BlockLimitingProposer<P> {
36+
pub struct BlockLimitingProposer<P, C> {
3437
inner: P,
38+
client: Arc<C>,
3539
para_id: ParaId,
3640
transaction_pool: Arc<sc_transaction_pool::FullPool<Block, ParachainClient>>,
3741
}
3842

39-
impl<P> BlockLimitingProposer<P> {
43+
impl<P, C> BlockLimitingProposer<P, C> {
4044
/// Create a new block-limiting proposer.
4145
pub fn new(
4246
inner: P,
47+
client: Arc<C>,
4348
para_id: ParaId,
4449
transaction_pool: Arc<sc_transaction_pool::FullPool<Block, ParachainClient>>,
4550
) -> Self {
4651
BlockLimitingProposer {
4752
inner,
53+
client,
4854
para_id,
4955
transaction_pool,
5056
}
5157
}
5258
}
5359

5460
#[async_trait::async_trait]
55-
impl<P: ProposerInterface<Block> + Send> ProposerInterface<Block> for BlockLimitingProposer<P> {
61+
impl<P, C> ProposerInterface<Block> for BlockLimitingProposer<P, C>
62+
where
63+
P: ProposerInterface<Block> + Send,
64+
C: StorageProvider<Block, sc_client_db::Backend<Block>> + Send + Sync,
65+
{
5666
async fn propose(
5767
&mut self,
5868
parent_header: &Header,
@@ -89,8 +99,44 @@ impl<P: ProposerInterface<Block> + Send> ProposerInterface<Block> for BlockLimit
8999
// testing for detection of healthiness.
90100
parent_header.number == 0
91101
};
102+
let exceeded_max_skipped_blocks = 'max_skipped: {
103+
let maybe_last_relay_block_number = self.client.storage(
104+
parent_header.parent_hash,
105+
&sp_storage::StorageKey(sugondat_primitives::last_relay_block_number_key()),
106+
);
92107

93-
if has_downward_message || has_go_ahead || has_transactions || first_block {
108+
// If the state of the previous block or the last relay block number
109+
// is not available, to be sure of not exceeding the max amount of
110+
// skippable blocks, the block will be produced.
111+
let last_relay_block_number = match maybe_last_relay_block_number {
112+
Ok(Some(raw_data)) => match Decode::decode(&mut &raw_data.0[..]) {
113+
Ok(last_relay_block_number) => last_relay_block_number,
114+
Err(_) => break 'max_skipped true,
115+
},
116+
_ => break 'max_skipped true,
117+
};
118+
let relay_block_number = paras_inherent_data.validation_data.relay_parent_number;
119+
120+
// TODO: Change 3600 to 7200 (half a day)
121+
// and `n_skipped_blocks = relay_parent_distance.saturating_sub(1)`
122+
// when updating to asynchronous backing
123+
// https://github.com/thrumdev/blobs/issues/166
124+
125+
// The accepted error is less than 10^(-2) for an expected
126+
// maximum of 3600 skipped blocks (half a day)
127+
const MAX_SKIPPED_BLOCKS: u32 = 3600;
128+
129+
let relay_parent_distance = relay_block_number.saturating_sub(last_relay_block_number);
130+
let n_skipped_blocks = relay_parent_distance.saturating_sub(2) / 2;
131+
n_skipped_blocks >= MAX_SKIPPED_BLOCKS
132+
};
133+
134+
if has_downward_message
135+
|| has_go_ahead
136+
|| has_transactions
137+
|| first_block
138+
|| exceeded_max_skipped_blocks
139+
{
94140
self.inner
95141
.propose(
96142
parent_header,

sugondat/chain/node/src/service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ fn start_consensus(
402402

403403
let proposer = Proposer::new(proposer_factory);
404404

405-
BlockLimitingProposer::new(proposer, para_id, transaction_pool)
405+
BlockLimitingProposer::new(proposer, client.clone(), para_id, transaction_pool)
406406
};
407407

408408
let collator_service = CollatorService::new(

sugondat/chain/primitives/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,12 @@ pub enum InvalidTransactionCustomError {
5656
/// The namespace ID is invalid.
5757
InvalidNamespaceId = 101,
5858
}
59+
60+
pub fn last_relay_block_number_key() -> Vec<u8> {
61+
[
62+
sp_core::twox_128(b"ParachainSystem"),
63+
sp_core::twox_128(b"LastRelayChainBlockNumber"),
64+
]
65+
.concat()
66+
.to_vec()
67+
}

0 commit comments

Comments
 (0)