diff --git a/Cargo.lock b/Cargo.lock index b2335386b54..fdbdb3acb9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9916,6 +9916,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-domains", + "sp-domains-fraud-proof", "sp-externalities", "sp-io", "sp-messenger-host-functions", @@ -12701,6 +12702,8 @@ dependencies = [ "frame-support", "frame-system", "pallet-transaction-payment", + "parity-scale-codec", + "scale-info", "sp-core", "sp-io", "sp-runtime", @@ -12845,6 +12848,7 @@ dependencies = [ "pallet-mmr", "pallet-offences-subspace", "pallet-rewards", + "pallet-runtime-configs", "pallet-subspace", "pallet-subspace-mmr", "pallet-sudo", diff --git a/crates/pallet-domains/src/domain_registry.rs b/crates/pallet-domains/src/domain_registry.rs index f8737b961b2..f1ee5858634 100644 --- a/crates/pallet-domains/src/domain_registry.rs +++ b/crates/pallet-domains/src/domain_registry.rs @@ -26,7 +26,7 @@ use scale_info::TypeInfo; use sp_core::Get; use sp_domains::{ derive_domain_block_hash, DomainBundleLimit, DomainId, DomainsDigestItem, - DomainsTransfersTracker, OperatorAllowList, RuntimeId, RuntimeType, + DomainsTransfersTracker, OnDomainInstantiated, OperatorAllowList, RuntimeId, RuntimeType, }; use sp_runtime::traits::{CheckedAdd, Zero}; use sp_runtime::DigestItem; @@ -293,6 +293,7 @@ pub(crate) fn do_instantiate_domain( ); import_genesis_receipt::(domain_id, genesis_receipt); + T::OnDomainInstantiated::on_domain_instantiated(domain_id); frame_system::Pallet::::deposit_log(DigestItem::domain_instantiation(domain_id)); diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index f9d1a82d8c8..75dd0c5b3a5 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -207,8 +207,8 @@ mod pallet { use sp_domains::bundle_producer_election::ProofOfElectionError; use sp_domains::{ BundleDigest, ConfirmedDomainBlock, DomainBundleSubmitted, DomainId, - DomainsTransfersTracker, EpochIndex, GenesisDomain, OperatorAllowList, OperatorId, - OperatorPublicKey, RuntimeId, RuntimeObject, RuntimeType, + DomainsTransfersTracker, EpochIndex, GenesisDomain, OnDomainInstantiated, + OperatorAllowList, OperatorId, OperatorPublicKey, RuntimeId, RuntimeObject, RuntimeType, }; use sp_domains_fraud_proof::fraud_proof::FraudProof; use sp_domains_fraud_proof::InvalidTransactionCode; @@ -389,6 +389,9 @@ mod pallet { /// Post hook to notify accepted domain bundles in previous block. type DomainBundleSubmitted: DomainBundleSubmitted; + + /// A hook to call after a domain is instantiated + type OnDomainInstantiated: OnDomainInstantiated; } #[pallet::pallet] diff --git a/crates/pallet-domains/src/tests.rs b/crates/pallet-domains/src/tests.rs index c23464f7e22..731077207a0 100644 --- a/crates/pallet-domains/src/tests.rs +++ b/crates/pallet-domains/src/tests.rs @@ -290,6 +290,7 @@ impl pallet_domains::Config for Test { type BundleLongevity = BundleLongevity; type ConsensusSlotProbability = SlotProbability; type DomainBundleSubmitted = (); + type OnDomainInstantiated = (); type Balance = Balance; } diff --git a/crates/sp-domains/src/lib.rs b/crates/sp-domains/src/lib.rs index 9dd389575cc..ee4ff4fca11 100644 --- a/crates/sp-domains/src/lib.rs +++ b/crates/sp-domains/src/lib.rs @@ -1248,6 +1248,15 @@ impl DomainBundleSubmitted for () { fn domain_bundle_submitted(_domain_id: DomainId) {} } +/// A hook to call after a domain is instantiated +pub trait OnDomainInstantiated { + fn on_domain_instantiated(domain_id: DomainId); +} + +impl OnDomainInstantiated for () { + fn on_domain_instantiated(_domain_id: DomainId) {} +} + pub type ExecutionReceiptFor = ExecutionReceipt< NumberFor, ::Hash, diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 3c9c7718612..30d37cc5869 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -707,6 +707,7 @@ impl pallet_domains::Config for Runtime { type MaxInitialDomainAccounts = MaxInitialDomainAccounts; type MinInitialDomainAccountBalance = MinInitialDomainAccountBalance; type DomainBundleSubmitted = Messenger; + type OnDomainInstantiated = Messenger; type Balance = Balance; } diff --git a/domains/pallets/messenger/src/lib.rs b/domains/pallets/messenger/src/lib.rs index f2ec0221006..4227daef486 100644 --- a/domains/pallets/messenger/src/lib.rs +++ b/domains/pallets/messenger/src/lib.rs @@ -39,7 +39,7 @@ use frame_system::pallet_prelude::BlockNumberFor; pub use pallet::*; use scale_info::TypeInfo; use sp_core::U256; -use sp_domains::DomainId; +use sp_domains::{DomainAllowlistUpdates, DomainId}; use sp_messenger::messages::{ ChainId, ChannelId, CrossDomainMessage, FeeModel, Message, MessageId, Nonce, }; @@ -292,8 +292,9 @@ mod pallet { #[pallet::getter(fn chain_allowlist)] pub(super) type ChainAllowlist = StorageValue<_, BTreeSet, ValueQuery>; - /// A temporary storage to store any allowlist updates to domain. - /// Will be cleared in the next block once the previous block has a domain bundle. + /// A storage to store any allowlist updates to domain. The updates will be cleared in the next block + /// once the previous block has a domain bundle, but a empty value should be left because in the invalid + /// extrinsic root fraud proof the prover need to generate a proof-of-empty-value for the domain. #[pallet::storage] #[pallet::getter(fn domain_chain_allowlist_updates)] pub(super) type DomainChainAllowlistUpdate = @@ -1211,7 +1212,7 @@ mod pallet { pub fn domain_chains_allowlist_update( domain_id: DomainId, ) -> Option { - DomainChainAllowlistUpdate::::get(domain_id) + DomainChainAllowlistUpdate::::get(domain_id).filter(|updates| !updates.is_empty()) } pub fn domain_allow_list_update_storage_key(domain_id: DomainId) -> Vec { @@ -1251,6 +1252,20 @@ where impl sp_domains::DomainBundleSubmitted for Pallet { fn domain_bundle_submitted(domain_id: DomainId) { - DomainChainAllowlistUpdate::::remove(domain_id); + // NOTE: clear the updates leave an empty value but does not delete the value for the + // domain completely because in the invalid extrinsic root fraud proof the prover need + // to generate a proof-of-empty-value for the domain. + DomainChainAllowlistUpdate::::mutate(domain_id, |maybe_updates| { + if let Some(ref mut updates) = maybe_updates { + updates.clear(); + } + }); + } +} + +// TODO: runtime mitigation code for 3h +impl sp_domains::OnDomainInstantiated for Pallet { + fn on_domain_instantiated(domain_id: DomainId) { + DomainChainAllowlistUpdate::::insert(domain_id, DomainAllowlistUpdates::default()); } } diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 76622d5af32..55a9aa93dcd 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -741,6 +741,7 @@ impl pallet_domains::Config for Runtime { type MaxInitialDomainAccounts = MaxInitialDomainAccounts; type MinInitialDomainAccountBalance = MinInitialDomainAccountBalance; type DomainBundleSubmitted = Messenger; + type OnDomainInstantiated = Messenger; type Balance = Balance; }