From 0200fced71f453f22dbafbbad790b16ffbea7501 Mon Sep 17 00:00:00 2001 From: linning Date: Wed, 16 Oct 2024 20:17:00 +0800 Subject: [PATCH 1/2] Add source to the OperatorRewarded event Signed-off-by: linning --- crates/pallet-domains/src/benchmarking.rs | 15 ++++++++--- crates/pallet-domains/src/block_tree.rs | 10 +++++--- crates/pallet-domains/src/lib.rs | 22 ++++++++++++---- crates/pallet-domains/src/staking.rs | 26 ++++++++++++++----- crates/pallet-domains/src/staking_epoch.rs | 30 +++++++++++++++++----- crates/sp-domains/src/lib.rs | 10 ++++++++ crates/subspace-runtime/src/lib.rs | 11 +++++--- test/subspace-test-runtime/src/lib.rs | 10 +++++--- 8 files changed, 103 insertions(+), 31 deletions(-) diff --git a/crates/pallet-domains/src/benchmarking.rs b/crates/pallet-domains/src/benchmarking.rs index d3480ff3d5..192068a37f 100644 --- a/crates/pallet-domains/src/benchmarking.rs +++ b/crates/pallet-domains/src/benchmarking.rs @@ -28,8 +28,8 @@ use sp_core::crypto::{Ss58Codec, UncheckedFrom}; use sp_core::ByteArray; use sp_domains::{ dummy_opaque_bundle, BlockFees, DomainId, ExecutionReceipt, OperatorAllowList, OperatorId, - OperatorPublicKey, OperatorSignature, PermissionedActionAllowedBy, ProofOfElection, - RuntimeType, SealedSingletonReceipt, SingletonReceipt, Transfers, + OperatorPublicKey, OperatorRewardSource, OperatorSignature, PermissionedActionAllowedBy, + ProofOfElection, RuntimeType, SealedSingletonReceipt, SingletonReceipt, Transfers, }; use sp_domains_fraud_proof::fraud_proof::FraudProof; use sp_runtime::traits::{CheckedAdd, One, Zero}; @@ -286,6 +286,7 @@ mod benchmarks { do_reward_operators::( domain_id, + OperatorRewardSource::Dummy, operator_ids[..n as usize].to_vec().into_iter(), operator_rewards, ) @@ -337,6 +338,7 @@ mod benchmarks { do_reward_operators::( domain_id, + OperatorRewardSource::Dummy, operator_ids.clone().into_iter(), operator_rewards, ) @@ -449,8 +451,13 @@ mod benchmarks { } assert_eq!(PendingStakingOperationCount::::get(domain_id), p); - do_reward_operators::(domain_id, operator_ids.into_iter(), operator_rewards) - .expect("reward operator should success"); + do_reward_operators::( + domain_id, + OperatorRewardSource::Dummy, + operator_ids.into_iter(), + operator_rewards, + ) + .expect("reward operator should success"); let epoch_index = DomainStakingSummary::::get(domain_id) .expect("staking summary must exist") diff --git a/crates/pallet-domains/src/block_tree.rs b/crates/pallet-domains/src/block_tree.rs index d2f2f34212..02dbe764d3 100644 --- a/crates/pallet-domains/src/block_tree.rs +++ b/crates/pallet-domains/src/block_tree.rs @@ -318,7 +318,8 @@ pub(crate) fn verify_execution_receipt( /// Details of the confirmed domain block such as operators, rewards they would receive. #[derive(Debug, PartialEq)] -pub(crate) struct ConfirmedDomainBlockInfo { +pub(crate) struct ConfirmedDomainBlockInfo { + pub consensus_block_number: ConsensusNumber, pub domain_block_number: DomainNumber, pub operator_ids: Vec, pub rewards: Balance, @@ -327,8 +328,10 @@ pub(crate) struct ConfirmedDomainBlockInfo { pub paid_bundle_storage_fees: BTreeMap, } -pub(crate) type ProcessExecutionReceiptResult = - Result, BalanceOf>>, Error>; +pub(crate) type ProcessExecutionReceiptResult = Result< + Option, DomainBlockNumberFor, BalanceOf>>, + Error, +>; /// Process the execution receipt to add it to the block tree /// Returns the domain block number that was pruned, if any @@ -429,6 +432,7 @@ pub(crate) fn process_execution_receipt( }); return Ok(Some(ConfirmedDomainBlockInfo { + consensus_block_number: execution_receipt.consensus_block_number, domain_block_number: to_prune, operator_ids, rewards: execution_receipt.block_fees.domain_execution_fee, diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index 6228e66247..9e769eb012 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -65,8 +65,8 @@ use sp_core::H256; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::{ DomainBundleLimit, DomainId, DomainInstanceData, ExecutionReceipt, OpaqueBundle, OperatorId, - OperatorPublicKey, OperatorSignature, ProofOfElection, RuntimeId, SealedSingletonReceipt, - DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT, EMPTY_EXTRINSIC_ROOT, + OperatorPublicKey, OperatorRewardSource, OperatorSignature, ProofOfElection, RuntimeId, + SealedSingletonReceipt, DOMAIN_EXTRINSICS_SHUFFLING_SEED_SUBJECT, EMPTY_EXTRINSIC_ROOT, }; use sp_domains_fraud_proof::fraud_proof::{ DomainRuntimeCodeAt, FraudProof, FraudProofVariant, InvalidBlockFeesProof, @@ -231,7 +231,8 @@ mod pallet { use sp_domains::{ BundleDigest, DomainBundleSubmitted, DomainId, DomainSudoCall, DomainsTransfersTracker, EpochIndex, GenesisDomain, OnChainRewards, OnDomainInstantiated, OperatorAllowList, - OperatorId, OperatorPublicKey, OperatorSignature, RuntimeId, RuntimeObject, RuntimeType, + OperatorId, OperatorPublicKey, OperatorRewardSource, OperatorSignature, RuntimeId, + RuntimeObject, RuntimeType, }; use sp_domains_fraud_proof::fraud_proof_runtime_interface::domain_runtime_call; use sp_domains_fraud_proof::storage_proof::{self, FraudProofStorageKeyProvider}; @@ -976,6 +977,7 @@ mod pallet { nominator_id: NominatorId, }, OperatorRewarded { + source: OperatorRewardSource>, operator_id: OperatorId, reward: BalanceOf, }, @@ -1134,6 +1136,9 @@ mod pallet { do_reward_operators::( domain_id, + OperatorRewardSource::Bundle { + at_block_number: confirmed_block_info.consensus_block_number, + }, confirmed_block_info.operator_ids.into_iter(), confirmed_block_info.rewards, ) @@ -1749,6 +1754,9 @@ mod pallet { do_reward_operators::( domain_id, + OperatorRewardSource::Bundle { + at_block_number: confirmed_block_info.consensus_block_number, + }, confirmed_block_info.operator_ids.into_iter(), confirmed_block_info.rewards, ) @@ -2833,14 +2841,18 @@ impl Pallet { } /// Reward the active operators of this domain epoch. - pub fn reward_domain_operators(domain_id: DomainId, rewards: BalanceOf) { + pub fn reward_domain_operators( + domain_id: DomainId, + source: OperatorRewardSource>, + rewards: BalanceOf, + ) { // If domain is not instantiated, then we don't care at the moment. if let Some(domain_stake_summary) = DomainStakingSummary::::get(domain_id) { let operators = domain_stake_summary .current_epoch_rewards .into_keys() .collect::>(); - let _ = do_reward_operators::(domain_id, operators.into_iter(), rewards); + let _ = do_reward_operators::(domain_id, source, operators.into_iter(), rewards); } } diff --git a/crates/pallet-domains/src/staking.rs b/crates/pallet-domains/src/staking.rs index c686e5929a..fa18a66094 100644 --- a/crates/pallet-domains/src/staking.rs +++ b/crates/pallet-domains/src/staking.rs @@ -18,10 +18,11 @@ use codec::{Decode, Encode}; use frame_support::traits::fungible::{Inspect, MutateHold}; use frame_support::traits::tokens::{Fortitude, Precision, Preservation}; use frame_support::{ensure, PalletError}; +use frame_system::pallet_prelude::BlockNumberFor; use scale_info::TypeInfo; use sp_core::{sr25519, Get}; use sp_domains::{ - DomainId, EpochIndex, OperatorId, OperatorPublicKey, OperatorSignature, + DomainId, EpochIndex, OperatorId, OperatorPublicKey, OperatorRewardSource, OperatorSignature, OperatorSigningKeyProofOfOwnershipData, }; use sp_runtime::traits::{CheckedAdd, CheckedSub, Zero}; @@ -1327,6 +1328,7 @@ pub(crate) fn do_cleanup_operator( /// Distribute the reward to the operators equally and drop any dust to treasury. pub(crate) fn do_reward_operators( domain_id: DomainId, + source: OperatorRewardSource>, operators: IntoIter, rewards: BalanceOf, ) -> Result<(), Error> { @@ -1374,6 +1376,7 @@ pub(crate) fn do_reward_operators( .insert(operator_id, total_reward); Pallet::::deposit_event(Event::OperatorRewarded { + source: source.clone(), operator_id, reward: operator_reward, }); @@ -1470,7 +1473,7 @@ pub(crate) mod tests { use sp_core::{sr25519, Pair, U256}; use sp_domains::{ BlockFees, DomainId, OperatorAllowList, OperatorId, OperatorPair, OperatorPublicKey, - OperatorSignature, Transfers, + OperatorRewardSource, OperatorSignature, Transfers, }; use sp_runtime::traits::Zero; use sp_runtime::{PerThing, Perbill}; @@ -2018,6 +2021,7 @@ pub(crate) mod tests { if !operator_reward.is_zero() { do_reward_operators::( domain_id, + OperatorRewardSource::Dummy, vec![operator_id].into_iter(), operator_reward, ) @@ -2865,8 +2869,13 @@ pub(crate) mod tests { .unwrap(); } - do_reward_operators::(domain_id, vec![operator_id].into_iter(), 20 * SSC) - .unwrap(); + do_reward_operators::( + domain_id, + OperatorRewardSource::Dummy, + vec![operator_id].into_iter(), + 20 * SSC, + ) + .unwrap(); do_finalize_domain_current_epoch::(domain_id).unwrap(); // Manually convert previous withdrawal in share to balance @@ -3024,8 +3033,13 @@ pub(crate) mod tests { .unwrap(); } - do_reward_operators::(domain_id, vec![operator_id].into_iter(), 20 * SSC) - .unwrap(); + do_reward_operators::( + domain_id, + OperatorRewardSource::Dummy, + vec![operator_id].into_iter(), + 20 * SSC, + ) + .unwrap(); do_finalize_domain_current_epoch::(domain_id).unwrap(); // Manually convert previous withdrawal in share to balance diff --git a/crates/pallet-domains/src/staking_epoch.rs b/crates/pallet-domains/src/staking_epoch.rs index 072c5a6238..abd13d4d07 100644 --- a/crates/pallet-domains/src/staking_epoch.rs +++ b/crates/pallet-domains/src/staking_epoch.rs @@ -536,7 +536,8 @@ mod tests { use frame_support::traits::fungible::InspectHold; use sp_core::{Pair, U256}; use sp_domains::{ - BlockFees, DomainId, OperatorPair, OperatorSigningKeyProofOfOwnershipData, Transfers, + BlockFees, DomainId, OperatorPair, OperatorRewardSource, + OperatorSigningKeyProofOfOwnershipData, Transfers, }; use sp_runtime::traits::Zero; use sp_runtime::{PerThing, Percent}; @@ -605,8 +606,13 @@ mod tests { } if !rewards.is_zero() { - do_reward_operators::(domain_id, vec![operator_id].into_iter(), rewards) - .unwrap() + do_reward_operators::( + domain_id, + OperatorRewardSource::Dummy, + vec![operator_id].into_iter(), + rewards, + ) + .unwrap() } // de-register operator @@ -770,8 +776,13 @@ mod tests { } if !rewards.is_zero() { - do_reward_operators::(domain_id, vec![operator_id].into_iter(), rewards) - .unwrap(); + do_reward_operators::( + domain_id, + OperatorRewardSource::Dummy, + vec![operator_id].into_iter(), + rewards, + ) + .unwrap(); } do_finalize_domain_current_epoch::(domain_id).unwrap(); @@ -864,8 +875,13 @@ mod tests { Operators::::insert(operator_id, operator); let expected_operator_tax = nomination_tax.mul_ceil(operator_rewards); - do_reward_operators::(domain_id, vec![operator_id].into_iter(), operator_rewards) - .unwrap(); + do_reward_operators::( + domain_id, + OperatorRewardSource::Dummy, + vec![operator_id].into_iter(), + operator_rewards, + ) + .unwrap(); operator_take_reward_tax_and_stake::(domain_id).unwrap(); let operator = Operators::::get(operator_id).unwrap(); diff --git a/crates/sp-domains/src/lib.rs b/crates/sp-domains/src/lib.rs index 363a2c2f6c..e0d84ff5bc 100644 --- a/crates/sp-domains/src/lib.rs +++ b/crates/sp-domains/src/lib.rs @@ -1473,6 +1473,16 @@ impl OnChainRewards for () { fn on_chain_rewards(_chain_id: ChainId, _reward: Balance) {} } +#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] +pub enum OperatorRewardSource { + Bundle { + at_block_number: Number, + }, + XDMProtocolFees, + #[cfg(any(feature = "std", feature = "runtime-benchmarks"))] + Dummy, +} + sp_api::decl_runtime_apis! { /// API necessary for domains pallet. pub trait DomainsApi { diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index de63358110..4708b89fa8 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -72,7 +72,8 @@ use sp_core::{ConstBool, OpaqueMetadata, H256}; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::{ ChannelId, DomainAllowlistUpdates, DomainId, DomainInstanceData, ExecutionReceiptFor, - OperatorId, OperatorPublicKey, DOMAIN_STORAGE_FEE_MULTIPLIER, INITIAL_DOMAIN_TX_RANGE, + OperatorId, OperatorPublicKey, OperatorRewardSource, DOMAIN_STORAGE_FEE_MULTIPLIER, + INITIAL_DOMAIN_TX_RANGE, }; use sp_domains_fraud_proof::fraud_proof::FraudProof; use sp_domains_fraud_proof::storage_proof::{ @@ -590,7 +591,7 @@ impl sp_messenger::OnXDMRewards for OnXDMRewards { // on consensus chain, reward the domain operators // balance is already on this consensus runtime if let ChainId::Domain(domain_id) = chain_id { - Domains::reward_domain_operators(domain_id, fees) + Domains::reward_domain_operators(domain_id, OperatorRewardSource::XDMProtocolFees, fees) } } } @@ -793,7 +794,11 @@ impl sp_domains::OnChainRewards for OnChainRewards { let _ = Balances::deposit_creating(&block_author, reward); } } - ChainId::Domain(domain_id) => Domains::reward_domain_operators(domain_id, reward), + ChainId::Domain(domain_id) => Domains::reward_domain_operators( + domain_id, + OperatorRewardSource::XDMProtocolFees, + reward, + ), } } } diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 7f526d38fc..4fe29aaf00 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -61,8 +61,8 @@ use sp_core::{OpaqueMetadata, H256}; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::{ DomainAllowlistUpdates, DomainId, DomainInstanceData, ExecutionReceiptFor, OpaqueBundle, - OpaqueBundles, OperatorId, OperatorPublicKey, DOMAIN_STORAGE_FEE_MULTIPLIER, - INITIAL_DOMAIN_TX_RANGE, + OpaqueBundles, OperatorId, OperatorPublicKey, OperatorRewardSource, + DOMAIN_STORAGE_FEE_MULTIPLIER, INITIAL_DOMAIN_TX_RANGE, }; use sp_domains_fraud_proof::fraud_proof::FraudProof; use sp_domains_fraud_proof::storage_proof::{ @@ -719,7 +719,11 @@ impl sp_domains::OnChainRewards for OnChainRewards { let _ = Balances::deposit_creating(&block_author, reward); } } - ChainId::Domain(domain_id) => Domains::reward_domain_operators(domain_id, reward), + ChainId::Domain(domain_id) => Domains::reward_domain_operators( + domain_id, + OperatorRewardSource::XDMProtocolFees, + reward, + ), } } } From 004c45432e757d16f064945b4a7a3d3c8fecfd6b Mon Sep 17 00:00:00 2001 From: linning Date: Wed, 16 Oct 2024 20:17:59 +0800 Subject: [PATCH 2/2] Set OnXDMRewards for the consensus test runtime to keep consistency with the production runtime Signed-off-by: linning --- test/subspace-test-runtime/src/lib.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 4fe29aaf00..6d2c2f25e6 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -603,6 +603,24 @@ parameter_types! { pub const ChannelFeeModel: FeeModel = FeeModel{relay_fee: SSC}; } +pub struct OnXDMRewards; + +impl sp_messenger::OnXDMRewards for OnXDMRewards { + fn on_xdm_rewards(reward: Balance) { + if let Some(block_author) = Subspace::find_block_reward_address() { + let _ = Balances::deposit_creating(&block_author, reward); + } + } + + fn on_chain_protocol_fees(chain_id: ChainId, fees: Balance) { + // on consensus chain, reward the domain operators + // balance is already on this consensus runtime + if let ChainId::Domain(domain_id) = chain_id { + Domains::reward_domain_operators(domain_id, OperatorRewardSource::XDMProtocolFees, fees) + } + } +} + impl pallet_messenger::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SelfChainId = SelfChainId; @@ -618,7 +636,7 @@ impl pallet_messenger::Config for Runtime { type Currency = Balances; type WeightInfo = pallet_messenger::weights::SubstrateWeight; type WeightToFee = ConstantMultiplier; - type OnXDMRewards = (); + type OnXDMRewards = OnXDMRewards; type MmrHash = mmr::Hash; type MmrProofVerifier = MmrProofVerifier; type StorageKeys = StorageKeys;