Skip to content

Commit

Permalink
Merge pull request #2275 from subspace/relayer_check_state_pruning
Browse files Browse the repository at this point in the history
Check if the state is available before trying to relay messages
  • Loading branch information
vedhavyas authored Nov 28, 2023
2 parents cb0f7d9 + 6e48403 commit c60cdb4
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 7 deletions.
1 change: 1 addition & 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 crates/subspace-node/src/bin/subspace-node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,10 @@ fn main() -> Result<(), Error> {
})?
.unwrap_or_default();

let consensus_state_pruning_mode = consensus_chain_config
.state_pruning
.clone()
.unwrap_or_default();
let consensus_chain_node = {
let span = sc_tracing::tracing::info_span!(
sc_tracing::logging::PREFIX_LOG_SPAN,
Expand Down Expand Up @@ -608,6 +612,7 @@ fn main() -> Result<(), Error> {
let relayer_worker =
domain_client_message_relayer::worker::relay_consensus_chain_messages(
consensus_chain_node.client.clone(),
consensus_state_pruning_mode,
consensus_chain_node.sync_service.clone(),
xdm_gossip_worker_builder.gossip_msg_sink(),
);
Expand Down
1 change: 1 addition & 0 deletions domains/client/relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cross-domain-message-gossip = { path = "../../client/cross-domain-message-gossip
futures = "0.3.29"
parity-scale-codec = { version = "3.6.5", features = ["derive"] }
sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sc-state-db = { version = "0.10.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
Expand Down
49 changes: 42 additions & 7 deletions domains/client/relayer/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{BlockT, Error, GossipMessageSink, HeaderBackend, HeaderT, Relayer, L
use futures::StreamExt;
use parity_scale_codec::FullCodec;
use sc_client_api::{AuxStore, BlockchainEvents, ProofProvider};
use sc_state_db::PruningMode;
use sp_api::{ApiError, ProvideRuntimeApi};
use sp_consensus::SyncOracle;
use sp_domains::DomainsApi;
Expand All @@ -15,6 +16,7 @@ use std::sync::Arc;
/// If the node is in major sync, worker waits waits until the sync is finished.
pub async fn relay_consensus_chain_messages<Client, Block, SO>(
consensus_chain_client: Arc<Client>,
state_pruning_mode: PruningMode,
sync_oracle: SO,
gossip_message_sink: GossipMessageSink,
) where
Expand All @@ -31,16 +33,17 @@ pub async fn relay_consensus_chain_messages<Client, Block, SO>(
// since all the relayers will haven embed client to known the canonical chain.
let result = start_relaying_messages(
NumberFor::<Block>::zero(),
consensus_chain_client,
consensus_chain_client.clone(),
|client, block_hash| {
Relayer::submit_messages_from_consensus_chain(client, block_hash, &gossip_message_sink)
},
sync_oracle,
|_, _| -> Result<bool, ApiError> {
// since we just need to provide a storage proof with the state root of Consensus chain
// proof can always be generated for any consensus chain block.
// So we can always relay messages.
Ok(true)
|_, relay_number| -> Result<bool, ApiError> {
Ok(is_state_available(
&state_pruning_mode,
&consensus_chain_client,
relay_number,
))
},
)
.await;
Expand All @@ -59,6 +62,7 @@ pub async fn relay_consensus_chain_messages<Client, Block, SO>(
pub async fn relay_domain_messages<CCC, DC, CCBlock, Block, SO>(
consensus_chain_client: Arc<CCC>,
domain_client: Arc<DC>,
domain_state_pruning: PruningMode,
sync_oracle: SO,
gossip_message_sink: GossipMessageSink,
) where
Expand Down Expand Up @@ -88,7 +92,7 @@ pub async fn relay_domain_messages<CCC, DC, CCBlock, Block, SO>(

let result = start_relaying_messages(
relay_confirmation_depth,
domain_client,
domain_client.clone(),
|client, block_hash| {
Relayer::submit_messages_from_domain(
client,
Expand All @@ -106,6 +110,11 @@ pub async fn relay_domain_messages<CCC, DC, CCBlock, Block, SO>(
)));
};

// short circuit if the domain state is unavailable to relay messages.
if !is_state_available(&domain_state_pruning, &domain_client, block_number) {
return Ok(false);
}

let api = consensus_chain_client.runtime_api();
let at = consensus_chain_client.info().best_hash;
let oldest_tracked_number = api.oldest_receipt_number(at, domain_id)?;
Expand All @@ -123,6 +132,32 @@ pub async fn relay_domain_messages<CCC, DC, CCBlock, Block, SO>(
}
}

fn is_state_available<Client, Block>(
state_pruning_mode: &PruningMode,
client: &Arc<Client>,
relay_number: NumberFor<Block>,
) -> bool
where
Block: BlockT,
Client: HeaderBackend<Block>,
{
match state_pruning_mode {
// all the state is available for archive and archive canonical.
// we can relay any message from any block
PruningMode::ArchiveAll | PruningMode::ArchiveCanonical => true,
// If the pruning mode is constrained, then check if the state is available for the `relay_number`
PruningMode::Constrained(constraints) => {
let max_blocks = NumberFor::<Block>::from(constraints.max_blocks.unwrap_or(0));
let current_best_block = client.info().best_number;
match current_best_block.checked_sub(&max_blocks) {
// we still have the state available as there was no pruning yet.
None => true,
Some(available_block_state) => relay_number >= available_block_state,
}
}
}
}

async fn start_relaying_messages<Client, Block, MP, SO, CRM>(
relay_confirmation_depth: NumberFor<Block>,
client: Arc<Client>,
Expand Down
2 changes: 2 additions & 0 deletions domains/service/src/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ where
})?;

let is_authority = domain_config.role.is_authority();
let domain_state_pruning = domain_config.state_pruning.clone().unwrap_or_default();
domain_config.rpc_id_provider = provider.rpc_id();
let rpc_builder = {
let deps = crate::rpc::FullDeps {
Expand Down Expand Up @@ -467,6 +468,7 @@ where
let relayer_worker = domain_client_message_relayer::worker::relay_domain_messages(
consensus_client.clone(),
client.clone(),
domain_state_pruning,
// domain relayer will use consensus chain sync oracle instead of domain sync orcle
// since domain sync oracle will always return `synced` due to force sync being set.
consensus_network_sync_oracle,
Expand Down

0 comments on commit c60cdb4

Please sign in to comment.