Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nomination pools rewards #21

Merged
merged 29 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
86274ed
added base PaidOut support
vovunku Jul 10, 2023
5a607d0
add source(direct/pooled) field to reward
vovunku Jul 10, 2023
9a031b1
add source to AccumulatedReward
vovunku Jul 10, 2023
b057df3
removed source/added new stakingType
vovunku Jul 11, 2023
0091b56
added BondedSlash handler(not tested)
vovunku Jul 11, 2023
f0e335b
pooled slashes implemented(not tested yet)
vovunku Jul 11, 2023
f9c487f
first test for bonded slash added
vovunku Jul 14, 2023
2dfb406
more accounts
vovunku Jul 17, 2023
711cc22
add unbonding test
vovunku Jul 17, 2023
04988f1
fixed member point logic
vovunku Jul 17, 2023
0301848
Merge branch 'feature/nomination-pools-rewards' into feature/nomintai…
vovunku Jul 17, 2023
50d2e23
added all unbonding tests
vovunku Jul 17, 2023
338c501
fixed division by zero if poolPoints === 0
vovunku Jul 17, 2023
83ac959
Merge branch 'feature/nomination-pools-rewards' into feature/nomintai…
vovunku Jul 17, 2023
1b09033
removed copypaste
vovunku Jul 17, 2023
c6faed5
added test for pool rewards
vovunku Jul 17, 2023
5d2e693
added pool handlers to Polkadot, Westend and Aleph-zero
vovunku Jul 17, 2023
b19971f
removed console.log
vovunku Jul 17, 2023
ecc1cf7
renamed test
vovunku Jul 17, 2023
2ff283e
code refactoring
vovunku Jul 18, 2023
adb5e38
Merge branch 'feature/nomination-pools-rewards' into feature/nomintai…
vovunku Jul 18, 2023
72368bd
updated nomination pools path
vovunku Jul 18, 2023
3f34099
merged master for apy
vovunku Jul 18, 2023
f603550
fixed common.ts while merging
vovunku Jul 18, 2023
2837b82
base added
vovunku Jul 20, 2023
8b95164
Merge branch 'feature/nomination-pools-rewards' into feature/nomintai…
vovunku Jul 25, 2023
b457ba9
Revert "base added"
vovunku Jul 25, 2023
eabbd75
Merge branch 'feature/nomination-pools-rewards' into feature/nomintai…
vovunku Jul 25, 2023
8da30b9
Merge pull request #22 from novasamatech/feature/nomintaion_pools_test
vovunku Jul 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions project-aleph-zero.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ dataSources:
module: staking
method: Rewarded

- handler: handleAlephZeroPoolStakingReward
kind: substrate/EventHandler
filter:
module: nominationPools
method: PaidOut

- handler: handleAlephZeroStakingSlash
kind: substrate/EventHandler
filter:
Expand All @@ -53,3 +59,15 @@ dataSources:
filter:
module: staking
method: Slashed

- handler: handleAlephZeroPoolStakingBondedSlash
kind: substrate/EventHandler
filter:
module: nominationPools
method: PoolSlashed

- handler: handleAlephZeroPoolStakingUnbondingSlash
kind: substrate/EventHandler
filter:
module: nominationPools
method: UnbondingPoolSlashed
18 changes: 18 additions & 0 deletions project-polkadot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ dataSources:
module: staking
method: Rewarded

- handler: handlePolkadotPoolStakingReward
kind: substrate/EventHandler
filter:
module: nominationPools
method: PaidOut

- handler: handlePolkadotStakingSlash
kind: substrate/EventHandler
filter:
Expand All @@ -52,3 +58,15 @@ dataSources:
filter:
module: staking
method: Slashed

- handler: handlePolkadotPoolStakingBondedSlash
kind: substrate/EventHandler
filter:
module: nominationPools
method: PoolSlashed

- handler: handlePolkadotPoolStakingUnbondingSlash
kind: substrate/EventHandler
filter:
module: nominationPools
method: UnbondingPoolSlashed
18 changes: 18 additions & 0 deletions project-westend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ dataSources:
module: staking
method: Rewarded

- handler: handleWestendPoolStakingReward
kind: substrate/EventHandler
filter:
module: nominationPools
method: PaidOut

- handler: handleWestendStakingSlash
kind: substrate/EventHandler
filter:
Expand All @@ -53,3 +59,15 @@ dataSources:
filter:
module: staking
method: Slashed

- handler: handleWestendPoolStakingBondedSlash
kind: substrate/EventHandler
filter:
module: nominationPools
method: PoolSlashed

- handler: handleWestendPoolStakingUnbondingSlash
kind: substrate/EventHandler
filter:
module: nominationPools
method: UnbondingPoolSlashed
33 changes: 28 additions & 5 deletions src/mappings/aleph-zero.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import {SubstrateEvent} from "@subql/types";
import {handleNewEra} from "./common";
import {handleNewEra, POOLED_STAKING_TYPE} from "./common";
import {AlephZeroRewardCalculator} from "./rewards/AlephZero";
import {ValidatorEraInfoDataSource} from "./era/ValidatorEraInfoDataSource";
import {Codec} from "@polkadot/types/types";
import {INumber} from "@polkadot/types-codec/types/interfaces";
import {handleRelaychainStakingReward, handleRelaychainStakingSlash} from "./rewards/history/relaychain";
import {
handleRelaychainPooledStakingReward,
handleRelaychainPooledStakingBondedSlash,
handleRelaychainPooledStakingUnbondingSlash
} from "./rewards/history/nomination_pools";

const ALEPH_ZERO_GENESIS = "0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e"
const STAKING_TYPE = "aleph-zero"
const DIRECT_STAKING_TYPE = "aleph-zero"

export async function handleAlephZeroNewEra(_: SubstrateEvent): Promise<void> {
let validatorEraInfoDataSource = new ValidatorEraInfoDataSource();
Expand All @@ -16,18 +21,36 @@ export async function handleAlephZeroNewEra(_: SubstrateEvent): Promise<void> {
validatorEraInfoDataSource,
new AlephZeroRewardCalculator(validatorEraInfoDataSource),
ALEPH_ZERO_GENESIS,
STAKING_TYPE
DIRECT_STAKING_TYPE
)
}

export async function handleAlephZeroStakingReward(
event: SubstrateEvent<[accountId: Codec, reward: INumber]>,
): Promise<void> {
await handleRelaychainStakingReward(event, ALEPH_ZERO_GENESIS, STAKING_TYPE)
await handleRelaychainStakingReward(event, ALEPH_ZERO_GENESIS, DIRECT_STAKING_TYPE)
}

export async function handleAlephZeroStakingSlash(
event: SubstrateEvent<[account: Codec, slash: INumber]>,
): Promise<void> {
await handleRelaychainStakingSlash(event, ALEPH_ZERO_GENESIS, STAKING_TYPE)
await handleRelaychainStakingSlash(event, ALEPH_ZERO_GENESIS, DIRECT_STAKING_TYPE)
}

export async function handleAlephZeroPoolStakingReward(
event: SubstrateEvent<[accountId: Codec, poolId: INumber, reward: INumber]>,
): Promise<void> {
await handleRelaychainPooledStakingReward(event, ALEPH_ZERO_GENESIS, POOLED_STAKING_TYPE)
}

export async function handleAlephZeroPoolStakingBondedSlash(
event: SubstrateEvent<[poolId: INumber, slash: INumber]>,
): Promise<void> {
await handleRelaychainPooledStakingBondedSlash(event, ALEPH_ZERO_GENESIS, POOLED_STAKING_TYPE)
}

export async function handleAlephZeroPoolStakingUnbondingSlash(
event: SubstrateEvent<[era: INumber, poolId: INumber, slash: INumber]>,
): Promise<void> {
await handleRelaychainPooledStakingUnbondingSlash(event, ALEPH_ZERO_GENESIS, POOLED_STAKING_TYPE)
}
8 changes: 3 additions & 5 deletions src/mappings/kusama.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import {SubstrateEvent} from "@subql/types";
import {handleNewEra} from "./common";
import {handleNewEra, POOLED_STAKING_TYPE} from "./common";
import {RelaychainRewardCalculator} from "./rewards/Relaychain";
import {ValidatorEraInfoDataSource} from "./era/ValidatorEraInfoDataSource";
import {Codec} from "@polkadot/types/types";
import {INumber} from "@polkadot/types-codec/types/interfaces";
import {handleRelaychainStakingReward, handleRelaychainStakingSlash} from "./rewards/history/relaychain";
import {
handleRelaychainStakingReward,
handleRelaychainStakingSlash,
handleRelaychainPooledStakingReward,
handleRelaychainPooledStakingBondedSlash,
handleRelaychainPooledStakingUnbondingSlash
} from "./rewards/history/relaychain";
} from "./rewards/history/nomination_pools";

const KUSAMA_GENESIS = "0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe"
const DIRECT_STAKING_TYPE = "relaychain"
const POOLED_STAKING_TYPE = "nomination-pool"

export async function handleKusamaNewEra(_: SubstrateEvent): Promise<void> {
let validatorEraInfoDataSource = new ValidatorEraInfoDataSource();
Expand Down
33 changes: 28 additions & 5 deletions src/mappings/polkadot.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import {SubstrateEvent} from "@subql/types";
import {handleNewEra} from "./common";
import {handleNewEra, POOLED_STAKING_TYPE} from "./common";
import {RelaychainRewardCalculator} from "./rewards/Relaychain";
import {ValidatorEraInfoDataSource} from "./era/ValidatorEraInfoDataSource";
import {Codec} from "@polkadot/types/types";
import {INumber} from "@polkadot/types-codec/types/interfaces";
import {handleRelaychainStakingReward, handleRelaychainStakingSlash} from "./rewards/history/relaychain";
import {
handleRelaychainPooledStakingReward,
handleRelaychainPooledStakingBondedSlash,
handleRelaychainPooledStakingUnbondingSlash
} from "./rewards/history/nomination_pools";

const POLKADOT_GENESIS = "0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3"
const STAKING_TYPE = "relaychain"
const DIRECT_STAKING_TYPE = "relaychain"

export async function handlePolkadotNewEra(_: SubstrateEvent): Promise<void> {
let validatorEraInfoDataSource = new ValidatorEraInfoDataSource();
Expand All @@ -16,18 +21,36 @@ export async function handlePolkadotNewEra(_: SubstrateEvent): Promise<void> {
validatorEraInfoDataSource,
await RelaychainRewardCalculator(validatorEraInfoDataSource),
POLKADOT_GENESIS,
STAKING_TYPE
DIRECT_STAKING_TYPE
)
}

export async function handlePolkadotStakingReward(
event: SubstrateEvent<[accountId: Codec, reward: INumber]>,
): Promise<void> {
await handleRelaychainStakingReward(event, POLKADOT_GENESIS, STAKING_TYPE)
await handleRelaychainStakingReward(event, POLKADOT_GENESIS, DIRECT_STAKING_TYPE)
}

export async function handlePolkadotStakingSlash(
event: SubstrateEvent<[account: Codec, slash: INumber]>,
): Promise<void> {
await handleRelaychainStakingSlash(event, POLKADOT_GENESIS, STAKING_TYPE)
await handleRelaychainStakingSlash(event, POLKADOT_GENESIS, DIRECT_STAKING_TYPE)
}

export async function handlePolkadotPoolStakingReward(
event: SubstrateEvent<[accountId: Codec, poolId: INumber, reward: INumber]>,
): Promise<void> {
await handleRelaychainPooledStakingReward(event, POLKADOT_GENESIS, POOLED_STAKING_TYPE)
}

export async function handlePolkadotPoolStakingBondedSlash(
event: SubstrateEvent<[poolId: INumber, slash: INumber]>,
): Promise<void> {
await handleRelaychainPooledStakingBondedSlash(event, POLKADOT_GENESIS, POOLED_STAKING_TYPE)
}

export async function handlePolkadotPoolStakingUnbondingSlash(
event: SubstrateEvent<[era: INumber, poolId: INumber, slash: INumber]>,
): Promise<void> {
await handleRelaychainPooledStakingUnbondingSlash(event, POLKADOT_GENESIS, POOLED_STAKING_TYPE)
}
106 changes: 106 additions & 0 deletions src/mappings/rewards/history/nomination_pools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {SubstrateEvent} from "@subql/types";
import {Codec} from "@polkadot/types/types";
import {RewardType} from "../../../types";
import {INumber} from "@polkadot/types-codec/types/interfaces";
import {handleRelaychainStakingRewardType} from "./relaychain";
import {PalletNominationPoolsPoolMember} from "@polkadot/types/lookup";

export async function handleRelaychainPooledStakingReward(
event: SubstrateEvent<[accountId: Codec, poolId: INumber, reward: INumber]>,
chainId: string,
stakingType: string
): Promise<void> {
const {event: {data: [accountId, poolId, amount]}} = event

await handleRelaychainStakingRewardType(
event,
amount.toBigInt(),
accountId.toString(),
RewardType.reward,
chainId, stakingType,
poolId.toNumber()
)
}

export async function handleRelaychainPooledStakingBondedSlash(
event: SubstrateEvent<[poolId: INumber, slash: INumber]>,
chainId: string,
stakingType: string
): Promise<void> {
const {event: {data: [poolId, slash]}} = event
const pid = poolId.toNumber()

const pool = (await api.query.nominationPools.bondedPools(pid)).unwrap()

await handleRelaychainPooledStakingSlash(
event,
pid,
pool.points.toBigInt(),
slash.toBigInt(),
chainId,
stakingType,
(member: PalletNominationPoolsPoolMember) : bigint => {
return member.points.toBigInt()
}
)
}

export async function handleRelaychainPooledStakingUnbondingSlash(
event: SubstrateEvent<[era: INumber, poolId: INumber, slash: INumber]>,
chainId: string,
stakingType: string
): Promise<void> {
const {event: {data: [era, poolId, slash]}} = event
const poolIdNumber = poolId.toNumber()
const eraIdNumber = era.toNumber()

const unbondingPools = (await api.query.nominationPools.subPoolsStorage(poolIdNumber)).unwrap()

const pool = unbondingPools.withEra[eraIdNumber] ?? unbondingPools.noEra

await handleRelaychainPooledStakingSlash(
event,
poolIdNumber,
pool.points.toBigInt(),
slash.toBigInt(),
chainId,
stakingType,
(member: PalletNominationPoolsPoolMember) : bigint => {
return member.unbondingEras[eraIdNumber]?.toBigInt() ?? BigInt(0)
}
)
}

export async function handleRelaychainPooledStakingSlash(
event: SubstrateEvent,
poolId: number,
poolPoints: bigint,
slash: bigint,
chainId: string,
stakingType: string,
memberPointsCounter: (member: PalletNominationPoolsPoolMember) => bigint
): Promise<void> {
if(poolPoints == BigInt(0)) {
return
}

const members = await api.query.nominationPools.poolMembers.entries()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's cache this request for a given block number


await Promise.all(members.map(async ([accountId, member]) => {
let memberPoints: bigint
if (member.isSome && member.unwrap().poolId.toNumber() === poolId) {
memberPoints = memberPointsCounter(member.unwrap())
if (memberPoints != BigInt(0)) {
await handleRelaychainStakingRewardType(
event,
(slash / poolPoints) * memberPoints,
accountId.toString(),
RewardType.slash,
chainId,
stakingType,
poolId
)
}
}
}))
}
Loading