diff --git a/packages/nns/README.md b/packages/nns/README.md index 7504e0407..6f36f471e 100644 --- a/packages/nns/README.md +++ b/packages/nns/README.md @@ -96,7 +96,7 @@ Parameters: - `params.neurons`: The neurons to filter. - `params.proposal`: The proposal to match against the selected neurons. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/nns/src/utils/neurons.utils.ts#L39) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/nns/src/utils/neurons.utils.ts#L29) #### :gear: votableNeurons @@ -111,22 +111,22 @@ Parameters: - `params.neurons`: The neurons to filter. - `params.proposal`: The proposal to match against the selected neurons. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/nns/src/utils/neurons.utils.ts#L68) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/nns/src/utils/neurons.utils.ts#L58) #### :gear: votedNeurons Filter the neurons that have voted for a proposal. -| Function | Type | -| -------------- | ------------------------------------------------------------------------------------------------------------------ | -| `votedNeurons` | `({ neurons, proposal: { id: proposalId }, }: { neurons: NeuronInfo[]; proposal: ProposalInfo; }) => NeuronInfo[]` | +| Function | Type | +| -------------- | ---------------------------------------------------------------------------------------------- | +| `votedNeurons` | `({ neurons, proposal, }: { neurons: NeuronInfo[]; proposal: ProposalInfo; }) => NeuronInfo[]` | Parameters: - `params.neurons`: The neurons to filter. - `params.proposal`: The proposal for which some neurons might have already voted. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/nns/src/utils/neurons.utils.ts#L94) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/nns/src/utils/neurons.utils.ts#L81) ### :factory: GenesisTokenCanister diff --git a/packages/nns/src/utils/neurons.utils.spec.ts b/packages/nns/src/utils/neurons.utils.spec.ts index b46df30d5..eba6d7bc7 100644 --- a/packages/nns/src/utils/neurons.utils.spec.ts +++ b/packages/nns/src/utils/neurons.utils.spec.ts @@ -40,169 +40,166 @@ describe("neurons-utils", () => { } as unknown as NeuronInfo, ]; - const eligibleNeuronsDate: NeuronInfo[] = [ + const eligibleNeuronsData: NeuronInfo[] = [ { createdTimestampSeconds: proposalTimestampSeconds - BigInt(1), neuronId: proposalNeuronId, recentBallots: [], votingPower: BigInt(1), } as unknown as NeuronInfo, + { + createdTimestampSeconds: proposalTimestampSeconds - BigInt(2), + neuronId: proposalNeuronId + 1n, + recentBallots: [], + votingPower: BigInt(1), + } as unknown as NeuronInfo, + { + createdTimestampSeconds: proposalTimestampSeconds - BigInt(3), + neuronId: proposalNeuronId + 2n, + recentBallots: [], + votingPower: BigInt(1), + } as unknown as NeuronInfo, ]; - it("should has an ineligible neuron because created after proposal", () => { - const ineligible = ineligibleNeurons({ - proposal, - neurons: ineligibleNeuronsDate, + describe("ineligibleNeurons", () => { + it("should has an ineligible neuron because created after proposal", () => { + const ineligible = ineligibleNeurons({ + proposal, + neurons: ineligibleNeuronsDate, + }); + expect(ineligible.length).toEqual(1); }); - expect(ineligible.length).toEqual(1); - }); - it("should has an ineligible neuron because dissolve too short", () => { - const ineligible = ineligibleNeurons({ - proposal, - neurons: ineligibleNeuronsTooShort, + it("should has an ineligible neuron because dissolve too short", () => { + const ineligible = ineligibleNeurons({ + proposal, + neurons: ineligibleNeuronsTooShort, + }); + expect(ineligible.length).toEqual(1); }); - expect(ineligible.length).toEqual(1); - }); - it("should has not ineligible neuron because empty", () => { - const ineligible = ineligibleNeurons({ proposal, neurons: [] }); - expect(ineligible.length).toEqual(0); + it("should has not ineligible neuron because empty", () => { + const ineligible = ineligibleNeurons({ proposal, neurons: [] }); + expect(ineligible.length).toEqual(0); + }); }); - it("should not have votable neurons because ineligible", () => { - let votable = votableNeurons({ - proposal, - neurons: ineligibleNeuronsDate, + describe("votableNeurons", () => { + it("should not have votable neurons because ineligible", () => { + let votable = votableNeurons({ + proposal, + neurons: ineligibleNeuronsDate, + }); + expect(votable.length).toEqual(0); + + votable = votableNeurons({ + proposal, + neurons: ineligibleNeuronsTooShort, + }); + expect(votable.length).toEqual(0); }); - expect(votable.length).toEqual(0); - votable = votableNeurons({ - proposal, - neurons: ineligibleNeuronsTooShort, + it("should not have votable neurons because already voted", () => { + const votable = votableNeurons({ + proposal, + neurons: [ + { + ...eligibleNeuronsData[0], + recentBallots: [ + { + proposalId, + vote: Vote.No, + }, + ], + }, + ], + }); + expect(votable.length).toEqual(0); }); - expect(votable.length).toEqual(0); - }); - it("should not have votable neurons because already voted", () => { - const votable = votableNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [ + it("should have votable neurons because not yet voted", () => { + const votable = votableNeurons({ + proposal: { + ...proposal, + ballots: [ { - proposalId, - vote: Vote.No, + neuronId: eligibleNeuronsData[0].neuronId, + vote: Vote.Unspecified, + votingPower: BigInt(1), + }, + { + neuronId: eligibleNeuronsData[1].neuronId, + vote: Vote.Yes, + votingPower: BigInt(1), }, - ], - }, - ], - }); - expect(votable.length).toEqual(0); - }); - - it("should have votable neurons because not yet voted", () => { - const votable = votableNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [ { - proposalId: BigInt(4), + neuronId: eligibleNeuronsData[2].neuronId, vote: Vote.No, + votingPower: BigInt(1), }, ], }, - ], - }); - expect(votable.length).toEqual(1); - }); - - it("should have votable neurons because never voted", () => { - const votable = votableNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [], - }, - ], + neurons: eligibleNeuronsData, + }); + expect(votable.length).toEqual(1); + expect(votable).toEqual([eligibleNeuronsData[0]]); }); - expect(votable.length).toEqual(1); - }); - it("should have votable neurons regardless of voting power", () => { - const votable = votableNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [], - votingPower: BigInt(0), - }, - { - ...eligibleNeuronsDate[0], - recentBallots: [], - votingPower: BigInt(1), - }, - { - ...eligibleNeuronsDate[0], - recentBallots: [], - votingPower: BigInt(0), - }, - ], - }); - expect(votable.length).toEqual(3); - }); - - it("should not have voted neurons because votable", () => { - const voted = votedNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [ + it("should have votable neurons regardless of voting power", () => { + const votable = votableNeurons({ + proposal: { + ...proposal, + ballots: [ { - proposalId: BigInt(4), - vote: Vote.No, + neuronId: eligibleNeuronsData[0].neuronId, + vote: Vote.Unspecified, + votingPower: BigInt(0), + }, + { + neuronId: eligibleNeuronsData[1].neuronId, + vote: Vote.Yes, + votingPower: BigInt(1), + }, + { + neuronId: eligibleNeuronsData[2].neuronId, + vote: Vote.Unspecified, + votingPower: BigInt(2), }, ], }, - ], + neurons: eligibleNeuronsData, + }); + expect(votable.length).toEqual(2); + expect(votable).toEqual([eligibleNeuronsData[0], eligibleNeuronsData[2]]); }); - expect(voted.length).toEqual(0); }); - it("should not have voted neurons because never voted", () => { - const voted = votedNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [], - }, - ], - }); - expect(voted.length).toEqual(0); - }); - - it("should have voted neurons because has voted", () => { - const voted = votedNeurons({ - proposal, - neurons: [ - { - ...eligibleNeuronsDate[0], - recentBallots: [ + describe("votedNeurons", () => { + it("should have only voted neurons", () => { + const voted = votedNeurons({ + proposal: { + ...proposal, + ballots: [ + { + neuronId: eligibleNeuronsData[0].neuronId, + vote: Vote.Unspecified, + votingPower: BigInt(1), + }, + { + neuronId: eligibleNeuronsData[1].neuronId, + vote: Vote.Yes, + votingPower: BigInt(1), + }, { - proposalId, + neuronId: eligibleNeuronsData[2].neuronId, vote: Vote.No, + votingPower: BigInt(1), }, ], }, - ], + neurons: eligibleNeuronsData, + }); + expect(voted).toEqual([eligibleNeuronsData[1], eligibleNeuronsData[2]]); }); - expect(voted.length).toEqual(1); }); }); diff --git a/packages/nns/src/utils/neurons.utils.ts b/packages/nns/src/utils/neurons.utils.ts index c9a21677d..0530afd78 100644 --- a/packages/nns/src/utils/neurons.utils.ts +++ b/packages/nns/src/utils/neurons.utils.ts @@ -1,28 +1,18 @@ -import type { Vote } from "../enums/governance.enums"; +import { Vote } from "../enums/governance.enums"; import type { Ballot, - BallotInfo, NeuronInfo, - ProposalId, ProposalInfo, } from "../types/governance_converters"; -const voteForProposal = ({ - recentBallots, - proposalId, +const getNeuronVoteForProposal = ({ + proposal: { ballots }, + neuron: { neuronId }, }: { - recentBallots: BallotInfo[]; - proposalId: ProposalId | undefined; -}): Vote | undefined => { - if (!proposalId) { - return undefined; - } - - const ballot: BallotInfo | undefined = recentBallots.find( - ({ proposalId: id }: BallotInfo) => id === proposalId, - ); - return ballot?.vote; -}; + proposal: ProposalInfo; + neuron: NeuronInfo; +}): Vote | undefined => + ballots.find(({ neuronId: id }) => id === neuronId)?.vote; /** * Filter the neurons that are ineligible to vote to a proposal. @@ -71,18 +61,15 @@ export const votableNeurons = ({ }: { neurons: NeuronInfo[]; proposal: ProposalInfo; -}): NeuronInfo[] => { - const { id: proposalId } = proposal; - - return neurons.filter( - ({ recentBallots, neuronId }: NeuronInfo) => - voteForProposal({ recentBallots, proposalId }) === undefined && +}): NeuronInfo[] => + neurons.filter( + (neuron: NeuronInfo) => + getNeuronVoteForProposal({ proposal, neuron }) === Vote.Unspecified && ineligibleNeurons({ neurons, proposal }).find( ({ neuronId: ineligibleNeuronId }: NeuronInfo) => - ineligibleNeuronId === neuronId, + ineligibleNeuronId === neuron.neuronId, ) === undefined, ); -}; /** * Filter the neurons that have voted for a proposal. @@ -93,12 +80,12 @@ export const votableNeurons = ({ */ export const votedNeurons = ({ neurons, - proposal: { id: proposalId }, + proposal, }: { neurons: NeuronInfo[]; proposal: ProposalInfo; }): NeuronInfo[] => neurons.filter( - ({ recentBallots }: NeuronInfo) => - voteForProposal({ recentBallots, proposalId }) !== undefined, + (neuron: NeuronInfo) => + getNeuronVoteForProposal({ proposal, neuron }) !== Vote.Unspecified, );