Skip to content

Commit c1a80d8

Browse files
committed
node: proposer for limiting blocks
1 parent 7d87615 commit c1a80d8

File tree

5 files changed

+95
-1
lines changed

5 files changed

+95
-1
lines changed

Cargo.lock

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

sugondat-chain/node/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ build = "build.rs"
1010
license = "MIT OR Apache-2.0"
1111

1212
[dependencies]
13+
anyhow = "1.0"
14+
async-trait = "0.1.73"
1315
clap = { version = "4.4.6", features = ["derive"] }
1416
log = "0.4.17"
1517
codec = { package = "parity-scale-codec", version = "3.0.0" }
@@ -46,10 +48,12 @@ sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk",
4648
sp-api = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
4749
sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
4850
sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
51+
sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
4952
sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
5053
sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
5154
sp-keystore = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
5255
sp-io = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
56+
sp-inherents = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
5357
sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
5458
sp-session = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
5559
sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
@@ -75,6 +79,8 @@ cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/p
7579
cumulus-relay-chain-interface = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.4.0" }
7680
color-print = "0.3.4"
7781

82+
cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.4.0" }
83+
7884
[build-dependencies]
7985
substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.4.0" }
8086

sugondat-chain/node/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod chain_spec;
77
mod service;
88
mod cli;
99
mod command;
10+
mod proposer;
1011
mod rpc;
1112

1213
fn main() -> sc_cli::Result<()> {

sugondat-chain/node/src/proposer.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//! Wrapper around a proposer which only authors blocks when certain conditions are met.
2+
//!
3+
//! These conditions are:
4+
//! 1. There is at least one transaction ready to post. This is used to determine that there were
5+
//! non-inherent extrinsics and avoid authoring empty blocks.
6+
//! 2. There is an incoming downward message from the relay chain.
7+
//! 3. There is a go-ahead signal for a parachain code upgrade.
8+
//!
9+
//! If any of these conditions are met, then the block is authored.
10+
11+
use anyhow::anyhow;
12+
13+
use sc_transaction_pool_api::TransactionPool;
14+
use sp_api::StorageProof;
15+
use sp_consensus::Proposal;
16+
use sp_inherents::InherentData;
17+
use sp_runtime::generic::Digest;
18+
19+
use cumulus_client_consensus_proposer::{Error as ProposerError, ProposerInterface};
20+
use cumulus_pallet_parachain_system::relay_state_snapshot::RelayChainStateProof;
21+
use cumulus_primitives_core::ParaId;
22+
use cumulus_primitives_parachain_inherent::ParachainInherentData;
23+
24+
use sugondat_primitives::opaque::{Block, Header};
25+
26+
use std::time::Duration;
27+
use std::sync::Arc;
28+
29+
use crate::service::ParachainClient;
30+
31+
/// Proposes blocks, but only under certain conditions. See module docs.
32+
pub struct BlockLimitingProposer<P>{
33+
inner: P,
34+
para_id: ParaId,
35+
transaction_pool: Arc<sc_transaction_pool::FullPool<Block, ParachainClient>>,
36+
}
37+
38+
#[async_trait::async_trait]
39+
impl<P: ProposerInterface<Block> + Send> ProposerInterface<Block> for BlockLimitingProposer<P> {
40+
async fn propose(
41+
&mut self,
42+
parent_header: &Header,
43+
paras_inherent_data: &ParachainInherentData,
44+
other_inherent_data: InherentData,
45+
inherent_digests: Digest,
46+
max_duration: Duration,
47+
block_size_limit: Option<usize>,
48+
) -> Result<Proposal<Block, StorageProof>, ProposerError> {
49+
let has_downward_message = !paras_inherent_data.downward_messages.is_empty();
50+
let has_transactions = self.transaction_pool.status().ready > 0;
51+
let has_go_ahead = {
52+
let maybe_go_ahead = RelayChainStateProof::new(
53+
self.para_id,
54+
paras_inherent_data.validation_data.relay_parent_storage_root,
55+
paras_inherent_data.relay_chain_state.clone(),
56+
).and_then(|p| p.read_upgrade_go_ahead_signal());
57+
58+
// when we encounter errors reading the go ahead signal,
59+
// we pessimistically opt to create a block as such errors indicate
60+
// changes in the relay chain protocol and would likely persist
61+
// until something is fixed here.
62+
match maybe_go_ahead {
63+
Err(_) => true,
64+
Ok(Some(_)) => true,
65+
Ok(None) => false,
66+
}
67+
};
68+
69+
if has_downward_message || has_go_ahead || has_transactions {
70+
self.inner.propose(
71+
parent_header,
72+
paras_inherent_data,
73+
other_inherent_data,
74+
inherent_digests,
75+
max_duration,
76+
block_size_limit,
77+
).await
78+
} else {
79+
Err(ProposerError::proposing(anyhow!("no need to create a block")))
80+
}
81+
}
82+
}

sugondat-chain/node/src/service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ type HostFunctions = (
5252
frame_benchmarking::benchmarking::HostFunctions,
5353
);
5454

55-
type ParachainClient = TFullClient<Block, RuntimeApi, WasmExecutor<HostFunctions>>;
55+
pub(crate) type ParachainClient = TFullClient<Block, RuntimeApi, WasmExecutor<HostFunctions>>;
5656

5757
type ParachainBackend = TFullBackend<Block>;
5858

0 commit comments

Comments
 (0)