Skip to content

Commit

Permalink
pallet
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolaos Dymitriadis <[email protected]>
  • Loading branch information
AmbientTea committed Feb 25, 2025
1 parent 2f5c26c commit d0bd897
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 1 deletion.
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ members = [
"toolkit/primitives/plutus-data",
"toolkit/pallets/address-associations",
"toolkit/primitives/stake-distribution",
"toolkit/pallets/block-rewards-payouts",
"toolkit/primitives/block-rewards-payouts",
]
resolver = "2"
Expand Down Expand Up @@ -242,4 +243,5 @@ partner-chains-cli = { path = "toolkit/partner-chains-cli", default-features = f
partner-chains-plutus-data = { path = "toolkit/primitives/plutus-data", default-features = false }
partner-chains-smart-contracts-commands = { path = "toolkit/cli/smart-contracts-commands", default-features = false }
pallet-address-associations = { path = "toolkit/pallets/address-associations", default-features = false }
pallet-block-rewards-payouts = { path = "toolkit/pallets/block-rewards-payouts", default-features = false }
sp-block-rewards-payouts = { path = "toolkit/primitives/block-rewards-payouts", default-features = false }
2 changes: 1 addition & 1 deletion node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ use sidechain_domain::{
use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_core::hexdisplay::HexDisplay;
use sp_core::ByteArray;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
use sp_core::{ByteArray, Pair};
use sp_runtime::{
generic, impl_opaque_keys,
traits::{
Expand Down
32 changes: 32 additions & 0 deletions toolkit/pallets/block-rewards-payouts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "pallet-block-rewards-payouts"
version = "0.1.0"
edition = "2021"

[dependencies]
frame-support = { workspace = true }
frame-system = { workspace = true }
log = { workspace = true }
parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
sp-std = { workspace = true }
sp-block-rewards-payouts = { workspace = true }
pallet-block-production-log = { workspace = true }

[dev-dependencies]
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }

[features]
default = ["std"]
std = [
"frame-support/std",
"frame-system/std",
"log/std",
"parity-scale-codec/std",
"scale-info/std",
"sp-std/std",
"sp-block-rewards-payouts/std",
"pallet-block-production-log/std"
]
110 changes: 110 additions & 0 deletions toolkit/pallets/block-rewards-payouts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::pallet_prelude::*;
pub use pallet::*;
use sp_block_rewards_payouts::*;

pub trait ShouldProcessPayout {
/// Should return slot up to which rewards should be paid out or None.
fn should_pay_out(slot: Slot) -> Option<Slot>;
}

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_system::pallet_prelude::*;
use scale_info::prelude::format;

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::config]
pub trait Config: frame_system::Config + pallet_block_production_log::Config {
/// Type identifying reward receiver on the Partner Chain
type BeneficiaryId: Member + Parameter + MaxEncodedLen;

type ShouldProcessPayout: ShouldProcessPayout;
}

#[pallet::inherent]
impl<T: Config> ProvideInherent for Pallet<T> {
type Call = Call<T>;
type Error = sp_block_rewards_payouts::InherentError;
const INHERENT_IDENTIFIER: InherentIdentifier =
sp_block_rewards_payouts::INHERENT_IDENTIFIER;

fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let up_to_slot = Self::get_rewards_inherent_data(data)?.up_to_slot;

Some(Call::note_payout { up_to_slot })
}

fn check_inherent(call: &Self::Call, data: &InherentData) -> Result<(), Self::Error> {
let Some(expected_inherent_data) = Self::get_rewards_inherent_data(data) else {
return Err(Self::Error::InherentRequired);
};

let Self::Call::note_payout { up_to_slot } = call else {
unreachable!("There should be no other extrinsic in the pallet")
};

if *up_to_slot != expected_inherent_data.up_to_slot {
return Err(Self::Error::IncorrectSlotBoundary);
}

Ok(())
}

fn is_inherent(call: &Self::Call) -> bool {
matches!(call, Call::note_payout { .. })
}

fn is_inherent_required(data: &InherentData) -> Result<Option<Self::Error>, Self::Error> {
if Self::get_rewards_inherent_data(data).is_some() {
Ok(Some(Self::Error::InherentRequired))
} else {
Ok(None)
}
}
}

impl<T: Config> Pallet<T> {
fn get_rewards_inherent_data(
data: &InherentData,
) -> Option<BlockProductionPayoutInfo<T::BlockProducerId, T::BeneficiaryId>> {
data.get_data(&Self::INHERENT_IDENTIFIER)
.map_err(|err| {
format!("Reward payout inherent data is present but invalid: {err:?}")
})
.unwrap()
}
}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight((0, DispatchClass::Mandatory))]
pub fn note_payout(origin: OriginFor<T>, up_to_slot: Slot) -> DispatchResult {
ensure_none(origin)?;
log::info!(
"💸 Processing block production rewards payouts up to slot {}.",
*up_to_slot
);
pallet_block_production_log::Pallet::<T>::drop_prefix(up_to_slot);
Ok(())
}
}

impl<T: Config> Pallet<T> {
pub fn should_pay_out(slot: Slot) -> Option<Slot> {
<T as Config>::ShouldProcessPayout::should_pay_out(slot)
}

pub fn blocks_to_reward(
slot: Slot,
) -> impl Iterator<Item = (Slot, <T as pallet_block_production_log::Config>::BlockProducerId)>
{
pallet_block_production_log::Pallet::<T>::peek_prefix(slot)
}
}
}

0 comments on commit d0bd897

Please sign in to comment.