Now that the PoA is running with multiple Aura validators in my substrate-node-template. How could I configure that reward amount or value for my validators?
4 Answers
I got it working, PoA will reward the validator who created the block using the tip as the sample value for the fees, here are the steps:
- Install the pallet_authorship
pallet-authorship = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.23" }
- Configure the pallet to get the current author of the block
pub struct AuraAccountAdapter;
impl frame_support::traits::FindAuthor<AccountId> for AuraAccountAdapter {
fn find_author<'a, I>(digests: I) -> Option<AccountId>
where I: 'a + IntoIterator<Item=(frame_support::ConsensusEngineId, &'a [u8])>
{
pallet_aura::AuraAuthorId::<Runtime>::find_author(digests).and_then(|k| {
AccountId::try_from(k.as_ref()).ok()
})
}
}
impl pallet_authorship::Config for Runtime {
type FindAuthor = AuraAccountAdapter;
type UncleGenerations = ();
type FilterUncle = ();
type EventHandler = ();
}
- Create OnUnbalanced implementation of Author and DealWithFees
use crate::{Authorship, Balances};
use frame_support::traits::{Imbalance, OnUnbalanced};
use crate::sp_api_hidden_includes_construct_runtime::hidden_include::traits::Currency;
use crate::AccountId;
type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
pub struct Author;
impl OnUnbalanced<NegativeImbalance> for Author {
fn on_nonzero_unbalanced(amount: NegativeImbalance) {
if let Some(author) = Authorship::author() {
Balances::resolve_creating(&author, amount);
}
}
}
pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
if let Some(fees) = fees_then_tips.next() {
let mut split = fees.ration(80, 20);
if let Some(tips) = fees_then_tips.next() {
// for tips, if any, 80% to treasury, 20% to block author (though this can be anything)
tips.ration_merge_into(80, 20, &mut split);
}
//Treasury::on_unbalanced(split.0);
Author::on_unbalanced(split.1);
}
}
}
- Call the implementation in the pallet_transaction_payment tuple OnChargeTransaction
impl pallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, crate::impls::DealWithFees>;
type OperationalFeeMultiplier = ConstU8<5>;
type WeightToFee = IdentityFee<Balance>;
type LengthToFee = IdentityFee<Balance>;
type FeeMultiplierUpdate = ();
}
Also added in my blog: https://hgminerva.wordpress.com/2022/06/21/how-to-pay-the-block-author-validator-on-a-proof-of-authority-poa-consensus-in-substrate/
This can be handled with OnUnbalanced on NegativeImbalance event when a fee is charged, here is sample code
You will also need to integrate authorship pallet to pass the author (validator) information, here is a snippet for this.
-
Thanks for the response! Although FYI it is always best practice to link out and provide directly a snippet here for reference. Both for keeping people from having to jump out of the site, but more importantly because those resources may disappear latter on or change– Nuke ♦Jun 20, 2022 at 2:52
-
So I need the following task for my substrate-node-template: 1. Import pallet_session 2. Import pallet_authorship 3. Implement both pallets in the /runtime/lib.rs 4. Implement OnUnbalanced event for Author struct 5. Implement OnUnbalanced event for DealtWithFees struct Jun 20, 2022 at 5:09
Please correct me if I am wrong on this Mo Elshami. These are the step on how to provide reward to your PoA validators in the substrate-node-template.
- Import the pallet_session (runtime/Cargo.toml)
pallet-session = { version = "4.0.0-dev", features = [ "historical" ], path = "../../../frame/session", default-features = false }`
- Import the pallet_authorship (runtime/Cargo.toml)
pallet-authorship = { version = "4.0.0-dev", default-features = false, path = "../../../frame/authorship" }`
- Implement both pallet in the /runtime/lib.rs
parameter_types! {
pub const Period: u32 = 6 * HOURS;
pub const Offset: u32 = 0;
pub const MaxAuthorities: u32 = 100_000;
}
impl pallet_session::Config for Runtime {
type Event = Event;
type ValidatorId = <Self as frame_system::Config>::AccountId;
// we don't have stash and controller, thus we don't need the convert as well.
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
type SessionManager = CollatorSelection;
// Essentially just Aura, but lets be pedantic.
type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys;
type WeightInfo = ();
}
parameter_types! {
pub const UncleGenerations: u32 = 0;
}
impl pallet_authorship::Config for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
type UncleGenerations = UncleGenerations;
type FilterUncle = ();
type EventHandler = (CollatorSelection,);
}
- Implement OnUnbalanced event for Author and DealtWithFees struct
use crate::{Authorship, Balances, NegativeImbalance, Treasury};
use frame_support::traits::{Currency, Imbalance, OnUnbalanced};
pub struct Author;
impl OnUnbalanced<NegativeImbalance> for Author {
fn on_nonzero_unbalanced(amount: NegativeImbalance) {
if let Some(author) = Authorship::author() {
Balances::resolve_creating(&author, amount);
}
}
}
pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
if let Some(fees) = fees_then_tips.next() {
let mut split = fees.ration(80, 20);
if let Some(tips) = fees_then_tips.next() {
// for tips, if any, 80% to treasury, 20% to block author (though this can be anything)
tips.ration_merge_into(80, 20, &mut split);
}
Treasury::on_unbalanced(split.0);
Author::on_unbalanced(split.1);
}
}
}
The above is about allowing the transaction fees to be split between validators. If you want inflation as well, this can currently only be done if you use pallet-staking
. Inflationary rewards are minted in pallet-staking
, and can configured via the type EraPayout
. See EraPayout
.
-
I am just using Aura for the time being. I want to pay the block authors/validators of the existing PoA. Jun 20, 2022 at 8:36