mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-23 06:05:40 +00:00
Fix crash of synced parachain node run with --sync=warp (#3523)
Fixes https://github.com/paritytech/polkadot-sdk/issues/3496.
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
title: Fix crash of synced parachain node run with `--sync=warp`
|
||||||
|
|
||||||
|
doc:
|
||||||
|
- audience: Node Operator
|
||||||
|
description: |
|
||||||
|
Fix crash of `SyncingEngine` when an already synced parachain node is run with `--sync=warp`
|
||||||
|
(issue https://github.com/paritytech/polkadot-sdk/issues/3496).
|
||||||
|
The issue manifests itself by errors in the logs:
|
||||||
|
```
|
||||||
|
[Parachain] Cannot set warp sync target block: no warp sync strategy is active.
|
||||||
|
[Parachain] Failed to set warp sync target block header, terminating `SyncingEngine`.
|
||||||
|
```
|
||||||
|
Followed by a stream of messages:
|
||||||
|
```
|
||||||
|
[Parachain] Protocol command streams have been shut down
|
||||||
|
```
|
||||||
|
|
||||||
|
crates:
|
||||||
|
- name: sc-network-sync
|
||||||
@@ -656,6 +656,8 @@ where
|
|||||||
Some(event) => self.process_notification_event(event),
|
Some(event) => self.process_notification_event(event),
|
||||||
None => return,
|
None => return,
|
||||||
},
|
},
|
||||||
|
// TODO: setting of warp sync target block should be moved to the initialization of
|
||||||
|
// `SyncingEngine`, see https://github.com/paritytech/polkadot-sdk/issues/3537.
|
||||||
warp_target_block_header = &mut self.warp_sync_target_block_header_rx_fused => {
|
warp_target_block_header = &mut self.warp_sync_target_block_header_rx_fused => {
|
||||||
if let Err(_) = self.pass_warp_sync_target_block_header(warp_target_block_header) {
|
if let Err(_) = self.pass_warp_sync_target_block_header(warp_target_block_header) {
|
||||||
error!(
|
error!(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use chain_sync::{ChainSync, ChainSyncAction, ChainSyncMode};
|
use chain_sync::{ChainSync, ChainSyncAction, ChainSyncMode};
|
||||||
use libp2p::PeerId;
|
use libp2p::PeerId;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info, warn};
|
||||||
use prometheus_endpoint::Registry;
|
use prometheus_endpoint::Registry;
|
||||||
use sc_client_api::{BlockBackend, ProofProvider};
|
use sc_client_api::{BlockBackend, ProofProvider};
|
||||||
use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock};
|
use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock};
|
||||||
@@ -159,7 +159,7 @@ impl<B: BlockT> From<ChainSyncAction<B>> for SyncingAction<B> {
|
|||||||
|
|
||||||
/// Proxy to specific syncing strategies.
|
/// Proxy to specific syncing strategies.
|
||||||
pub struct SyncingStrategy<B: BlockT, Client> {
|
pub struct SyncingStrategy<B: BlockT, Client> {
|
||||||
/// Syncing configuration.
|
/// Initial syncing configuration.
|
||||||
config: SyncingConfig,
|
config: SyncingConfig,
|
||||||
/// Client used by syncing strategies.
|
/// Client used by syncing strategies.
|
||||||
client: Arc<Client>,
|
client: Arc<Client>,
|
||||||
@@ -466,15 +466,27 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
target_header: B::Header,
|
target_header: B::Header,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
match self.warp {
|
match self.config.mode {
|
||||||
Some(ref mut warp) => {
|
SyncMode::Warp => match self.warp {
|
||||||
warp.set_target_block(target_header);
|
Some(ref mut warp) => {
|
||||||
Ok(())
|
warp.set_target_block(target_header);
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
// As mode is set to warp sync, but no warp sync strategy is active, this means
|
||||||
|
// that warp sync has already finished / was skipped.
|
||||||
|
warn!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"Discarding warp sync target, as warp sync was seemingly skipped due \
|
||||||
|
to node being (partially) synced.",
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
},
|
},
|
||||||
None => {
|
_ => {
|
||||||
error!(
|
error!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Cannot set warp sync target block: no warp sync strategy is active."
|
"Cannot set warp sync target block: not in warp sync mode."
|
||||||
);
|
);
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
Err(())
|
Err(())
|
||||||
@@ -587,3 +599,63 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use futures::executor::block_on;
|
||||||
|
use sc_block_builder::BlockBuilderBuilder;
|
||||||
|
use substrate_test_runtime_client::{
|
||||||
|
ClientBlockImportExt, ClientExt, DefaultTestClientBuilderExt, TestClientBuilder,
|
||||||
|
TestClientBuilderExt,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Regression test for crash when starting already synced parachain node with `--sync=warp`.
|
||||||
|
/// We must remove this after setting of warp sync target block is moved to initialization of
|
||||||
|
/// `SyncingEngine` (issue https://github.com/paritytech/polkadot-sdk/issues/3537).
|
||||||
|
#[test]
|
||||||
|
fn set_target_block_finished_warp_sync() {
|
||||||
|
// Populate database with finalized state.
|
||||||
|
let mut client = Arc::new(TestClientBuilder::new().build());
|
||||||
|
let block = BlockBuilderBuilder::new(&*client)
|
||||||
|
.on_parent_block(client.chain_info().best_hash)
|
||||||
|
.with_parent_block_number(client.chain_info().best_number)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block;
|
||||||
|
block_on(client.import(BlockOrigin::Own, block.clone())).unwrap();
|
||||||
|
let just = (*b"TEST", Vec::new());
|
||||||
|
client.finalize_block(block.hash(), Some(just)).unwrap();
|
||||||
|
let target_block = BlockBuilderBuilder::new(&*client)
|
||||||
|
.on_parent_block(client.chain_info().best_hash)
|
||||||
|
.with_parent_block_number(client.chain_info().best_number)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block;
|
||||||
|
|
||||||
|
// Initialize syncing strategy.
|
||||||
|
let config = SyncingConfig {
|
||||||
|
mode: SyncMode::Warp,
|
||||||
|
max_parallel_downloads: 3,
|
||||||
|
max_blocks_per_request: 64,
|
||||||
|
metrics_registry: None,
|
||||||
|
};
|
||||||
|
let mut strategy =
|
||||||
|
SyncingStrategy::new(config, client, Some(WarpSyncConfig::WaitForTarget)).unwrap();
|
||||||
|
|
||||||
|
// Warp sync instantly finishes as we have finalized state in DB.
|
||||||
|
let actions = strategy.actions().unwrap();
|
||||||
|
assert_eq!(actions.len(), 1);
|
||||||
|
assert!(matches!(actions[0], SyncingAction::Finished));
|
||||||
|
assert!(strategy.warp.is_none());
|
||||||
|
|
||||||
|
// Try setting the target block. We mustn't crash.
|
||||||
|
strategy
|
||||||
|
.set_warp_sync_target_block_header(target_block.header().clone())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user