From 1c3e2da1c50a2105c5d7f346e7b27ca8955f68b1 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Mon, 9 Sep 2024 16:27:22 +0300 Subject: [PATCH] Allow to disable gap creation during block import (#5343) This feature is helpful for us with custom sync protocol that is similar to Warp sync except we do not ever sync the gap and don't want it to exist in the first place (see https://github.com/paritytech/polkadot-sdk/issues/5333 and its references for motivation). Otherwise we had to resort to this: https://github.com/autonomys/polkadot-sdk/commit/d5375125ca7c59fcc1ac72dc1b2ac251cbc80323 --------- Co-authored-by: Davide Galassi (cherry picked from commit 030cb4a71b0b390626a586bfe7117b7c66b4700c) --- prdoc/pr_5343.prdoc | 19 +++++++++++++++++++ substrate/client/api/src/backend.rs | 3 +++ substrate/client/api/src/in_mem.rs | 2 ++ .../consensus/common/src/block_import.rs | 3 +++ substrate/client/db/src/lib.rs | 11 +++++++++-- substrate/client/service/src/client/client.rs | 3 +++ 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 prdoc/pr_5343.prdoc diff --git a/prdoc/pr_5343.prdoc b/prdoc/pr_5343.prdoc new file mode 100644 index 000000000000..3cec70de93cb --- /dev/null +++ b/prdoc/pr_5343.prdoc @@ -0,0 +1,19 @@ +title: Allow to disable gap creation during block import + +doc: + - audience: Node Dev + description: | + New property `BlockImportParams::create_gap` allows to change whether to create block gap in case block + has no parent (defaults to `true` keeping existing behavior), which is helpful for sync protocols that do not need + to sync the gap after this happens. `BlockImportOperation::create_gap()` method was also introduced, though in + most cases `BlockImportParams::create_gap` will be used. + +crates: + - name: sc-client-api + bump: major + - name: sc-consensus + bump: minor + - name: sc-client-db + bump: minor + - name: sc-service + bump: minor diff --git a/substrate/client/api/src/backend.rs b/substrate/client/api/src/backend.rs index 0b2a34952401..9c9601a912ac 100644 --- a/substrate/client/api/src/backend.rs +++ b/substrate/client/api/src/backend.rs @@ -232,6 +232,9 @@ pub trait BlockImportOperation { /// Add a transaction index operation. fn update_transaction_index(&mut self, index: Vec) -> sp_blockchain::Result<()>; + + /// Configure whether to create a block gap if newly imported block is missing parent + fn set_create_gap(&mut self, create_gap: bool); } /// Interface for performing operations on the backend. diff --git a/substrate/client/api/src/in_mem.rs b/substrate/client/api/src/in_mem.rs index ba89aede9147..c045a393bb21 100644 --- a/substrate/client/api/src/in_mem.rs +++ b/substrate/client/api/src/in_mem.rs @@ -584,6 +584,8 @@ impl backend::BlockImportOperation for BlockImportOperatio ) -> sp_blockchain::Result<()> { Ok(()) } + + fn set_create_gap(&mut self, _create_gap: bool) {} } /// In-memory backend. Keeps all states and blocks in memory. diff --git a/substrate/client/consensus/common/src/block_import.rs b/substrate/client/consensus/common/src/block_import.rs index 4d7b89f37d86..0fcf96a96368 100644 --- a/substrate/client/consensus/common/src/block_import.rs +++ b/substrate/client/consensus/common/src/block_import.rs @@ -214,6 +214,8 @@ pub struct BlockImportParams { pub fork_choice: Option, /// Re-validate existing block. pub import_existing: bool, + /// Whether to create "block gap" in case this block doesn't have parent. + pub create_gap: bool, /// Cached full header hash (with post-digests applied). pub post_hash: Option, } @@ -234,6 +236,7 @@ impl BlockImportParams { auxiliary: Vec::new(), fork_choice: None, import_existing: false, + create_gap: true, post_hash: None, } } diff --git a/substrate/client/db/src/lib.rs b/substrate/client/db/src/lib.rs index ba0cbc09d53d..83400b5ada9f 100644 --- a/substrate/client/db/src/lib.rs +++ b/substrate/client/db/src/lib.rs @@ -841,6 +841,7 @@ pub struct BlockImportOperation { finalized_blocks: Vec<(Block::Hash, Option)>, set_head: Option, commit_state: bool, + create_gap: bool, index_ops: Vec, } @@ -995,6 +996,10 @@ impl sc_client_api::backend::BlockImportOperation self.index_ops = index_ops; Ok(()) } + + fn set_create_gap(&mut self, create_gap: bool) { + self.create_gap = create_gap; + } } struct StorageDb { @@ -1707,8 +1712,9 @@ impl Backend { &(start, end).encode(), ); } - } else if number > best_num + One::one() && - number > One::one() && self.blockchain.header(parent_hash)?.is_none() + } else if operation.create_gap && + number > best_num + One::one() && + self.blockchain.header(parent_hash)?.is_none() { let gap = (best_num + One::one(), number - One::one()); transaction.set(columns::META, meta_keys::BLOCK_GAP, &gap.encode()); @@ -2060,6 +2066,7 @@ impl sc_client_api::backend::Backend for Backend { finalized_blocks: Vec::new(), set_head: None, commit_state: false, + create_gap: true, index_ops: Default::default(), }) } diff --git a/substrate/client/service/src/client/client.rs b/substrate/client/service/src/client/client.rs index 22defd7c5514..19d17a4f5488 100644 --- a/substrate/client/service/src/client/client.rs +++ b/substrate/client/service/src/client/client.rs @@ -513,6 +513,7 @@ where fork_choice, intermediates, import_existing, + create_gap, .. } = import_block; @@ -537,6 +538,8 @@ where *self.importing_block.write() = Some(hash); + operation.op.set_create_gap(create_gap); + let result = self.execute_and_import_block( operation, origin,