[NNS Voting Error] NNS App UI shows error when voting every time

Issue: Today, every single time I tried to vote on a proposal I received an error message (See screenshot at bottom of post)

What I did to trigger this error: I checked the “Hide Open proposals where all your neurons have voted or are ineligible to vote”, and my voting tab showed 9 proposals that I had not yet voted on. Each time I then attempted to vote on a proposal, I received the following error.

“Sorry, there was an error while registering the vote. Please try again. XXX Neuron already voted on proposal. XXX Neuron already voted on proposal”

Potential Reprocussions: This either is an error by the frontend in loading proposals that have already been voted on by my neuron through my followees, or an error in submitting my vote to the NNS, the later of which is obviously much worse, but it is still a high priority bug regardless as it leads to the voter wondering if their vote was counted and the integrity of the voting system. I’d be happy to give DFINITY an ID of a neuron which voted in a private message to help aid in this investigation.




Smaller bug: As an additional smaller but noticeable error, I’m receiving the following errors in my console when opening up a proposal from the voting tab. My browser is Safari.

1 Like

Since this may not get looked at until Monday (and then it may take time to investigate), I’d recommend trying a different browser or device at least in the interim, see if that allows you to vote or see if the votes are already cast.

I also have the same issue since the latest upgrade.
This only happens when I vote Reject.
My device is iphone xs

You can go to the page for a neuron at https://dashboard.internetcomputer.org/ to see how it voted on recent proposals. You can either do this for the neurons you’re following (to check “proposals that have already been voted on by my neuron through my followees”) or for one of your own neurons.

1 Like

Can confirm this also happens on firefox, whether I choose ‘adopt’ or ‘reject’

Thanks for the details @justmythoughts. We are aware of the issue and are on it. Debugging it and finding a solution is one of our priority at the moment.

Regarding “Portentially serious NNS error” I tend to be a bit moderate about it. Like you said it is most probably a UI error that loads a proposal for which you actually indeed already had voted that ultimately leads to display the error message - backend behaves correctly and the error message is indeed in that case expected. Still have to be proven of course but that’s my current assumption.

Being said and don’t misunderstand me, I don’t like the error. Like I said, we are still debugging it. We will report as soon as we get some findings.

Meanwhile if anyone can share an exact “step by step” description that leads (from not having the issue to having it), that would be useful.

Thanks for responding and looking into this during Easter weekend.

I’ll make a screen recording of my next vote and if I run into the issue again I’ll send it to you in a DM - hopefully that helps.

That would be awesome!!! I have tried again in test and on mainnet with my personal neuron this morning and couldn’t replicate the issue :disappointed_relieved:. Typically sounds like the kind of issue that is harder for the developer to reproduce than to fix.

May I ask, you and others:

  • are you voting with multiple neurons? if yes, is one of these displayed with a voting power === 0?
  • you are facing the issue with neuron that are created from main/sub-accounts or are you using hardware wallets? don’t think it would be related but I did not use a hardware wallet yet in my test

Thanks in advance for the help.

Yes

No

Neurons were created from a main account which was created through the NNS dapp. (No hardware…yet)

All of my neurons follow a single neuron which has multiple default followees

Also, if this helps localize the issue I did not have this issue prior to the date of the bug post. I vote 2-3 times per week.

Ok, I will get a video to you within the next 10-12 hrs as I’m currently in bed about to konk out :sweat_smile: :yawning_face:

Thanks for the answer, I did not added this to my test setup, something I should do, who knows.

Haha tomorrow is all fine. Today is holiday afterall and in any case any help is appreciated any time. Enjoy your morning

Was able to reproduce the error with a screen recording - sent you a private message with the information.

1 Like

Quick update: event though we tried lots of scenarios, we were not able to reproduce the issue on our testnet (of course, that would have been too easy :crazy_face:). However we were able to simulate it. Indeed if we call back to back the “register vote” backend endpoint twice with the same neuron id, we do get above issue. That’s why, at least in a first step, we gonna provide a PR (#721) that ensure the neuron ids we use to call the register vote feature are unique - i.e. one call per neuron id. In addition, the PR also adds some client side tracing information (“console.log”) to make the debugging easier. It will ease our communication if there is (still) an issue to analyze. We will now finish work, test the app and then propose it. I’ll of course update the thread.

Side note: the error message is effectively thrown by the backend - the governance canister (link to code). When I simulated the error with two queries back to back my votes were correctly cast.

1 Like

I tested out a few things when voting today since there were like 5 NNS proposals and think the bug is double voting (as you had mentioned).

This is my hypothesis - lets take the following example:

We have neurons A, B, and C:

Neurons B and C follow neuron A

When A, B, and C vote

  • if B and C are updated first, then (probably) we have no problem as A then just votes itself.
  • if A is updated first, it also starts to update each of its followers’ votes. If this dependency-type update happens before B and C’s requests have hit the backend and updated their votes, then B and C’s requests are rejected, and we get the error on the frontend.

To fix this issue, and to remove the need for double requests, I propose the following solution (that should be fun to implement as well).

Before a user in the NNS app votes, hold the entire dependency tree of just the specific user’s neurons (not external followees) in the app.

In this case, you’d store something like

               A
              / \
             B   C

Then, when the user votes you walk the dependency tree for each “checked” user neuron that is casting a vote down their subtree, adding all neurons in their subtree to a set (unique neurons). Then you only vote with the set of unique “checked” parent nodes, who’s votes will be sent to the NNS which will then propagate those votes to all of the checked children nodes.

Here’s a more complicated example to illustrate the implementation (with more neurons and the followee dependency tree)

        A                   G              J            K
       / \                 /
      B   C               H
     /  \  \             /
    D    E  F           I

In this example, neurons B, D, F, G, I, and K are checked and vote.

Lets say we iterate through the neurons in the order B, D, F, I, G, K

  • B is checked, so we add B to the parent set, and its children D and E to a “visited” child set
  • D is checked and has no children, but it is present in the child set (it has already been added by B) so we don’t add it to the parent set (will be covered by B voting)
  • F is checked and has no children, so we add it to the parent set
  • I is checked and has no children, so we add it to the parent set
  • G is checked, so we add G to the set, and its children H and I to the “visited” child set. For each child we visit, we attempt remove it from the parent set if it exists there. I exists in the parent set, so we remove it from the parent set.
  • K is checked and has no children, so we add it to the parent set

Then we vote with the neurons that have been added to the parent set: { B, F, G, K }, and the NNS ends up casting votes for B, D, E, F, G, H, I, and K.

This way, you eliminate any race conditions and need for a second go around trip - plus it eliminates the double voting bug.

5 Likes

Removing “Potentially Serious” from the post topic title, as I now feel more confident that no votes were discounted/missed due to this bug.

That’s the issue, can reproduce it, finally! Thanks for this feedback, it helps a lot.

I share it with the team as your suggestion of solution as well. Agree with you, we have to amend the “followee” dependency tree to avoid unnecessary votes.

Will report and keep the post updated.

Again, thanks a lot :pray:

1 Like

Once we were able to reproduce the issue, we analyzed it further and actually noticed that this error (actually an information, since all votes are cast correctly) was not new and already existed in the Flutter version of the app. However, the error was ignored, therefore not presented to the user and silent.

We discussed different ways to process the neurons tree on the frontend side to query the backend with only unique neurons but any solution also need in our opinions UX improvements as user should also be made aware of the relations between the neurons when voting.

That’s why we decided to postpone such a tasky enhancements for the future and for now on, to ignore safely the error message that is again actually an information.

The related PR is #726 and we will propose it with next version of nns-dapp.

A big shout out to @justmythoughts that found the root cause of the issue. Not all heroes wear capes!

1 Like

The new version of nns-dapp is now live. This issue should be fixed as described above.
Please let me know if it works out :crossed_fingers:

2 Likes

The error disappeared, thanks :clap:

2 Likes

Cool! Happy to hear that, thanks for the feedback

Reminded me of this ; )

1 Like