mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
Merge branch 'main' into fix/verify-allowlist-tx-receipt-status
This commit is contained in:
commit
90c1f320e8
8 changed files with 139 additions and 35 deletions
|
|
@ -625,10 +625,43 @@ pub mod pallet {
|
|||
impl<T: Config> OnEraEnd for Pallet<T> {
|
||||
fn on_era_end(era_index: EraIndex) {
|
||||
// Calculate performance-scaled inflation based on blocks produced.
|
||||
// This must be done first since we use it for both minting and the rewards message.
|
||||
let base_inflation = T::EraInflationProvider::get();
|
||||
let scaled_inflation = Self::calculate_scaled_inflation(era_index, base_inflation);
|
||||
|
||||
// Check that there are reward points before minting.
|
||||
// This prevents minting inflation when no validators have earned rewards.
|
||||
let era_reward_points = RewardPointsForEra::<T>::get(&era_index);
|
||||
let total_points: u128 = era_reward_points
|
||||
.individual
|
||||
.values()
|
||||
.map(|pts| *pts as u128)
|
||||
.sum();
|
||||
|
||||
if total_points.is_zero() {
|
||||
log::error!(
|
||||
target: "ext_validators_rewards",
|
||||
"No reward points in era {}, skipping inflation minting",
|
||||
era_index
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let ethereum_sovereign_account = T::RewardsEthereumSovereignAccount::get();
|
||||
|
||||
// Mint scaled inflation tokens using the configurable handler.
|
||||
// Returns an InflationMintResult with the rewards/treasury split.
|
||||
let mint_result = match T::HandleInflation::mint_inflation(
|
||||
ðereum_sovereign_account,
|
||||
scaled_inflation,
|
||||
) {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
log::error!(target: "ext_validators_rewards", "Failed to handle inflation: {err:?}");
|
||||
log::error!(target: "ext_validators_rewards", "Not sending message since there are no rewards to distribute");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Get era start timestamp from the active era (still the ending era at this point).
|
||||
// Convert from milliseconds to seconds for EigenLayer compatibility.
|
||||
let era_start_timestamp = T::EraIndexProvider::active_era()
|
||||
|
|
@ -636,11 +669,11 @@ pub mod pallet {
|
|||
.map(|ms| (ms / 1000) as u32)
|
||||
.unwrap_or(0);
|
||||
|
||||
// Generate era rewards utils with the scaled inflation amount.
|
||||
// This ensures the message to EigenLayer matches the actual minted amount.
|
||||
let utils = match RewardPointsForEra::<T>::get(&era_index).generate_era_rewards_utils(
|
||||
// Generate era rewards utils with the actual rewards amount (post-treasury split).
|
||||
// This ensures the message to EigenLayer matches the actual minted rewards.
|
||||
let utils = match era_reward_points.generate_era_rewards_utils(
|
||||
era_index,
|
||||
scaled_inflation,
|
||||
mint_result.rewards_amount,
|
||||
era_start_timestamp,
|
||||
) {
|
||||
Some(utils) => utils,
|
||||
|
|
@ -654,17 +687,6 @@ pub mod pallet {
|
|||
}
|
||||
};
|
||||
|
||||
let ethereum_sovereign_account = T::RewardsEthereumSovereignAccount::get();
|
||||
|
||||
// Mint scaled inflation tokens using the configurable handler
|
||||
if let Err(err) =
|
||||
T::HandleInflation::mint_inflation(ðereum_sovereign_account, scaled_inflation)
|
||||
{
|
||||
log::error!(target: "ext_validators_rewards", "Failed to handle inflation: {err:?}");
|
||||
log::error!(target: "ext_validators_rewards", "Not sending message since there are no rewards to distribute");
|
||||
return;
|
||||
}
|
||||
|
||||
frame_system::Pallet::<T>::register_extra_weight_unchecked(
|
||||
T::WeightInfo::on_era_end(),
|
||||
DispatchClass::Mandatory,
|
||||
|
|
@ -675,7 +697,7 @@ pub mod pallet {
|
|||
message_id,
|
||||
era_index,
|
||||
total_points: utils.total_points,
|
||||
inflation_amount: scaled_inflation,
|
||||
inflation_amount: mint_result.rewards_amount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,10 @@ impl pallet_external_validators_rewards::Config for Test {
|
|||
|
||||
pub struct InflationMinter;
|
||||
impl HandleInflation<H160> for InflationMinter {
|
||||
fn mint_inflation(rewards_account: &H160, total_amount: u128) -> sp_runtime::DispatchResult {
|
||||
fn mint_inflation(
|
||||
rewards_account: &H160,
|
||||
total_amount: u128,
|
||||
) -> Result<crate::types::InflationMintResult, sp_runtime::DispatchError> {
|
||||
use sp_runtime::traits::Zero;
|
||||
|
||||
if total_amount.is_zero() {
|
||||
|
|
@ -266,7 +269,10 @@ impl HandleInflation<H160> for InflationMinter {
|
|||
.map_err(|_| DispatchError::Other("Failed to mint treasury inflation"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(crate::types::InflationMintResult {
|
||||
rewards_amount,
|
||||
treasury_amount,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,15 +160,19 @@ fn test_on_era_end() {
|
|||
let era_rewards = pallet_external_validators_rewards::RewardPointsForEra::<Test>::get(1);
|
||||
let inflation =
|
||||
<Test as pallet_external_validators_rewards::Config>::EraInflationProvider::get();
|
||||
// The event should contain the rewards amount (post-treasury split), not the full inflation.
|
||||
// Treasury gets Perbill::from_percent(20).mul_floor(inflation), rewards gets the rest.
|
||||
let treasury_amount = InflationTreasuryProportion::get().mul_floor(inflation);
|
||||
let rewards_amount = inflation - treasury_amount;
|
||||
// Use 0 for era_start_timestamp in tests
|
||||
let rewards_utils = era_rewards.generate_era_rewards_utils(1, inflation, 0);
|
||||
let rewards_utils = era_rewards.generate_era_rewards_utils(1, rewards_amount, 0);
|
||||
assert!(rewards_utils.is_some());
|
||||
System::assert_last_event(RuntimeEvent::ExternalValidatorsRewards(
|
||||
crate::Event::RewardsMessageSent {
|
||||
message_id: Default::default(),
|
||||
era_index: 1,
|
||||
total_points: total_points as u128,
|
||||
inflation_amount: inflation,
|
||||
inflation_amount: rewards_amount,
|
||||
},
|
||||
));
|
||||
})
|
||||
|
|
|
|||
|
|
@ -39,14 +39,34 @@ pub trait SendMessage {
|
|||
fn deliver(ticket: Self::Ticket) -> Result<H256, SendError>;
|
||||
}
|
||||
|
||||
// Trait for handling inflation
|
||||
/// Result of minting inflation tokens, detailing the split between rewards and treasury.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct InflationMintResult {
|
||||
/// Amount minted to the rewards account (for distribution to validators via AVS).
|
||||
pub rewards_amount: u128,
|
||||
/// Amount minted to the treasury account.
|
||||
pub treasury_amount: u128,
|
||||
}
|
||||
|
||||
/// Trait for handling inflation minting with a rewards/treasury split.
|
||||
pub trait HandleInflation<AccountId> {
|
||||
fn mint_inflation(who: &AccountId, amount: u128) -> sp_runtime::DispatchResult;
|
||||
/// Mint inflation tokens, splitting between rewards and treasury.
|
||||
/// Returns an `InflationMintResult` detailing the amounts minted to each destination.
|
||||
fn mint_inflation(
|
||||
who: &AccountId,
|
||||
amount: u128,
|
||||
) -> Result<InflationMintResult, sp_runtime::DispatchError>;
|
||||
}
|
||||
|
||||
impl<AccountId> HandleInflation<AccountId> for () {
|
||||
fn mint_inflation(_: &AccountId, _: u128) -> sp_runtime::DispatchResult {
|
||||
Ok(())
|
||||
fn mint_inflation(
|
||||
_: &AccountId,
|
||||
_: u128,
|
||||
) -> Result<InflationMintResult, sp_runtime::DispatchError> {
|
||||
Ok(InflationMintResult {
|
||||
rewards_amount: 0,
|
||||
treasury_amount: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,11 +165,15 @@ where
|
|||
TreasuryProportion: Get<Perbill>,
|
||||
TreasuryAccount: Get<crate::AccountId>,
|
||||
{
|
||||
/// Mints inflation tokens and splits them between rewards and treasury accounts
|
||||
/// Mints inflation tokens and splits them between rewards and treasury accounts.
|
||||
/// Returns an `InflationMintResult` detailing the amounts minted to each destination.
|
||||
pub fn mint_inflation(
|
||||
rewards_account: &crate::AccountId,
|
||||
total_amount: u128,
|
||||
) -> sp_runtime::DispatchResult {
|
||||
) -> Result<
|
||||
pallet_external_validators_rewards::types::InflationMintResult,
|
||||
sp_runtime::DispatchError,
|
||||
> {
|
||||
use sp_runtime::traits::Zero;
|
||||
|
||||
if total_amount.is_zero() {
|
||||
|
|
@ -236,7 +240,12 @@ where
|
|||
treasury_amount
|
||||
);
|
||||
|
||||
Ok(())
|
||||
Ok(
|
||||
pallet_external_validators_rewards::types::InflationMintResult {
|
||||
rewards_amount,
|
||||
treasury_amount,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -247,6 +256,7 @@ mod tests {
|
|||
parameter_types,
|
||||
traits::fungible::{Inspect, Mutate, Unbalanced},
|
||||
};
|
||||
use pallet_external_validators_rewards::types::InflationMintResult;
|
||||
use sp_runtime::Perbill;
|
||||
use std::cell::RefCell;
|
||||
|
||||
|
|
@ -561,7 +571,13 @@ mod tests {
|
|||
let total_inflation = 1_000_000u128;
|
||||
|
||||
let result = TestHandler::mint_inflation(&rewards_account, total_inflation);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(InflationMintResult {
|
||||
rewards_amount: 800_000,
|
||||
treasury_amount: 200_000,
|
||||
})
|
||||
);
|
||||
|
||||
let rewards_balance = get_balance(&rewards_account);
|
||||
let treasury_balance = get_balance(&TreasuryAccountId::get());
|
||||
|
|
@ -579,7 +595,13 @@ mod tests {
|
|||
let total_inflation = 1_000_000u128;
|
||||
|
||||
let result = TestHandler50Pct::mint_inflation(&rewards_account, total_inflation);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(InflationMintResult {
|
||||
rewards_amount: 500_000,
|
||||
treasury_amount: 500_000,
|
||||
})
|
||||
);
|
||||
|
||||
let rewards_balance = get_balance(&rewards_account);
|
||||
let treasury_balance = get_balance(&TreasuryAccountId::get());
|
||||
|
|
@ -596,7 +618,13 @@ mod tests {
|
|||
let total_inflation = 1_000_000u128;
|
||||
|
||||
let result = TestHandler0Pct::mint_inflation(&rewards_account, total_inflation);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(InflationMintResult {
|
||||
rewards_amount: total_inflation,
|
||||
treasury_amount: 0,
|
||||
})
|
||||
);
|
||||
|
||||
let rewards_balance = get_balance(&rewards_account);
|
||||
let treasury_balance = get_balance(&TreasuryAccountId::get());
|
||||
|
|
@ -613,7 +641,13 @@ mod tests {
|
|||
let total_inflation = 1_000_000u128;
|
||||
|
||||
let result = TestHandler100Pct::mint_inflation(&rewards_account, total_inflation);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(InflationMintResult {
|
||||
rewards_amount: 0,
|
||||
treasury_amount: total_inflation,
|
||||
})
|
||||
);
|
||||
|
||||
let rewards_balance = get_balance(&rewards_account);
|
||||
let treasury_balance = get_balance(&TreasuryAccountId::get());
|
||||
|
|
|
|||
|
|
@ -1460,7 +1460,13 @@ pub struct ExternalRewardsInflationHandler;
|
|||
impl pallet_external_validators_rewards::types::HandleInflation<AccountId>
|
||||
for ExternalRewardsInflationHandler
|
||||
{
|
||||
fn mint_inflation(who: &AccountId, amount: u128) -> sp_runtime::DispatchResult {
|
||||
fn mint_inflation(
|
||||
who: &AccountId,
|
||||
amount: u128,
|
||||
) -> Result<
|
||||
pallet_external_validators_rewards::types::InflationMintResult,
|
||||
sp_runtime::DispatchError,
|
||||
> {
|
||||
datahaven_runtime_common::inflation::ExternalRewardsInflationHandler::<
|
||||
Balances,
|
||||
runtime_params::dynamic_params::runtime_config::InflationTreasuryProportion,
|
||||
|
|
|
|||
|
|
@ -1456,7 +1456,13 @@ pub struct ExternalRewardsInflationHandler;
|
|||
impl pallet_external_validators_rewards::types::HandleInflation<AccountId>
|
||||
for ExternalRewardsInflationHandler
|
||||
{
|
||||
fn mint_inflation(who: &AccountId, amount: u128) -> sp_runtime::DispatchResult {
|
||||
fn mint_inflation(
|
||||
who: &AccountId,
|
||||
amount: u128,
|
||||
) -> Result<
|
||||
pallet_external_validators_rewards::types::InflationMintResult,
|
||||
sp_runtime::DispatchError,
|
||||
> {
|
||||
datahaven_runtime_common::inflation::ExternalRewardsInflationHandler::<
|
||||
Balances,
|
||||
runtime_params::dynamic_params::runtime_config::InflationTreasuryProportion,
|
||||
|
|
|
|||
|
|
@ -1460,7 +1460,13 @@ pub struct ExternalRewardsInflationHandler;
|
|||
impl pallet_external_validators_rewards::types::HandleInflation<AccountId>
|
||||
for ExternalRewardsInflationHandler
|
||||
{
|
||||
fn mint_inflation(who: &AccountId, amount: u128) -> sp_runtime::DispatchResult {
|
||||
fn mint_inflation(
|
||||
who: &AccountId,
|
||||
amount: u128,
|
||||
) -> Result<
|
||||
pallet_external_validators_rewards::types::InflationMintResult,
|
||||
sp_runtime::DispatchError,
|
||||
> {
|
||||
datahaven_runtime_common::inflation::ExternalRewardsInflationHandler::<
|
||||
Balances,
|
||||
runtime_params::dynamic_params::runtime_config::InflationTreasuryProportion,
|
||||
|
|
|
|||
Loading…
Reference in a new issue