NNS Updates: Nov 8, 2024

The Governance Team submitted the following proposal to Upgrade NNS Governance. DFINITY plans to vote on these proposals the following Monday.

https://dashboard.internetcomputer.org/proposal/134043

# Upgrade the Governance Canister to Commit 0f96a6f

__Proposer__: arshavir.ter.gabrielyan at dfinity.org

__Source code__: [0f96a6f4661f0d87bd9149a88846db9674360291][new-commit]

[new-commit]: https://github.com/dfinity/ic/tree/0f96a6f4661f0d87bd9149a88846db9674360291

## New Commits

```
$ git log --format="%C(auto) %h %s" aa91ecacdf3824e193e21b70e0127e8d3edab51a..0f96a6f4661f0d87bd9149a88846db9674360291 --  ./rs/nns/governance ./rs/sns/init
 4a7913a300 chore(nns): add feature flag for stable following index (#2474)
 67e2ff4a50 feat(nns): Added total_potential_voting_power to proposals. (#2375)
 7927c348c7 feat(nns): Make distinction between potential and deciding voting power. (#2339)
 52e5c5a9c5 chore(nns): Cleanup internal types that should not be in API (#2430)
 b588a681ef chore(nns): remove governance api--test-feature bazel target (#2394)
 f2b767f156 fix(nns): validate dissolve state and age before saving neuron (#2222)
 ce465b8bd9 fix: Make NNS init .csv parser recognize `dissolve_delay_s` and `maturity_e8s_equivalent` values again (#2384)
 a52f966827 feat(nns): Refresh voting power. (#2320)
 de1e62b8c6 feat(nns): Added Neuron::voting_power_refreshed_timestamp_seconds field. (#2268)
 c0b2ec6580 chore(sns): Rename sale → swap in various places. (#2267)
```


## Current Version

__Current git hash__: aa91ecacdf3824e193e21b70e0127e8d3edab51a

__Current wasm hash__: 18ca5b86271c76459f249c87d80c9e0172e09f64e18c04cf1c28d95f3489de4e


## Verification

See the general instructions on [how to verify] proposals like this. A "quick
start" guide is provided here.

[how to verify]: https://github.com/dfinity/ic/tree/0f96a6f4661f0d87bd9149a88846db9674360291/rs/nervous_system/docs/proposal_verification.md


### WASM Verification

See ["Building the code"][prereqs] for prerequisites.

[prereqs]: https://github.com/dfinity/ic/tree/0f96a6f4661f0d87bd9149a88846db9674360291/README.adoc#building-the-code

```
# 1. Get a copy of the code.
git clone git@github.com:dfinity/ic.git
cd ic
# Or, if you already have a copy of the ic repo,
git fetch
git checkout 0f96a6f4661f0d87bd9149a88846db9674360291

# 2. Build canisters.
./ci/container/build-ic.sh -c

# 3. Fingerprint the result.
sha256sum ./artifacts/canisters/governance-canister.wasm.gz
```

This should match `wasm_module_hash` field of this proposal.
1 Like

Review Proposal 134043

Screenshot 2024-11-11 at 08.28.40

Args, wasm hash, install mode, and canister id are all correct/reproducible.

The code update introduces a voting_power_refreshed_timestamp_seconds field within the Neuron struct, which tracks the last point at which a neuron’s voting power was refreshed. This addition aims to enforce voting power degradation for neurons that have not voted or set followees recently. If the voting_power_refreshed_timestamp_seconds field is older than six months, the neuron’s voting power starts to decrease linearly over one month until it reaches zero, which clears non-ManageNeuron followers.

The constant DEFAULT_VOTING_POWER_REFRESHED_TIMESTAMP_SECONDS initializes unrefreshed neurons, and a new flag, IS_VOTING_POWER_ADJUSTMENT_ENABLED, toggles the adjustment.

No issue was found in the code diffs.

1 Like

Proposal #134043

Vote: Adopted
Reason: Builds fine and hash matches, as do all the listed commits.

Review:

4a7913a300 chore(nns): add feature flag for stable following index (#2474)
Temporary feature flag USE_STABLE_MEMORY_FOLLOWING_INDEX is added that will be used for supporting stable neurons, until migration is complete.

67e2ff4a50 feat(nns): Added total_potential_voting_power to proposals. (#2375)
As part of the new periodic confirmation it adds total_potential_voting_power to be used as the baseline for voting rewards in case all neurons are refreshed. This is used along with the distinction between Potential voting power vs. Deciding voting power to make sure refreshed neurons get the same rewards while the rest will get decreased.
Interesting to see the Weird Special Case: ManageNeuron proposals.
The total_potential_voting_power function calculates the total potential voting power both for standard and for ManageNeuron proposals that follow special voting rules: only followers of the neuron being managed can vote, and they each get exactly 1 voting power, regardless of their refresh status. This special rule is enforced by returning ballots_len as the total potential voting power.
The test_total_potential_voting_power function tests the total_potential_voting_power function using multiple scenarios to verify correct voting power calculations. It checks both the normal and special cases for the ManageNeuron proposal type, as well as confirm behavior over time.

7927c348c7 feat(nns): Make distinction between potential and deciding voting power. (#2339)
Another part of periodic confirmation. Done by adding deciding_voting_power method and renaming voting_power method to potential_voting_power, and also the addition of a flag for adjustmemts by deciding_voting_power to be used in testing.
The deciding_voting_power_adjustment_factor function is used to calculate an adjustment factor for voting power based on how long it has been since a neuron’s voting power was last refreshed. This adjustment factor decreases linearly from 1 to 0 as the duration since the last refresh extends from 6 to 7 months, representing a gradual reduction in voting power over this period.
And the deciding_voting_power function calculates the effective voting power of a neuron when casting a vote, taking into account a potential adjustment factor based on how recently the neuron’s voting power was refreshed.

52e5c5a9c5 chore(nns): Cleanup internal types that should not be in API (#2430)
Simple cleanup of unused code.
b588a681ef chore(nns): remove governance api–test-feature bazel target (#2394)
Removed unused code.
f2b767f156 fix(nns): validate dissolve state and age before saving neuron (#2222)
The added validate function for DissolveStateAndAge performs a round-trip conversion to check the internal consistency of the struct’s data, verifying its validity before it’s used.
While validate_neuron function makes sure that any neuron passed to it has a valid dissolve state and age.
ce465b8bd9 fix: Make NNS init .csv parser recognize dissolve_delay_s and maturity_e8s_equivalent values again (#2384)
dissolve_delay_s and maturity_e8s_equivalent are added to neurons init.
a52f966827 feat(nns): Refresh voting power. (#2320)
Again part of the periodic confirmation. To be used to reduce the voting power for neurons that weren’t refreshed.
Adds the refresh_voting_power function to update the voting power of a specified neuron based on the current time.
The DEFAULT_VOTING_POWER_REFRESHED_TIMESTAMP_SECONDS constant is set to 1731628801 that corresponds to November 15, 2024, 00:00:01 UTC.
de1e62b8c6 feat(nns): Added Neuron::voting_power_refreshed_timestamp_seconds field. (#2268)
Matches description.

c0b2ec6580 chore(sns): Rename sale → swap in various places. (#2267)
Simple rename of sale to swap.

1 Like

Proposal 134043

Vote: ADOPT

Reason: Build is successful and hashes match, I’ve checked all commits and the changes are sound. This build is particularly interesting as it contains many commit related to the periodic confirmation feature, which is nice to see.

134043

Reviews

4a7913a300 Added USE_STABLE_MEMORY_FOLLOWING_INDEX feature flag, its status is set based on whether the canister is built in test mode. Also created a getter and test methods to enable/disable it. Added annotations to other methods used to toggle feature flags to make them only available when running integration tests.

67e2ff4a50 Added total_potential_voting_power field to ProposalInfo and ProposalData structs, this field is necessary once periodic confirmation is implemented to keep rewards calculation working as they should. In make_proposal method the value is processed by summing the potential voting power, i.e VP without any scaling factor, of all neurons eligible to vote.

7927c348c7 Added IS_VOTING_POWER_ADJUSTMENT_ENABLED feature flag alongside a getter and test methods to toggle it, the flag is used to switch between current voting power calculation logic and the new one being developed as part of the periodic confirmation feature, which has neuron losing VP after a period of inactivity. A new method has also been added to the Neuron struct called deciding_voting_power_adjustment_factor, this is used to determine the scaling factor to apply to a neuron based on how long it has been inactive for.

In compute_ballots_for_new_proposal the method used to calculate a neuron’s vp has been replaced with the new deciding_voting_power, if the feature flag is enabled it calculates the scaling factor to apply if any, otherwise preserves current behaviour.

52e5c5a9c5 Removed AbridgedNeuron struct and its protobuf conversion logic from nns governance API.

b588a681ef Remove deprecated bazel target.

f2b767f156 Perform validation check before adding a neuron to the NeuronStore to ensure it can be retrieved from stable memory.

ce465b8bd9 Updated add_all_neurons_from_csv_file to recognize dissolve_delay_s and maturity_e8s_equivalent values again. Added values for said fields to test CSVs.

a52f966827 Refresh voting_power_refreshed_timestamp_seconds field of a neuron whenever a vote is cast manually, its follow settings are updated or a proposal is submitted by it.

[de1e62b8c6] Added voting_power_refreshed_timestamp_seconds field to neuron, this will be used to track last time the neuron was “manually” interacted with, the value of the field is optional and when trying to unwrap it, if it is empty DEFAULT_VOTING_POWER_REFRESHED_TIMESTAMP_SECONDS is returned, this is an arbitrary timestamp, which will be used as a starting point for all neurons for the inactivity timer once the feature is enabled.

c0b2ec6580 Simple renaming.

2 Likes

Proposal 134043

Vote: ADOPT

Reason:
Build successful and hashes match, commits look great and found no issues.

Review:

[4a7913a300]: Adds a temporary feature flag USE_STABLE_MEMORY_FOLLOWING_INDEX that will be used to support stable neurons until migration is completed.

[67e2ff4a50]: A new method total_potential_voting_power calculates the total amount of voting power that would be available if all the neurons kept themselves refreshed. This is used as a baseline for neuron rewards as it makes that neurons that are refreshed continue to get the same rewards as they would previously get and those that are not get a smaller amount. There is a special case for ManageNeuron where the voting power for all neurons regardless if they are refreshed or not is 1 and there are no rewards, as such the function total_potential_voting_power in this case only returns ballots_len.

[7927c348c7]: Renames the previously known voting_power of a neuron to potential_voting_power and introduces a new method deciding_voting_power. This new method is controlled by a feature flag is_voting_power_adjustment_enabled that when disabled (default), the voting power equals potential_voting_power and when enabled (only on tests) deciding_voting_power. The deciding_voting_power makes so that there is an adjustment_factor to the voting power based on the voting_power_refreshed_timestamp_seconds.

[52e5c5a9c5]: Cleanup of internal types that aren’t needed.

[b588a681ef]: Removes governance api–test-feature bazel target

[f2b767f156]: Fixes a bug where malformed neurons would be inaccessible after being written to stable storage. This was caused when a neuron’s DissolveState was set to
WhenDissolvedTimestampSeconds(0) and the translation would panic. To solve this it was implemented a validation of the neuron before being written to the stable storage. A new method validate is introduced in the DissolveStateAndAge type to ensure that the neuron’s state and ages are consistent and is used in the new method validate_neuron that validates neurons before they are added or updated to store.

[ce465b8bd9]: Updates the function add_all_neurons_from_csv_file to recognize again the fields dissolve_delay_s and maturity_e8s_equivalent.

[a52f966827]: Implements the function refresh_voting_power to implement the logic of refreshing a neuron’s voting power whenever this votes directly or updates it’s list of followees.

[de1e62b8c6]: Added the field voting_power_refreshed_timestamp_seconds to the Neuron and NeuronInfo structs. This field will track the last time a neuron’s voting power was refreshed with the intent of reducing it’s voting power down to 0 each month after a 6 months period of inactivity. For newly created Neurons this value will be populated with created_timestamp_seconds but for neurons created prior to this feature they will be populated with the constant DEFAULT_VOTING_POWER_REFRESHED_TIMESTAMP_SECONDS that has the value one second after midnight, 2024-11-05 (UTC) this being an approximation of the time when this feature is released.

[c0b2ec6580]: Renaming sale to swap in function and comments across multiple files.