Sub3.0模板进化2修改aura为babe--by Skyh

node-template起始共识是Aura,就是Round Robin轮流出块的简单机制,现在改成Babe就是基于插槽VRF的共识

1. 依赖修改

runtime的Cargo.toml搜索有两处aura

pallet-aura = { version = "3.0.0", default-features = false }
sp-consensus-aura = { version = "0.9.0", default-features = false }
修改成:
pallet-babe = { version = "3.0.0", default-features = false }
sp-consensus-babe = { version = "0.9.0", default-features = false }
还有std中的

还有node的Cargo.toml也有两处

sc-consensus-aura = "0.9.0"
sp-consensus-aura = "0.9.0"

2. 修改runtime的lib.rs, 搜索Aura

把SessionKey修改:

impl_opaque_keys! {
    pub struct SessionKeys {
        pub aura: Aura,
        pub grandpa: Grandpa,
    }
}
改成:
impl_opaque_keys! {
    pub struct SessionKeys {
        pub babe: Babe,
        pub grandpa: Grandpa,
    }
}

把aura的定义改成:

parameter_types! {
    pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
    pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
    pub const ReportLongevity: u64 = 0; // by Skyh
        // BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); // Kusama
}

impl pallet_babe::Config for Runtime {
    type EpochDuration = EpochDuration;
    type ExpectedBlockTime = ExpectedBlockTime;
    type EpochChangeTrigger = pallet_babe::ExternalTrigger;
    type KeyOwnerProofSystem = (); // Historical;
    type KeyOwnerProof =
    >::Proof;
    type KeyOwnerIdentification =
    >::IdentificationTuple;
    type HandleEquivocation = (); //pallet_babe::EquivocationHandler; // () Offences
    type WeightInfo = ();
}

修改construct_runtime的Aura:

construct_runtime!(
    pub enum Runtime where
        Block = Block,
        NodeBlock = opaque::Block,
        UncheckedExtrinsic = UncheckedExtrinsic
    {
        Sudo: pallet_sudo::{Module, Call, Config, Storage, Event},
        System: frame_system::{Module, Call, Config, Storage, Event},
        Balances: pallet_balances::{Module, Call, Storage, Config, Event},
        Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
        TransactionPayment: pallet_transaction_payment::{Module, Storage},
        RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},

        Babe: pallet_babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned},
        Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned},

        // Include the custom logic from the template pallet in the runtime.
        TemplateModule: template::{Module, Call, Storage, Event},
    }
);

修改impl_runtime_apis中的AuraApi

impl sp_consensus_babe::BabeApi for Runtime {
        fn configuration() -> sp_consensus_babe::BabeGenesisConfiguration {
            sp_consensus_babe::BabeGenesisConfiguration {
                slot_duration: Babe::slot_duration(),
                epoch_length: EpochDuration::get(),
                c: PRIMARY_PROBABILITY,
                genesis_authorities: Babe::authorities(),
                randomness: Babe::randomness(),
                allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
            }
        }

        fn current_epoch_start() -> sp_consensus_babe::Slot {
            Babe::current_epoch_start()
        }

        fn current_epoch() -> sp_consensus_babe::Epoch {
            Babe::current_epoch()
        }

        fn next_epoch() -> sp_consensus_babe::Epoch {
            Babe::next_epoch()
        }

        fn generate_key_ownership_proof(
            _slot: sp_consensus_babe::Slot,
            authority_id: sp_consensus_babe::AuthorityId,
        ) -> Option {
            use codec::Encode;

            Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id))
                .map(|p| p.encode())
                .map(sp_consensus_babe::OpaqueKeyOwnershipProof::new)
        }

        fn submit_report_equivocation_unsigned_extrinsic(
            equivocation_proof: sp_consensus_babe::EquivocationProof<::Header>,
            key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
            ) -> Option<()> {
            let key_owner_proof = key_owner_proof.decode()?;

            Babe::submit_unsigned_equivocation_report(
                equivocation_proof,
                key_owner_proof,
                )
        }
    }

坑:在这里,高度抽象化必须对应看人家项目使用Historical,所以必须在runtime中加入:

# historical的特性
pallet-session = { version = "3.0.0", default-features = false, features = ["historical"] }

impl pallet_session::historical::Config for Runtime {
    type FullIdentification = pallet_staking::Exposure;
    type FullIdentificationOf = pallet_staking::ExposureOf;
}

Historical: session_historical::{Module},

坑2:也要加入staking, 这算耦合么,暂时没有好的解决方法

pallet-staking = { version = "3.0.0", default-features = false }

也在babe和grandpa加入KeyOwnerProofSystem为Historical
编译报错要实现super的session的config


image.png

3. 被逼加入session和staking

具体代码

parameter_types! {
    pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

impl pallet_session::Config for Runtime {
    type Event = Event;
    type ValidatorId = ::AccountId;
    type ValidatorIdOf = pallet_staking::StashOf;

    type Keys = SessionKeys;
    type ShouldEndSession = Babe;
    type NextSessionRotation = Babe;
    type SessionManager = pallet_session::historical::NoteHistoricalRoot;
    type SessionHandler = ::KeyTypeIdProviders;
    type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
    type WeightInfo = ();
}

impl pallet_session::historical::Config for Runtime {
    type FullIdentification = pallet_staking::Exposure;
    type FullIdentificationOf = pallet_staking::ExposureOf;
}

又必须加入staking

pallet_staking_reward_curve::build! {
    const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
        min_inflation: 0_025_000,
        max_inflation: 0_100_000,
        ideal_stake: 0_500_000,
        falloff: 0_050_000,
        max_piece_count: 40,
        test_precision: 0_005_000,
    );
}

parameter_types! {
    pub const SessionsPerEra: sp_staking::SessionIndex = 3; // 3 hours
    pub const BondingDuration: pallet_staking::EraIndex = 4; // 12 hours
    pub const SlashDeferDuration: pallet_staking::EraIndex = 2; // 6 hours
    pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
    pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;

    pub const MaxNominatorRewardedPerValidator: u32 = 64;
    pub const MaxIterations: u32 = 5;
    // 0.05%. The higher the value, the more strict solution acceptance becomes.
    pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
    pub StakingUnsignedPriority: TransactionPriority =
        Perbill::from_percent(90) * TransactionPriority::max_value();
}

parameter_types! {
    pub OffchainSolutionWeightLimit: Weight = BlockWeights::get()
        .get(DispatchClass::Normal)
        .max_extrinsic
        .expect("Normal extrinsics have weight limit configured by default; qed")
        .saturating_sub(BlockExecutionWeight::get());
}

pub type CurrencyToVote = frame_support::traits::U128CurrencyToVote;

// TODO: Kusama
// type SlashCancelOrigin = EnsureOneOf<
//  AccountId,
//  EnsureRoot,
//  pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>
// >;

impl pallet_staking::Config for Runtime {
    type Call = Call;
    type Event = Event;
    type UnixTime = Timestamp;

    type Currency = Balances;
    type CurrencyToVote = CurrencyToVote;
    type RewardRemainder = (); // TODO: Treasury
    type Slash = (); // TODO: Treasury
    type Reward = (); // rewards are minted from the voi

    type SessionInterface = Self;
    type NextNewSession = Session;
    type SessionsPerEra = SessionsPerEra;
    type BondingDuration = BondingDuration;
    type SlashDeferDuration = SlashDeferDuration;
    /// A super-majority of the council can cancel the slash.
    type SlashCancelOrigin = EnsureRoot; // TODO: SlashCancelOrigin
    type RewardCurve = RewardCurve;
    type ElectionLookahead = ElectionLookahead;

    type MinSolutionScoreBump = MinSolutionScoreBump;
    type MaxIterations = MaxIterations;
    type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
    type UnsignedPriority = StakingUnsignedPriority; // Kusama
    type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
    type WeightInfo = ();
}

坑3:staking需要实现SendTransactionTypes

impl frame_system::offchain::SendTransactionTypes for Runtime
    where
        Call: From,
{
    type OverarchingCall = Call;
    type Extrinsic = UncheckedExtrinsic;
}

4. 修改chain_spec.rs和service.rs

chain_spec首先先引入 BabeId

use sp_consensus_babe::AuthorityId as BabeId;

// 加session_key
fn session_keys(
    babe: BabeId,
    grandpa: GrandpaId,
) -> SessionKeys {
    SessionKeys { babe, grandpa }
}

修改authority_keys_from_seed的AuraId

pub fn authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, BabeId, GrandpaId) {
    (
        get_account_id_from_seed::(&format!("{}//stash", seed)),
        get_account_id_from_seed::(seed),
        get_from_seed::(seed),
        get_from_seed::(seed),
    )
}

再在testnet_genesis中修改aura:

pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_session: Some(SessionConfig {
            keys: initial_authorities.iter().map(|x| {
                (x.0.clone(),
                 x.0.clone(),
                 session_keys(
                     x.2.clone(), x.3.clone()
                 ))
            }).collect::>(),
        }),
        pallet_staking: Some(StakingConfig {
            validator_count: initial_authorities.len() as u32 * 2,
            minimum_validator_count: initial_authorities.len() as u32,
            stakers: initial_authorities
                .iter()
                .map(|x| (x.0.clone(), x.1.clone(), INITIAL_STAKING, StakerStatus::Validator))
                .collect(),
            invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
            slash_reward_fraction: Perbill::from_percent(10),
            ..Default::default()
        }),

写在最后,这次修改在这里:
https://github.com/skyh24/node-template3/commit/513d4bad382baf1f65d90608143d1bc491e9de74

你可能感兴趣的:(Sub3.0模板进化2修改aura为babe--by Skyh)