<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 05:11:14 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[SERVER-46354] Abstract away &apos;votes&apos; and &apos;newlyAdded&apos; fields so it is impossible to mis-count votes</title>
                <link>https://jira.mongodb.org/browse/SERVER-46354</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;Otherwise it would be easy to incorrectly calculate the majority number of the replica set by not considering the &#8216;newlyAdded&#8217; field.&lt;/p&gt;</description>
                <environment></environment>
        <key id="1181470">SERVER-46354</key>
            <summary>Abstract away &apos;votes&apos; and &apos;newlyAdded&apos; fields so it is impossible to mis-count votes</summary>
                <type id="3" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14718&amp;avatarType=issuetype">Task</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="13203">Gone away</resolution>
                                        <assignee username="vesselina.ratcheva@mongodb.com">Vesselina Ratcheva</assignee>
                                    <reporter username="judah.schvimer@mongodb.com">Judah Schvimer</reporter>
                        <labels>
                    </labels>
                <created>Mon, 24 Feb 2020 17:10:14 +0000</created>
                <updated>Fri, 27 Oct 2023 20:42:20 +0000</updated>
                            <resolved>Wed, 10 Jun 2020 05:59:25 +0000</resolved>
                                                                    <component>Replication</component>
                                        <votes>0</votes>
                                    <watches>1</watches>
                                                                                                                <comments>
                            <comment id="3202399" author="vesselina.ratcheva" created="Wed, 10 Jun 2020 05:57:48 +0000"  >&lt;p&gt;I concluded that no changes are needed here, as &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-47091&quot; title=&quot;Make ReplSetConfig and MemberConfig immutable&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-47091&quot;&gt;&lt;del&gt;SERVER-47091&lt;/del&gt;&lt;/a&gt; managed to tighten things a lot here and there are no longer any ways to miscalculate votes.&lt;/p&gt;

&lt;p&gt;In order to find out if an individual node is voting or not, we use either either the &lt;a href=&quot;https://github.com/mongodb/mongo/blob/ad170b9f34c828ec25404f600e95416639e1fecd/src/mongo/db/repl/member_config.h#L145&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;isVoter&lt;/a&gt; or the &lt;a href=&quot;https://github.com/mongodb/mongo/blob/ad170b9f34c828ec25404f600e95416639e1fecd/src/mongo/db/repl/member_config.h#L152&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;getNumVotes&lt;/a&gt; (one uses the other, and the only real difference is that one returns a bool and the other an int). For purposes like write concern satisfiability, we use tags. There was a point where we weren&apos;t updating the tags along with changes to newlyAdded (&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-47499&quot; title=&quot;MemberConfig internal tags are not changed when newlyAdded is changed&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-47499&quot;&gt;&lt;del&gt;SERVER-47499&lt;/del&gt;&lt;/a&gt;), but that was fixed in &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-47091&quot; title=&quot;Make ReplSetConfig and MemberConfig immutable&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-47091&quot;&gt;&lt;del&gt;SERVER-47091&lt;/del&gt;&lt;/a&gt;. The $voter and $configVoter tags themselves uses isVoter (see &lt;a href=&quot;https://github.com/mongodb/mongo/blob/ad170b9f34c828ec25404f600e95416639e1fecd/src/mongo/db/repl/member_config.cpp#L144-L162&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo/blob/ad170b9f34c828ec25404f600e95416639e1fecd/src/mongo/db/repl/member_config.cpp#L144-L162&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The MemberConfig class also has a getNewlyAdded() method, but it is not used outside of it.&lt;/p&gt;

&lt;p&gt;I went through and enumerated/audited all places that I could think of that need some sort of voter check or count. All of them are using the above methods (or derivatives).&lt;/p&gt;

&lt;p&gt;ReplSetConfig:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;validate: uses isVoter&lt;/li&gt;
	&lt;li&gt;checkIfWriteConcernCanBeSatisfied: uses tags&lt;/li&gt;
	&lt;li&gt;_calculateMajorities: uses isVoter, results exposed in the voter count methods we know and love:
	&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
		&lt;li&gt;getMajorityVoteCount()&lt;/li&gt;
		&lt;li&gt;getWriteMajority()&lt;/li&gt;
		&lt;li&gt;getTotalVotingMembers()&lt;/li&gt;
		&lt;li&gt;getWritableVotingMembersCount()&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;_addInternalWriteConcernModes: uses tags&lt;/li&gt;
	&lt;li&gt;votingMembers: uses getNumVotes&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;repl_set_config_checks.cpp:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;validateSingleNodeChange: uses ReplSetConfig::votingMembers() (which uses getNumVotes)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;QuorumChecker:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;constructor: uses isVoter to populate _voters, which is read throughout the file&lt;/li&gt;
	&lt;li&gt;_tabulateHeartbeatResponse: same as above&lt;/li&gt;
	&lt;li&gt;hasReceivedSufficientResponses: uses _voters&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;VoteRequester:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;Algorithm (constructor): uses isVoter to populate _targets, which is read throughout the file&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;TopologyCoordinator: (too many to enumerate, so I&apos;m summarizing some of those)&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;_aMajoritySeemsToBeUp: uses getNumVotes&lt;/li&gt;
	&lt;li&gt;prepareStatusResponse: uses the four counter methods listed above&lt;/li&gt;
	&lt;li&gt;a few other instances of those&lt;/li&gt;
	&lt;li&gt;the rest use isVoter&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;ReplicationCoordinator:&lt;/p&gt;
&lt;ul class=&quot;alternate&quot; type=&quot;square&quot;&gt;
	&lt;li&gt;processReplSetReconfig: uses isVoter&lt;/li&gt;
	&lt;li&gt;doReplSetReconfig: uses isVoter&lt;/li&gt;
	&lt;li&gt;various read/write concern functions that (now) all use tags&lt;/li&gt;
	&lt;li&gt;a few instances of the four horsemen of vote counting&lt;/li&gt;
&lt;/ul&gt;
</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                <customfield id="customfield_10050" key="com.atlassian.jira.toolkit:comments">
                        <customfieldname># Replies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1.0</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18555" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname># of Sprints</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2.0</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10055" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>Date of 1st Reply</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Wed, 10 Jun 2020 05:57:48 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        3 years, 35 weeks ago
    
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18254" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Dependencies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[]]></customfieldvalue>


                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                            <customfield id="customfield_10857" key="com.pyxis.greenhopper.jira:gh-epic-link">
                        <customfieldname>Epic Link</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>PM-1096</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10057" key="com.atlassian.jira.toolkit:lastusercommented">
                        <customfieldname>Last comment by Customer</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>true</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10056" key="com.atlassian.jira.toolkit:lastupdaterorcommenter">
                        <customfieldname>Last commenter</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>luke.bonanomi@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            3 years, 35 weeks ago
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                    <customfield id="customfield_10051" key="com.atlassian.jira.toolkit:participants">
                        <customfieldname>Participants</customfieldname>
                        <customfieldvalues>
                                        <customfieldvalue>judah.schvimer@mongodb.com</customfieldvalue>
            <customfieldvalue>vesselina.ratcheva@mongodb.com</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hwud2v:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hwt3g7:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_23361" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Requested By</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_10557" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue id="3882">Repl 2020-05-18</customfieldvalue>
    <customfieldvalue id="3935">Repl 2020-06-15</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_10053" key="com.atlassian.jira.ext.charting:timeinstatus">
                        <customfieldname>Time In Status</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_22870" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Triagers</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_14350" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>serverRank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hwtzc7:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>