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

⚓ Integrate set era payout damping factor proposal #4818

Merged
merged 27 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
92702a4
Fix InputNumber maxAllowedValue
thesan Mar 26, 2024
41b3a00
Create set era payout damping factor proposals
thesan Mar 26, 2024
023f673
Preview set era payout damping factor proposals
thesan Mar 26, 2024
2fac8e6
Fix typo
thesan Mar 26, 2024
baaec86
Query `SetEraPayoutDampingFactorProposalDetails`
thesan Mar 26, 2024
aded88b
Use the proper percentageMapper to preview the proposal
thesan Mar 29, 2024
220daa2
Compare with current multiplier value
thesan Mar 29, 2024
2fc1507
Describe the proposal
thesan Mar 29, 2024
d2535be
Validate that the multiplier is at most 100%
thesan Apr 2, 2024
66e4fa0
Make the NumberOfBlocks renderer reusable
thesan Mar 29, 2024
b120b09
Preview CRT constraints proposal
thesan Mar 29, 2024
a9850ee
Create CRT constraints proposal
thesan Apr 2, 2024
c3b0ef9
Query `UpdateTokenPalletTokenConstraintsProposalDetails`
thesan Apr 2, 2024
bd44e13
Schema and types
thesan Apr 2, 2024
44bc262
Show current values in the form
thesan Apr 2, 2024
e914884
Show current values on the preview page
thesan Apr 2, 2024
f2496c4
Fix the vote on proposal modal
thesan Apr 3, 2024
a62b5e8
Fix mismatched values
thesan Apr 3, 2024
ada87e2
Show current values on field inputs sub label instead of message
thesan Apr 3, 2024
852b0f1
Enable decimal values in `InputNumber`
thesan Apr 3, 2024
3ad9514
Use decimal percent to represent part per million
thesan Apr 3, 2024
9458833
Preview decimal percents
thesan Apr 3, 2024
06b39b9
Merge branch 'feature/crt-constraints-proposal' into feature/luxor/re…
thesan Apr 4, 2024
364101f
Generate queries
thesan Apr 4, 2024
e7bab76
Patch `@joystream/types`
thesan Apr 4, 2024
30fbe31
Fix type issue
thesan Apr 4, 2024
4185ef3
Merge branch 'luxor' of github.com:Joystream/pioneer into feature/lux…
thesan Apr 8, 2024
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
13,075 changes: 9,329 additions & 3,746 deletions .yarn/patches/@joystream-types-npm-4.3.0-542438a0b6.patch

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions packages/ui/src/app/pages/Proposals/CurrentProposals.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,38 @@ export const SpecificParametersRuntimeUpgrade: Story = {
}),
}

export const SpecificParametersSetEraPayoutDampingFactor: Story = {
play: specificParametersTest('Set Era Payout Damping Factor', async ({ args, createProposal, modal, step }) => {
await createProposal(async () => {
const nextButton = getButtonByText(modal, 'Create proposal')
expect(nextButton).toBeDisabled()

// Valid
const factorField = await modal.findByLabelText('Validator reward multiplier')
await userEvent.type(factorField, '60')
await waitFor(() => expect(nextButton).toBeEnabled())

// Invalid
await userEvent.clear(factorField)
await userEvent.type(factorField, '200')
await modal.findByText('The value must be between 0 and 100%.')
await waitFor(() => expect(nextButton).toBeDisabled())

// Valid again
await userEvent.clear(factorField)
await userEvent.type(factorField, '60')
await waitFor(() => expect(nextButton).toBeEnabled())
})

await step('Transaction parameters', () => {
const [, , specificParameters] = args.onCreateProposal.mock.calls.at(-1)
expect(specificParameters.toJSON()).toEqual({
setEraPayoutDampingFactor: 60,
})
})
}),
}

export const SpecificParametersDecreaseCouncilBudget: Story = {
parameters: {
councilBudget: joy(500),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export default {
council: {
budget: joy(1000),
councilorReward: joy(1),
eraPayoutDampingFactor: 70,
},
referendum: { stage: {} },
projectToken: {
Expand Down Expand Up @@ -304,6 +305,9 @@ export const UpdateChannelPayouts: Story = {
export const UpdatePalletFrozenStatus: Story = {
args: { type: 'UpdatePalletFrozenStatusProposalDetails' },
}
export const SetEraPayoutDampingFactor: Story = {
args: { type: 'SetEraPayoutDampingFactorProposalDetails' },
}
export const UpdateWorkingGroupBudget: Story = {
args: { type: 'UpdateWorkingGroupBudgetProposalDetails' },
}
Expand Down Expand Up @@ -683,7 +687,7 @@ export const TestCancelProposalHappy: Story = {
})

await step('Confirm', async () => {
expect(await modal.findByText('Your propsal has been cancelled.'))
expect(await modal.findByText('Your proposal has been cancelled.'))

expect(onCancel).toHaveBeenLastCalledWith(activeMember.controllerAccount, activeMember.id, PROPOSAL_DATA.id)
})
Expand Down

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

8 changes: 8 additions & 0 deletions packages/ui/src/common/api/schemas/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2593,6 +2593,7 @@ union ProposalDetails =
| UpdateGlobalNftLimitProposalDetails
| DecreaseCouncilBudgetProposalDetails
| UpdateTokenPalletTokenConstraintsProposalDetails
| SetEraPayoutDampingFactorProposalDetails

union ProposalStatus =
ProposalStatusDeciding
Expand Down Expand Up @@ -3338,6 +3339,13 @@ type SetCouncilorRewardProposalDetails {
newRewardPerBlock: BigInt!
}

type SetEraPayoutDampingFactorProposalDetails {
"""
Proposed validator payout damping factor
"""
dampingFactor: Int!
}

type SetInitialInvitationBalanceProposalDetails {
"""
The new (proposed) initial balance credited to controller account of an invitee (locked for transaction fee payments only)
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/src/common/components/forms/InputNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ import { Input, InputProps } from './InputComponent'

interface BaseNumberInputProps extends Omit<InputProps, 'type' | 'defaultValue' | 'onChange'> {
decimalScale?: number
maxAllowedValue?: number
maxAllowedValue?: number // At most MAX_SAFE_INTEGER (otherwise InputNumber might not be the right component).
onChange?: (event: React.ChangeEvent<HTMLInputElement>, numberValue: number) => void
}

const BasedInputNumber = React.memo(
({ id, onChange, value = '', maxAllowedValue = 2 ** 32, decimalScale = 0, ...props }: BaseNumberInputProps) => {
({ id, onChange, value = '', maxAllowedValue = 2 ** 32 - 1, decimalScale = 0, ...props }: BaseNumberInputProps) => {
const onInputChange = useCallback(
({ floatValue = 0 }: NumberFormatValues, { event }: SourceInfo) => onChange?.(event, floatValue),
[onChange]
)

const isAllowed = useCallback(
({ floatValue = 0 }: NumberFormatValues) => floatValue < maxAllowedValue,
({ floatValue = 0 }: NumberFormatValues) => floatValue <= maxAllowedValue,
[maxAllowedValue]
)

Expand Down

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

2 changes: 2 additions & 0 deletions packages/ui/src/mocks/data/proposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const proposalDetails: Record<ProposalDetailsType, RecursivePartial<ProposalWith
UpdateWorkingGroupBudgetProposalDetails: { amount: joy(200), group: workingGroup },
VetoProposalDetails: { proposal: { __typename: 'Proposal', id: '0', title: random.words(4) } },
UpdateGlobalNftLimitProposalDetails: {},
SetEraPayoutDampingFactorProposalDetails: { dampingFactor: 60 },
DecreaseCouncilBudgetProposalDetails: { amount: joy(100) },
UpdateTokenPalletTokenConstraintsProposalDetails: {
maxYearlyRate: 0.4 * 10 ** 6,
Expand Down Expand Up @@ -257,6 +258,7 @@ export const proposalsPagesChain = (
budget: councilBudget,
councilorReward,
nextRewardPayments,
eraPayoutDampingFactor: 70,
},
referendum: { stage: {} },

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const proposalDetailsToConstantKeyMap = new Map<ProposalDetailsType, keyof Api['
['UpdateWorkingGroupBudgetProposalDetails', 'updateWorkingGroupBudgetProposalParameters'],
['VetoProposalDetails', 'vetoProposalProposalParameters'],
['UpdatePalletFrozenStatusProposalDetails', 'setPalletFozenStatusProposalParameters'],
['SetEraPayoutDampingFactorProposalDetails', 'setEraPayoutDampingFactorProposalParameters'],
['DecreaseCouncilBudgetProposalDetails', 'decreaseCouncilBudgetProposalParameters'],
['UpdateTokenPalletTokenConstraintsProposalDetails', 'updateTokenPalletTokenConstraints'],
])
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ const renderTypeMapper: Partial<Record<RenderType, ProposalDetailContent>> = {
export const ProposalDetails = ({ proposalDetails, gracePeriod, exactExecutionBlock, createdInBlock }: Props) => {
const { api } = useApi()
const { budget } = useCouncilStatistics()

const validatorRewardMultiplier = useFirstObservableValue(() => {
if (proposalDetails?.type === 'setEraPayoutDampingFactor') {
return api?.query.council.eraPayoutDampingFactor()
}
}, [api?.isConnected, proposalDetails?.type])

const { group } = useWorkingGroup({
name: (proposalDetails as UpdateGroupBudgetDetails)?.group?.id,
})
Expand Down Expand Up @@ -124,6 +131,17 @@ export const ProposalDetails = ({ proposalDetails, gracePeriod, exactExecutionBl
] as RenderNode[]
}

if (proposalDetails?.type === 'setEraPayoutDampingFactor') {
return [
{
renderType: 'Numeric',
units: '%',
label: 'Current multiplier',
value: validatorRewardMultiplier,
},
] as RenderNode[]
}

if (proposalDetails?.type === 'updateTokenPalletTokenConstraints') {
return [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ export type RenderType =
| 'Divider'
| 'ProposalLink'
| 'OpeningLink'
| 'Percentage'
| 'Hash'
| 'DestinationsPreview'
| 'BlockTimeDisplay'

export interface RenderNode {
label: string
value: any
renderType: RenderType
tooltip?: TooltipContentProp
units?: string
}

type Mapper<Detail, Key extends keyof Detail> = (
Expand Down Expand Up @@ -308,6 +309,9 @@ const mappers: Partial<Record<ProposalDetailsKeys, Mapper<any, any>>> = {
pallet: palletMapper,
freeze: palletStatusMapper,

// SetEraPayoutDampingFactor
multiplier: percentageMapper('Validator reward multiplier'),

// UpdateTokenPalletTokenConstraints
maxYearlyRate: percentageMapper('Proposed maximum yearly rate'),
minAmmSlope: amountMapper('Proposed minimum AMM slope'),
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/proposals/hooks/useProposalConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const proposalTypeToConstantKey = new Map<ProposalType, keyof Api['consts']['pro
['terminateWorkingGroupLead', 'terminateWorkingGroupLeadProposalParameters'],
['updateWorkingGroupBudget', 'updateWorkingGroupBudgetProposalParameters'],
['veto', 'vetoProposalProposalParameters'],
['setEraPayoutDampingFactor', 'setEraPayoutDampingFactorProposalParameters'],
['decreaseCouncilBudget', 'decreaseCouncilBudgetProposalParameters'],
['updateTokenPalletTokenConstraints', 'updateTokenPalletTokenConstraints'],
])
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'

import { useApi } from '@/api/hooks/useApi'
import { InputComponent, InputNumber } from '@/common/components/forms'
import { Row } from '@/common/components/Modal'
import { RowGapBlock } from '@/common/components/page/PageContent'
import { TextMedium } from '@/common/components/typography'
import { useFirstObservableValue } from '@/common/hooks/useFirstObservableValue'

export const SetEraPayoutDampingFactor = () => {
const { api } = useApi()
const current = useFirstObservableValue(() => api?.query.council.eraPayoutDampingFactor(), [api?.isConnected])

return (
<RowGapBlock gap={24}>
<Row>
<RowGapBlock gap={8}>
<h4>Specific parameters</h4>
<TextMedium lighter>
Set the validator reward multiplier. {current && `The current value is ${current.toNumber()}%`}.
</TextMedium>
</RowGapBlock>
</Row>
<Row>
<RowGapBlock gap={20}>
<InputComponent
message={'Amount must be greater than zero'}
id="damping-factor-input"
name="setEraPayoutDampingFactor.dampingFactor"
label="Validator reward multiplier"
tight
units="%"
required
>
<InputNumber id="damping-factor-input" name="setEraPayoutDampingFactor.dampingFactor" placeholder="100" />
</InputComponent>
thesan marked this conversation as resolved.
Show resolved Hide resolved
</RowGapBlock>
</Row>
</RowGapBlock>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export const SetMembershipLeadInvitationQuota = () => {
id="amount-input"
name="setMembershipLeadInvitationQuota.count"
placeholder="0"
maxAllowedValue={Math.pow(2, 32) - 1}
disabled={isLoading || !group?.leadId}
/>
</InputComponent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const SetReferralCut = () => {
id="amount-input"
name="setReferralCut.referralCut"
placeholder="0"
maxAllowedValue={Math.pow(2, 8)}
maxAllowedValue={2 ** 8 - 1}
/>
</InputComponent>
</RowGapBlock>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { FillWorkingGroupLeadOpening } from '@/proposals/modals/AddNewProposal/c
import { AddNewProposalMachineState } from '@/proposals/modals/AddNewProposal/machine'

import { DecreaseCouncilBudget } from './DecreaseCouncilBudget'
import { SetEraPayoutDampingFactor } from './SetEraPayoutDampingFactor'
import { SetInitialInvitationBalance } from './SetInitialInvitationBalance'
import { SetInitialInvitationCount } from './SetInitialInvitationCount'
import { UpdatePalletFrozenStatus } from './UpdatePalletFrozenStatus'
Expand Down Expand Up @@ -88,6 +89,9 @@ export const SpecificParametersStep = ({ matches }: SpecificParametersStepProps)
case matches('specificParameters.updatePalletFrozenStatus'): {
return <UpdatePalletFrozenStatus />
}
case matches('specificParameters.setEraPayoutDampingFactor'): {
return <SetEraPayoutDampingFactor />
}
case matches('specificParameters.decreaseCouncilBudget'): {
return <DecreaseCouncilBudget />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,7 @@ export const TriggerAndDiscussionStep = () => {
name="triggerAndDiscussion.triggerBlock"
message={triggerBlock ? `≈ ${inBlocksDate(triggerBlock)}` : ''}
>
<InputNumber
id="triggerBlock"
placeholder="0"
name="triggerAndDiscussion.triggerBlock"
maxAllowedValue={Math.pow(2, 32)}
/>
<InputNumber id="triggerBlock" placeholder="0" name="triggerAndDiscussion.triggerBlock" />
</InputComponent>
)}
</RowGapBlock>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,15 @@ export const getSpecificParameters = async (
}
case 'updatePalletFrozenStatus': {
return createType('PalletProposalsCodexProposalDetails', {
// NOTE: The "SetPalletFozenStatus" typo comes from the runtime so it should be fixed there first.
SetPalletFozenStatus: [!specifics.updatePalletFrozenStatus.enable, specifics.updatePalletFrozenStatus.pallet],
})
}
case 'setEraPayoutDampingFactor': {
return createType('PalletProposalsCodexProposalDetails', {
setEraPayoutDampingFactor: createType('Percent', specifics?.setEraPayoutDampingFactor?.dampingFactor ?? 100),
})
}
case 'decreaseCouncilBudget': {
return createType('PalletProposalsCodexProposalDetails', {
DecreaseCouncilBudget: specifics.decreaseCouncilBudget?.amount,
Expand Down
Loading
Loading