Dfx nns local proposal fail "Cannot compute Neurons' Fund participation intervals"

When I submit SNS proposal on a local replica started with dfx and on which the NNS governance has been deployed using dfx nns install, I get following error:

2024-07-10 15:11:27.941557 UTC: [Canister rrkah-fqaaa-aaaaa-aaaaq-cai] [Governance] Execution of proposal: 6 failed. Reason: GovernanceError { error_type: InvalidProposal, error_message: “Error while computing eligibility intervals: Cannot compute Neurons’ Fund participation intervals, as total_maturity_equivalent_icp_e8s = 0.” } (Proposal title: Some(“NNS Proposal to create an SNS named ‘CYCLES-TRANSFER-STATION’”))

Resulting in all proposals to fails.

How can this error be resolved?

Note that the SNS.yaml file describe the participation to the fund as following:

 # Whether Neurons' Fund participation is requested.
neurons_fund_participation: true

So that’s why I expect this to work locally.

Thanks @aterga for helping me understand this error. This is actually expected in the sense that I cannot propose an SNS that uses the neuron funds locally if there is no neuron with maturity participating in the neuron funds, as I’m starting from an empty state.

Therefore, to resolve the issue, two things need to be done.

1. Participate to neuron fund

First, in the local NNS dapp, open the neuron I’m using for test purposes and set Participate in neuron's fund.

2. Get Maturity

The neuron needs maturity, so sure, I can wait, but that’s probably not what one wants to do when testing locally. Fortunately, there is a solution to speed up things, as when spun locally, the Governance canister is deployed with a handy function update_neuron that can be used to set any fields of the neuron (as long as the one making the request is a controller or hotkey of the neuron).

There is probably a way to do that with dfx and stuff, but given that I’ve got no clue about those tools, I wrote a JS script.

#!/usr/bin/env node

import { assertNonNullish } from '@dfinity/utils';
import { copyFileSync } from 'node:fs';
import { join } from 'node:path';
import { getGovernanceActor, getGovernanceTestActor } from './actor.utils.mjs';

const governanceCanisterId = 'rrkah-fqaaa-aaaaa-aaaaq-cai';

copyFileSync(
	join(process.cwd(), 'node_modules/@dfinity/nns/dist/candid/governance.idl.js'),
	join(process.cwd(), 'node_modules/@dfinity/nns/dist/candid/governance.idl.mjs')
);

copyFileSync(
	join(process.cwd(), 'node_modules/@dfinity/nns/dist/candid/governance_test.idl.js'),
	join(process.cwd(), 'node_modules/@dfinity/nns/dist/candid/governance_test.idl.mjs')
);

const updateNeuron = async () => {
	const [, , neuronId] = process.argv;

	assertNonNullish(neuronId);

	const { get_full_neuron } = await getGovernanceActor(governanceCanisterId);

	const neuron = await get_full_neuron(BigInt(neuronId));

	console.log('Current neuron', neuron.Ok);

	const updateNeuron = {
		...neuron.Ok,
		maturity_e8s_equivalent: 100_000_000_000_000n
	};

	const { update_neuron } = await getGovernanceTestActor(governanceCanisterId);
	await update_neuron(updateNeuron);
};

await updateNeuron();

Just copying the above code won’t work. Check out the repo for everything: https://github.com/peterpeterparker/proposals.network

1 Like

Thanks for the summary.

Note that since you call the test-only update_neuron endpoint anyway, you should be able to skip the first (manual) step by setting the joined_community_fund_timestamp_seconds field (to some non-zero timestamp) in the second step.

1 Like

Oh cool! Thanks for the tips.