Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add runtime_upgrades() runtime API for DomainRuntimeUpgrades #3337

Merged
merged 6 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
6 changes: 6 additions & 0 deletions crates/pallet-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2102,11 +2102,17 @@ impl<T: Config> Pallet<T> {
Ok(HeadDomainNumber::<T>::get(domain_id) + missed_upgrade.into())
}

/// Returns the runtime ID for the supplied `domain_id`, if that domain exists.
pub fn runtime_id(domain_id: DomainId) -> Option<RuntimeId> {
DomainRegistry::<T>::get(domain_id)
.map(|domain_object| domain_object.domain_config.runtime_id)
}

/// Returns the list of runtime upgrades in the current block.
pub fn runtime_upgrades() -> Vec<RuntimeId> {
DomainRuntimeUpgrades::<T>::get()
}

pub fn domain_instance_data(
domain_id: DomainId,
) -> Option<(DomainInstanceData, BlockNumberFor<T>)> {
Expand Down
4 changes: 2 additions & 2 deletions crates/sp-domains-fraud-proof/src/fraud_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,8 @@ pub struct InvalidExtrinsicsRootProof {
/// The combined storage proofs used during verification
pub invalid_inherent_extrinsic_proofs: InvalidInherentExtrinsicDataProof,

/// Domain runtime code upgraded (or "not upgraded") storage proof
pub domain_runtime_upgraded_proof: DomainRuntimeUpgradedProof,
/// A single domain runtime code upgrade (or "not upgraded") storage proof
pub maybe_domain_runtime_upgraded_proof: MaybeDomainRuntimeUpgradedProof,

/// Storage proof for a change to the chains that are allowed to open a channel with each domain
pub domain_chain_allowlist_proof: DomainChainsAllowlistUpdateStorageProof,
Expand Down
12 changes: 8 additions & 4 deletions crates/sp-domains-fraud-proof/src/storage_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,18 @@ where
}
}

/// A proof of a single domain runtime upgrade (or that there wasn't an upgrade).
#[derive(Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo)]
pub struct DomainRuntimeUpgradedProof {
pub struct MaybeDomainRuntimeUpgradedProof {
/// A list of domain runtime upgrades for a block.
pub domain_runtime_upgrades: DomainRuntimeUpgradesProof,

/// The new domain runtime code, if the domain runtime was upgraded.
pub new_domain_runtime_code: Option<DomainRuntimeCodeProof>,
}

impl DomainRuntimeUpgradedProof {
/// Generate the `DomainRuntimeUpgradedProof`.
impl MaybeDomainRuntimeUpgradedProof {
/// Generate the `MaybeDomainRuntimeUpgradedProof`.
/// It is the caller's responsibility to check if the domain runtime is upgraded at
/// `block_hash`. If it is, the `maybe_runtime_id` should be `Some`.
#[cfg(feature = "std")]
Expand Down Expand Up @@ -324,7 +328,7 @@ impl DomainRuntimeUpgradedProof {
} else {
None
};
Ok(DomainRuntimeUpgradedProof {
Ok(MaybeDomainRuntimeUpgradedProof {
domain_runtime_upgrades,
new_domain_runtime_code,
})
Expand Down
4 changes: 2 additions & 2 deletions crates/sp-domains-fraud-proof/src/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ where
let InvalidExtrinsicsRootProof {
valid_bundle_digests,
invalid_inherent_extrinsic_proofs,
domain_runtime_upgraded_proof,
maybe_domain_runtime_upgraded_proof,
domain_chain_allowlist_proof,
domain_sudo_call_proof,
} = fraud_proof;
Expand All @@ -79,7 +79,7 @@ where
)?;

let maybe_domain_runtime_upgrade =
domain_runtime_upgraded_proof.verify::<CBlock, SKP>(runtime_id, &state_root)?;
maybe_domain_runtime_upgraded_proof.verify::<CBlock, SKP>(runtime_id, &state_root)?;

let domain_chain_allowlist = <DomainChainsAllowlistUpdateStorageProof as BasicStorageProof<
CBlock,
Expand Down
41 changes: 22 additions & 19 deletions crates/sp-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,10 +1481,10 @@ sp_api::decl_runtime_apis! {
/// Submits the transaction bundle via an unsigned extrinsic.
fn submit_bundle_unsigned(opaque_bundle: OpaqueBundle<NumberFor<Block>, Block::Hash, DomainHeader, Balance>);

// Submit singleton receipt via an unsigned extrinsic.
// Submits a singleton receipt via an unsigned extrinsic.
fn submit_receipt_unsigned(singleton_receipt: SealedSingletonReceipt<NumberFor<Block>, Block::Hash, DomainHeader, Balance>);

/// Extract the bundles stored successfully from the given extrinsics.
/// Extracts the bundles successfully stored from the given extrinsics.
fn extract_successful_bundles(
domain_id: DomainId,
extrinsics: Vec<Block::Extrinsic>,
Expand All @@ -1493,22 +1493,25 @@ sp_api::decl_runtime_apis! {
/// Generates a randomness seed for extrinsics shuffling.
fn extrinsics_shuffling_seed() -> Randomness;

/// Returns the WASM bundle for given `domain_id`.
/// Returns the current WASM bundle for the given `domain_id`.
fn domain_runtime_code(domain_id: DomainId) -> Option<Vec<u8>>;

/// Returns the runtime id for given `domain_id`.
/// Returns the runtime id for the given `domain_id`.
fn runtime_id(domain_id: DomainId) -> Option<RuntimeId>;

/// Returns the domain instance data for given `domain_id`.
/// Returns the list of runtime upgrades in the current block.
fn runtime_upgrades() -> Vec<RuntimeId>;

/// Returns the domain instance data for the given `domain_id`.
fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor<Block>)>;

/// Returns the current timestamp at given height.
/// Returns the current timestamp at the current height.
fn timestamp() -> Moment;

/// Returns the current Tx range for the given domain Id.
fn domain_tx_range(domain_id: DomainId) -> U256;

/// Return the genesis state root if not pruned
/// Returns the genesis state root if not pruned.
fn genesis_state_root(domain_id: DomainId) -> Option<H256>;

/// Returns the best execution chain number.
Expand All @@ -1523,38 +1526,38 @@ sp_api::decl_runtime_apis! {
/// Returns true if there are any ERs in the challenge period with non empty extrinsics.
fn non_empty_er_exists(domain_id: DomainId) -> bool;

/// Returns the current best number of the domain.
/// Returns the current best block number for the domain.
fn domain_best_number(domain_id: DomainId) -> Option<HeaderNumberFor<DomainHeader>>;

/// Returns the execution receipt
/// Returns the execution receipt with the given hash.
fn execution_receipt(receipt_hash: HeaderHashFor<DomainHeader>) -> Option<ExecutionReceiptFor<DomainHeader, Block, Balance>>;

/// Returns the current epoch and the next epoch operators of the given domain
/// Returns the current epoch and the next epoch operators of the given domain.
fn domain_operators(domain_id: DomainId) -> Option<(BTreeMap<OperatorId, Balance>, Vec<OperatorId>)>;

/// Returns the execution receipt hash of the given domain and domain block number
/// Returns the execution receipt hash of the given domain and domain block number.
fn receipt_hash(domain_id: DomainId, domain_number: HeaderNumberFor<DomainHeader>) -> Option<HeaderHashFor<DomainHeader>>;

/// Return the consensus chain byte fee that will used to charge the domain transaction for consensus
/// chain storage fee
/// Returns the consensus chain byte fee that will used to charge the domain transaction for consensus
/// chain storage fees.
fn consensus_chain_byte_fee() -> Balance;

/// Returns the latest confirmed domain block number and hash
/// Returns the latest confirmed domain block number and hash.
fn latest_confirmed_domain_block(domain_id: DomainId) -> Option<(HeaderNumberFor<DomainHeader>, HeaderHashFor<DomainHeader>)>;

/// Return if the receipt is exist and pending to prune
/// Returns if the receipt is exist and pending to prune
fn is_bad_er_pending_to_prune(domain_id: DomainId, receipt_hash: HeaderHashFor<DomainHeader>) -> bool;

/// Return the balance of the storage fund account
/// Returns the balance of the storage fund account.
fn storage_fund_account_balance(operator_id: OperatorId) -> Balance;

/// Return if the domain runtime code is upgraded since `at`
/// Returns true if the given domain's runtime code has been upgraded since `at`.
fn is_domain_runtime_upgraded_since(domain_id: DomainId, at: NumberFor<Block>) -> Option<bool>;

/// Return domain sudo call.
/// Returns the domain sudo calls for the given domain, if any.
fn domain_sudo_call(domain_id: DomainId) -> Option<Vec<u8>>;

/// Return last confirmed domain block execution receipt.
/// Returns the last confirmed domain block execution receipt.
fn last_confirmed_domain_block_receipt(domain_id: DomainId) ->Option<ExecutionReceiptFor<DomainHeader, Block, Balance>>;
}

Expand Down
4 changes: 4 additions & 0 deletions crates/subspace-fake-runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ sp_api::impl_runtime_apis! {
unreachable!()
}

fn runtime_upgrades() -> Vec<sp_domains::RuntimeId> {
unreachable!()
}

fn domain_instance_data(_domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor<Block>)> {
unreachable!()
}
Expand Down
4 changes: 4 additions & 0 deletions crates/subspace-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,10 @@ impl_runtime_apis! {
Domains::runtime_id(domain_id)
}

fn runtime_upgrades() -> Vec<sp_domains::RuntimeId> {
Domains::runtime_upgrades()
}

fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor<Block>)> {
Domains::domain_instance_data(domain_id)
}
Expand Down
33 changes: 6 additions & 27 deletions domains/client/block-preprocessor/src/inherents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_domains::{DomainId, DomainsApi, DomainsDigestItem};
use sp_domains::{DomainId, DomainsApi};
use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider};
use sp_messenger::MessengerApi;
use sp_runtime::traits::{Block as BlockT, Header, NumberFor};
use sp_runtime::traits::{Block as BlockT, NumberFor};
use sp_timestamp::InherentType;
use std::error::Error;
use std::sync::Arc;
Expand Down Expand Up @@ -69,25 +69,15 @@ where
CBlock: BlockT,
Block: BlockT,
{
let header = consensus_client.header(consensus_block_hash)?.ok_or(
sp_blockchain::Error::MissingHeader(format!(
"No header found for {consensus_block_hash:?}"
)),
)?;

let runtime_api = consensus_client.runtime_api();
let runtime_id = runtime_api
.runtime_id(consensus_block_hash, domain_id)?
.ok_or(sp_blockchain::Error::Application(Box::from(format!(
"No RuntimeId found for {domain_id:?}"
))))?;
let runtime_upgrades = runtime_api.runtime_upgrades(consensus_block_hash)?;

Ok(header
.digest()
.logs
.iter()
.filter_map(|log| log.as_domain_runtime_upgrade())
.any(|upgraded_runtime_id| upgraded_runtime_id == runtime_id))
Ok(runtime_upgrades.contains(&runtime_id))
}

/// Returns new upgraded runtime if upgraded did happen in the provided consensus block.
Expand All @@ -102,26 +92,15 @@ where
CBlock: BlockT,
Block: BlockT,
{
let header = consensus_client.header(consensus_block_hash)?.ok_or(
sp_blockchain::Error::MissingHeader(format!(
"No header found for {consensus_block_hash:?}"
)),
)?;

let runtime_api = consensus_client.runtime_api();
let runtime_id = runtime_api
.runtime_id(consensus_block_hash, domain_id)?
.ok_or(sp_blockchain::Error::Application(Box::from(format!(
"No RuntimeId found for {domain_id:?}"
))))?;
let runtime_upgrades = runtime_api.runtime_upgrades(consensus_block_hash)?;

if header
.digest()
.logs
.iter()
.filter_map(|log| log.as_domain_runtime_upgrade())
.any(|upgraded_runtime_id| upgraded_runtime_id == runtime_id)
{
if runtime_upgrades.contains(&runtime_id) {
let new_domain_runtime = runtime_api
.domain_runtime_code(consensus_block_hash, domain_id)?
.ok_or_else(|| {
Expand Down
22 changes: 5 additions & 17 deletions domains/client/domain-operator/src/fraud_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ use sp_domain_digests::AsPredigest;
use sp_domains::core_api::DomainCoreApi;
use sp_domains::proof_provider_and_verifier::StorageProofProvider;
use sp_domains::{
DomainId, DomainsApi, DomainsDigestItem, ExtrinsicDigest, HeaderHashingFor, InvalidBundleType,
RuntimeId,
DomainId, DomainsApi, ExtrinsicDigest, HeaderHashingFor, InvalidBundleType, RuntimeId,
};
use sp_domains_fraud_proof::execution_prover::ExecutionProver;
use sp_domains_fraud_proof::fraud_proof::{
Expand Down Expand Up @@ -389,7 +388,7 @@ where
&self.storage_key_provider,
)?;

let domain_runtime_upgraded_proof = DomainRuntimeUpgradedProof::generate(
let maybe_domain_runtime_upgraded_proof = MaybeDomainRuntimeUpgradedProof::generate(
&self.storage_key_provider,
self.consensus_client.as_ref(),
consensus_block_hash,
Expand Down Expand Up @@ -418,7 +417,7 @@ where
proof: FraudProofVariant::InvalidExtrinsicsRoot(InvalidExtrinsicsRootProof {
valid_bundle_digests,
invalid_inherent_extrinsic_proofs,
domain_runtime_upgraded_proof,
maybe_domain_runtime_upgraded_proof,
domain_chain_allowlist_proof,
domain_sudo_call_proof,
}),
Expand All @@ -432,27 +431,16 @@ where
domain_id: DomainId,
at: CBlock::Hash,
) -> Result<Option<RuntimeId>, FraudProofError> {
let header =
self.consensus_client
.header(at)?
.ok_or(sp_blockchain::Error::MissingHeader(format!(
"No header found for {at:?}"
)))?;

let runtime_id = self
.consensus_client
.runtime_api()
.runtime_id(at, domain_id)?
.ok_or(sp_blockchain::Error::Application(Box::from(format!(
"No RuntimeId found for {domain_id:?}"
))))?;
let runtime_upgrades = self.consensus_client.runtime_api().runtime_upgrades(at)?;

let is_runtime_upgraded = header
.digest()
.logs
.iter()
.filter_map(|log| log.as_domain_runtime_upgrade())
.any(|upgraded_runtime_id| upgraded_runtime_id == runtime_id);
let is_runtime_upgraded = runtime_upgrades.contains(&runtime_id);

Ok(is_runtime_upgraded.then_some(runtime_id))
}
Expand Down
4 changes: 4 additions & 0 deletions test/subspace-test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,10 @@ impl_runtime_apis! {
Domains::runtime_id(domain_id)
}

fn runtime_upgrades() -> Vec<sp_domains::RuntimeId> {
Domains::runtime_upgrades()
}

fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor<Block>)> {
Domains::domain_instance_data(domain_id)
}
Expand Down
Loading