Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
c71487f
Support multiple blocks in `ParachainBlockData`
bkchr Oct 16, 2024
0cdb13d
Comments
bkchr Oct 16, 2024
4415530
Add a test
bkchr Oct 18, 2024
109b3f2
Only set the head on the last block
bkchr Oct 18, 2024
6f7667d
Handle versioning in collation generation
bkchr Oct 18, 2024
a8a64bc
Write tests for pov-recovery
bkchr Oct 18, 2024
3c0f51a
Use enum to be future proof
bkchr Oct 18, 2024
9dd1704
Merge branch 'master'
bkchr Oct 18, 2024
f7b2bbf
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Oct 18, 2024
e8caeb9
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Nov 6, 2024
fbf15b9
Merge remote-tracking branch 'refs/remotes/origin/master'
bkchr Nov 15, 2024
acb64ae
Use scale
bkchr Nov 15, 2024
70e7d50
Handle UMPSignals
bkchr Nov 15, 2024
91767c1
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Jan 2, 2025
aae2d2b
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Jan 31, 2025
e5277ff
Ensure the blocks match
bkchr Jan 31, 2025
8779f5f
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Mar 21, 2025
7f20108
Only one proof
bkchr Mar 21, 2025
ce343a6
Fix warnings
bkchr Mar 23, 2025
44ab288
Fix compilation errors
bkchr Mar 24, 2025
8e46176
More fixes
bkchr Mar 24, 2025
b0b041d
FMT..
bkchr Mar 24, 2025
b6cfcda
More
bkchr Mar 24, 2025
05096af
MIGHTY CLIPPY ACCEPT MY SACRIFICE
bkchr Mar 25, 2025
4c1557b
Merge branch 'master'
bkchr Mar 25, 2025
fa08898
Update from github-actions[bot] running command 'prdoc --bump major -…
github-actions[bot] Mar 25, 2025
4f5ffb3
Fix doc issue
bkchr Mar 25, 2025
99f814c
Update from github-actions[bot] running command 'fmt'
github-actions[bot] Mar 25, 2025
146f29d
Fix some issues
bkchr Mar 25, 2025
96791f5
Merge branch 'bkchr-parachain-block-data-multiple-blocks' of github.c…
bkchr Mar 25, 2025
06dba39
Fix bug
bkchr Mar 25, 2025
cedb8e2
Fix more zombienet tests
bkchr Mar 26, 2025
d79ebcf
Let's sleep longer
bkchr Mar 26, 2025
aae6db9
Use debug for logging
bkchr Mar 27, 2025
a178766
Merge branch 'master' into bkchr-parachain-block-data-multiple-blocks
bkchr Mar 27, 2025
93365e1
Merge branch 'master' into bkchr-parachain-block-data-multiple-blocks
bkchr Mar 27, 2025
f10615b
Initial support for ignoring trie nodes
bkchr Mar 27, 2025
c64ac05
Introduce `IgnoredNodes` type to hold the ignored nodes
bkchr Mar 31, 2025
9f70dac
Update cumulus/primitives/core/Cargo.toml
bkchr Mar 31, 2025
55753f4
Try to get the tests working
bkchr Mar 31, 2025
c8ec8e2
Work on the test
bkchr Apr 1, 2025
80e8b3d
Fix the test properly
bkchr Apr 2, 2025
d375bde
Extend the test
bkchr Apr 2, 2025
1d74d6b
Fix test
bkchr Apr 2, 2025
c2f867f
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Apr 3, 2025
d4904ec
Review comments
bkchr Apr 3, 2025
58ddac0
Merge branch 'master' into bkchr-parachain-block-data-multiple-blocks
bkchr Apr 4, 2025
583efc2
Make it backwards and forwards compatible
bkchr Apr 4, 2025
16d95c9
Update pr_6137.prdoc
bkchr Apr 4, 2025
80e2a82
Merge remote-tracking branch 'origin/master' into bkchr-parachain-blo…
bkchr Apr 7, 2025
a6e621d
Merge branch 'bkchr-parachain-block-data-multiple-blocks' into bkchr-…
bkchr Apr 7, 2025
a303b8c
Update cumulus/primitives/core/src/parachain_block_data.rs
bkchr Apr 7, 2025
0d78e54
Merge remote-tracking branch 'origin/bkchr-parachain-block-data-multi…
bkchr Apr 7, 2025
8becf8c
Fix compile errors
bkchr Apr 7, 2025
085944c
Merge remote-tracking branch 'origin/master' into bkchr-ignore-trie-n…
bkchr Apr 10, 2025
0ac06c5
Ensure no nodes are shared
bkchr Apr 10, 2025
e4c66ee
Take by value
bkchr Apr 11, 2025
da1cc2a
Merge remote-tracking branch 'origin/master' into bkchr-ignore-trie-n…
bkchr May 20, 2025
a1402c8
Add some test and fix the code
bkchr May 20, 2025
131f65e
Fix the test
bkchr May 28, 2025
d7daabc
Merge remote-tracking branch 'origin/master' into bkchr-ignore-trie-n…
bkchr May 28, 2025
f886c4c
Merge remote-tracking branch 'origin/master' into bkchr-ignore-trie-n…
bkchr May 29, 2025
e3d8c0a
Fix docs
bkchr Jun 1, 2025
bbd4814
Merge branch 'master' into bkchr-ignore-trie-nodes
bkchr Jun 1, 2025
0431e22
Fix tests
bkchr Jun 2, 2025
97dc073
Merge branch 'master' into bkchr-ignore-trie-nodes
bkchr Jun 6, 2025
05082c3
Merge remote-tracking branch 'origin/master' into bkchr-ignore-trie-n…
bkchr Jun 17, 2025
74b1a86
Review feedback
bkchr Jun 17, 2025
9419194
Update substrate/client/basic-authorship/src/basic_authorship.rs
bkchr Jun 18, 2025
eb49746
Review feedback
bkchr Jun 18, 2025
8d97b43
Merge remote-tracking branch 'refs/remotes/origin/bkchr-ignore-trie-n…
bkchr Jun 18, 2025
43621c0
Update from github-actions[bot] running command 'prdoc --audience nod…
github-actions[bot] Jun 18, 2025
5e26182
Update pr_8172.prdoc
bkchr Jun 18, 2025
b8ad463
Merge branch 'master' into bkchr-ignore-trie-nodes
bkchr Jun 18, 2025
e10ce1b
Merge remote-tracking branch 'origin/master' into bkchr-ignore-trie-n…
bkchr Jul 29, 2025
f9b15f7
Fix zombienet tests
bkchr Jul 30, 2025
0eeec28
This time
bkchr Jul 30, 2025
d5a1588
Update pr_8172.prdoc
bkchr Jul 30, 2025
5ecc80c
Update from github-actions[bot] running command 'fmt'
github-actions[bot] Jul 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions cumulus/client/consensus/proposer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ async-trait = { workspace = true }
thiserror = { workspace = true }

# Substrate
sc-basic-authorship = { workspace = true }
sc-block-builder = { workspace = true }
sc-transaction-pool-api = { workspace = true }
sp-api = { workspace = true, default-features = true }
sp-blockchain = { workspace = true, default-features = true }
sp-consensus = { workspace = true, default-features = true }
sp-inherents = { workspace = true, default-features = true }
sp-runtime = { workspace = true, default-features = true }
Expand Down
52 changes: 23 additions & 29 deletions cumulus/client/consensus/proposer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <https://www.gnu.org/licenses/>.

//! The Cumulus [`Proposer`] is a wrapper around a Substrate [`sp_consensus::Environment`]
//! The Cumulus [`ProposerInterface`] is an extension of the Substrate [`ProposerFactory`]
//! for creating new parachain blocks.
//!
//! This utility is designed to be composed within any collator consensus algorithm.

use async_trait::async_trait;

use sp_consensus::{EnableProofRecording, Environment, Proposal, Proposer as SubstrateProposer};
use cumulus_primitives_parachain_inherent::ParachainInherentData;
use sc_basic_authorship::{ProposeArgs, ProposerFactory};
use sc_block_builder::BlockBuilderApi;
use sc_transaction_pool_api::TransactionPool;
use sp_api::{ApiExt, CallApiAt, ProvideRuntimeApi};
use sp_blockchain::HeaderBackend;
use sp_consensus::{EnableProofRecording, Environment, Proposal};
use sp_inherents::{InherentData, InherentDataProvider};
use sp_runtime::{traits::Block as BlockT, Digest};
use sp_state_machine::StorageProof;

use cumulus_primitives_parachain_inherent::ParachainInherentData;
use std::{fmt::Debug, time::Duration};

/// Errors that can occur when proposing a parachain block.
Expand All @@ -50,7 +53,7 @@ impl Error {
}

/// A type alias for easily referring to the type of a proposal produced by a specific
/// [`Proposer`].
/// [`ProposerInterface`].
pub type ProposalOf<B> = Proposal<B, StorageProof>;

/// An interface for proposers.
Expand Down Expand Up @@ -80,39 +83,24 @@ pub trait ProposerInterface<Block: BlockT> {
) -> Result<Option<Proposal<Block, StorageProof>>, Error>;
}

/// A simple wrapper around a Substrate proposer for creating collations.
pub struct Proposer<B, T> {
inner: T,
_marker: std::marker::PhantomData<B>,
}

impl<B, T> Proposer<B, T> {
/// Create a new Cumulus [`Proposer`].
pub fn new(inner: T) -> Self {
Proposer { inner, _marker: std::marker::PhantomData }
}
}

#[async_trait]
impl<B, T> ProposerInterface<B> for Proposer<B, T>
impl<Block, A, C> ProposerInterface<Block> for ProposerFactory<A, C, EnableProofRecording>
where
B: sp_runtime::traits::Block,
T: Environment<B> + Send,
T::Error: Send + Sync + 'static,
T::Proposer: SubstrateProposer<B, ProofRecording = EnableProofRecording, Proof = StorageProof>,
<T::Proposer as SubstrateProposer<B>>::Error: Send + Sync + 'static,
A: TransactionPool<Block = Block> + 'static,
C: HeaderBackend<Block> + ProvideRuntimeApi<Block> + CallApiAt<Block> + Send + Sync + 'static,
C::Api: ApiExt<Block> + BlockBuilderApi<Block>,
Block: sp_runtime::traits::Block,
{
async fn propose(
&mut self,
parent_header: &B::Header,
parent_header: &Block::Header,
paras_inherent_data: &ParachainInherentData,
other_inherent_data: InherentData,
inherent_digests: Digest,
max_duration: Duration,
block_size_limit: Option<usize>,
) -> Result<Option<Proposal<B, StorageProof>>, Error> {
) -> Result<Option<Proposal<Block, StorageProof>>, Error> {
let proposer = self
.inner
.init(parent_header)
.await
.map_err(|e| Error::proposer_creation(anyhow::Error::new(e)))?;
Expand All @@ -124,7 +112,13 @@ where
.map_err(|e| Error::proposing(anyhow::Error::new(e)))?;

proposer
.propose(inherent_data, inherent_digests, max_duration, block_size_limit)
.propose_block(ProposeArgs {
inherent_data,
inherent_digests,
max_duration,
block_size_limit,
ignored_nodes_by_proof_recording: None,
})
.await
.map(Some)
.map_err(|e| Error::proposing(anyhow::Error::new(e)).into())
Expand Down
3 changes: 2 additions & 1 deletion cumulus/pallets/parachain-system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ trie-standardmap = { workspace = true }


# Substrate
sc-consensus = { workspace = true }
sp-api = { workspace = true, default-features = true }
sp-consensus-slots = { workspace = true, default-features = true }
sp-crypto-hashing = { workspace = true, default-features = true }
sp-keyring = { workspace = true, default-features = true }
sp-tracing = { workspace = true, default-features = true }
sp-version = { workspace = true, default-features = true }

# Cumulus
cumulus-test-client = { workspace = true }
cumulus-test-relay-sproof-builder = { workspace = true, default-features = true }
Expand Down
100 changes: 62 additions & 38 deletions cumulus/pallets/parachain-system/src/validate_block/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,32 @@
//! The actual implementation of the validate block functionality.

use super::{trie_cache, trie_recorder, MemoryOptimizedValidationParams};
use crate::parachain_inherent::BasicParachainInherentData;
use cumulus_primitives_core::{
relay_chain::Hash as RHash, ParachainBlockData, PersistedValidationData,
};

use polkadot_parachain_primitives::primitives::{
HeadData, RelayChainBlockNumber, ValidationResult,
};

use crate::{parachain_inherent::BasicParachainInherentData, ClaimQueueOffset, CoreSelector};
use alloc::vec::Vec;
use codec::{Decode, Encode};

use cumulus_primitives_core::relay_chain::vstaging::{UMPSignal, UMP_SEPARATOR};
use cumulus_primitives_core::{
relay_chain::{
vstaging::{UMPSignal, UMP_SEPARATOR},
Hash as RHash,
},
ParachainBlockData, PersistedValidationData,
};
use frame_support::{
traits::{ExecuteBlock, Get, IsSubType},
BoundedVec,
};
use polkadot_parachain_primitives::primitives::{
HeadData, RelayChainBlockNumber, ValidationResult,
};
use sp_core::storage::{ChildInfo, StateVersion};
use sp_externalities::{set_and_run_with_externalities, Externalities};
use sp_io::{hashing::blake2_128, KillStorageResult};
use sp_runtime::traits::{
Block as BlockT, ExtrinsicCall, ExtrinsicLike, HashingFor, Header as HeaderT,
Block as BlockT, ExtrinsicCall, ExtrinsicLike, Hash as HashT, HashingFor, Header as HeaderT,
};

use sp_state_machine::OverlayedChanges;
use sp_trie::ProofSizeProvider;
use trie_recorder::SizeOnlyRecorderProvider;
use sp_trie::{HashDBT, ProofSizeProvider, EMPTY_PREFIX};
use trie_recorder::{SeenNodes, SizeOnlyRecorderProvider};

type Ext<'a, Block, Backend> = sp_state_machine::Ext<'a, HashingFor<Block>, Backend>;

Expand Down Expand Up @@ -174,37 +173,40 @@ where
let num_blocks = blocks.len();

// Create the db
let db = match proof.to_memory_db(Some(parent_header.state_root())) {
let mut db = match proof.to_memory_db(Some(parent_header.state_root())) {
Ok((db, _)) => db,
Err(_) => panic!("Compact proof decoding failure."),
};

core::mem::drop(proof);

let cache_provider = trie_cache::CacheProvider::new();
// We use the storage root of the `parent_head` to ensure that it is the correct root.
// This is already being done above while creating the in-memory db, but let's be paranoid!!
let backend = sp_state_machine::TrieBackendBuilder::new_with_cache(
db,
*parent_header.state_root(),
cache_provider,
)
.build();

// We use the same recorder when executing all blocks. So, each node only contributes once to
// the total size of the storage proof. This recorder should only be used for `execute_block`.
let mut execute_recorder = SizeOnlyRecorderProvider::default();
// `backend` with the `execute_recorder`. As the `execute_recorder`, this should only be used
// for `execute_block`.
let execute_backend = sp_state_machine::TrieBackendBuilder::wrap(&backend)
.with_recorder(execute_recorder.clone())
let seen_nodes = SeenNodes::<HashingFor<B>>::default();

for (block_index, block) in blocks.into_iter().enumerate() {
// We use the storage root of the `parent_head` to ensure that it is the correct root.
// This is already being done above while creating the in-memory db, but let's be paranoid!!
let backend = sp_state_machine::TrieBackendBuilder::new_with_cache(
&db,
*parent_header.state_root(),
&cache_provider,
)
.build();

// We let all blocks contribute to the same overlay. Data written by a previous block will be
// directly accessible without going to the db.
let mut overlay = OverlayedChanges::default();
// We use the same recorder when executing all blocks. So, each node only contributes once
// to the total size of the storage proof. This recorder should only be used for
// `execute_block`.
let mut execute_recorder = SizeOnlyRecorderProvider::with_seen_nodes(seen_nodes.clone());
// `backend` with the `execute_recorder`. As the `execute_recorder`, this should only be
// used for `execute_block`.
let execute_backend = sp_state_machine::TrieBackendBuilder::wrap(&backend)
.with_recorder(execute_recorder.clone())
.build();

// We let all blocks contribute to the same overlay. Data written by a previous block will
// be directly accessible without going to the db.
let mut overlay = OverlayedChanges::default();

for (block_index, block) in blocks.into_iter().enumerate() {
parent_header = block.header().clone();
let inherent_data = extract_parachain_inherent_data(&block);

Expand Down Expand Up @@ -308,11 +310,33 @@ where
);
}
},
)
);

if block_index + 1 != num_blocks {
let mut changes = overlay
.drain_storage_changes(
&backend,
<PSC as frame_system::Config>::Version::get().state_version(),
)
.expect("Failed to get drain storage changes from the overlay.");

drop(backend);

// We just forward the changes directly to our db.
changes.transaction.drain().into_iter().for_each(|(_, (value, count))| {
// We only care about inserts and not deletes.
if count > 0 {
db.insert(EMPTY_PREFIX, &value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is up with this EMPTY_PREFIX here? I see that internally, the value is hashed for the key. Makes sense, but when would we need the prefix here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are using a HashKey, that ignores the prefix. The prefix would be important if we use a PrefixKey (this is used by changes.transaction).

In the end what is happening here is that we use the hash of value as key and EMPTY_PREFIX is ignored.


let hash = HashingFor::<B>::hash(&value);
seen_nodes.borrow_mut().insert(hash);
}
});
}
}

if !upward_message_signals.is_empty() {
let mut selected_core = None;
let mut selected_core: Option<(CoreSelector, ClaimQueueOffset)> = None;
let mut approved_peer = None;

upward_message_signals.iter().for_each(|s| {
Expand Down
Loading
Loading