@@ -261,6 +261,7 @@ def test_proposal_storage(network, args):
261261 "proposalState" : "Open" ,
262262 "proposalId" : proposal_id ,
263263 "ballotCount" : 0 ,
264+ "ballotSubmitters" : [],
264265 }
265266 assert r .body .json () == expected , r .body .json ()
266267
@@ -306,6 +307,7 @@ def test_proposal_withdrawal(network, args):
306307 "proposalState" : "Open" ,
307308 "proposalId" : proposal_id ,
308309 "ballotCount" : 0 ,
310+ "ballotSubmitters" : [],
309311 }
310312 assert r .body .json () == expected , r .body .json ()
311313
@@ -316,6 +318,7 @@ def test_proposal_withdrawal(network, args):
316318 "proposalState" : "Withdrawn" ,
317319 "proposalId" : proposal_id ,
318320 "ballotCount" : 0 ,
321+ "ballotSubmitters" : [],
319322 }
320323 assert r .body .json () == expected , r .body .json ()
321324
@@ -405,6 +408,8 @@ def test_pure_proposals(network, args):
405408 r = c .post ("/gov/members/proposals:create" , prop )
406409 assert r .status_code == 200 , r .body .text ()
407410 assert r .body .json ()["proposalState" ] == state , r .body .json ()
411+ assert "finalVotes" in r .body .json (), r .body .json ()
412+ assert r .body .json ()["finalVotes" ] == {}, r .body .json ()
408413 proposal_id = r .body .json ()["proposalId" ]
409414
410415 ballot = ballot_yes
@@ -568,6 +573,10 @@ def test_proposals_with_votes(network, args):
568573 )
569574 assert r .status_code == 200 , r .body .text ()
570575 assert r .body .json ()["proposalState" ] == state , r .body .json ()
576+ assert "finalVotes" in r .body .json (), r .body .json ()
577+ assert r .body .json ()["finalVotes" ] == {
578+ member_id : direction == "true"
579+ }, r .body .json ()
571580
572581 infra .clients .get_clock ().advance ()
573582
@@ -585,6 +594,10 @@ def test_proposals_with_votes(network, args):
585594 )
586595 assert r .status_code == 200 , r .body .text ()
587596 assert r .body .json ()["proposalState" ] == state , r .body .json ()
597+ assert "finalVotes" in r .body .json (), r .body .json ()
598+ assert r .body .json ()["finalVotes" ] == {
599+ member_id : direction == "true"
600+ }, r .body .json ()
588601
589602 for prop , state , ballot in [
590603 (always_accept_with_two_votes , "Accepted" , ballot_yes ),
@@ -593,6 +606,7 @@ def test_proposals_with_votes(network, args):
593606 r = c .post ("/gov/members/proposals:create" , prop )
594607 assert r .status_code == 200 , r .body .text ()
595608 assert r .body .json ()["proposalState" ] == "Open" , r .body .json ()
609+ assert r .body .json ()["ballotSubmitters" ] == [], r .body .json ()
596610 proposal_id = r .body .json ()["proposalId" ]
597611
598612 r = c .post (
@@ -601,6 +615,7 @@ def test_proposals_with_votes(network, args):
601615 )
602616 assert r .status_code == 200 , r .body .text ()
603617 assert r .body .json ()["proposalState" ] == "Open" , r .body .json ()
618+ assert r .body .json ()["ballotSubmitters" ] == [member_id ], r .body .json ()
604619
605620 with node .api_versioned_client (
606621 None , None , "member1" , api_version = args .gov_api_version
@@ -614,6 +629,16 @@ def test_proposals_with_votes(network, args):
614629 )
615630 assert r .status_code == 200 , r .body .text ()
616631 assert r .body .json ()["proposalState" ] == state , r .body .json ()
632+ assert set (r .body .json ()["ballotSubmitters" ]) == {
633+ member_id ,
634+ other_member_id ,
635+ }, r .body .json ()
636+ assert "finalVotes" in r .body .json (), r .body .json ()
637+ expected_vote = state == "Accepted"
638+ assert r .body .json ()["finalVotes" ] == {
639+ member_id : expected_vote ,
640+ other_member_id : expected_vote ,
641+ }, r .body .json ()
617642
618643 return network
619644
@@ -640,34 +665,38 @@ def test_vote_failure_reporting(network, args):
640665 with node .api_versioned_client (
641666 None , None , "member0" , api_version = args .gov_api_version
642667 ) as c :
643- member_id = network .consortium .get_member_by_local_id ("member0" ).service_id
668+ member0_id = network .consortium .get_member_by_local_id ("member0" ).service_id
644669 r = c .post ("/gov/members/proposals:create" , always_accept_with_one_vote )
645670 assert r .status_code == 200 , r .body .text ()
646671 assert r .body .json ()["proposalState" ] == "Open" , r .body .json ()
672+ assert r .body .json ()["ballotSubmitters" ] == [], r .body .json ()
647673 proposal_id = r .body .json ()["proposalId" ]
648674
649675 ballot = vote (f'throw new Error("{ error_body } ")' )
650676 r = c .post (
651- f"/gov/members/proposals/{ proposal_id } /ballots/{ member_id } :submit" , ballot
677+ f"/gov/members/proposals/{ proposal_id } /ballots/{ member0_id } :submit" , ballot
652678 )
653679 assert r .status_code == 200 , r .body .text ()
654680 assert r .body .json ()["proposalState" ] == "Open" , r .body .json ()
681+ assert r .body .json ()["ballotSubmitters" ] == [member0_id ], r .body .json ()
655682
656683 with node .api_versioned_client (
657684 None , None , "member1" , api_version = args .gov_api_version
658685 ) as c :
659686 ballot = ballot_yes
660- member_id = network .consortium .get_member_by_local_id ("member1" ).service_id
687+ member1_id = network .consortium .get_member_by_local_id ("member1" ).service_id
661688 r = c .post (
662- f"/gov/members/proposals/{ proposal_id } /ballots/{ member_id } :submit" , ballot
689+ f"/gov/members/proposals/{ proposal_id } /ballots/{ member1_id } :submit" , ballot
663690 )
664691 assert r .status_code == 200 , r .body .text ()
665692 rj = r .body .json ()
666693 LOG .warning (rj )
667694 assert rj ["proposalState" ] == "Accepted" , r .body .json ()
695+ assert set (rj ["ballotSubmitters" ]) == {member0_id , member1_id }, rj
696+ assert "finalVotes" in rj , rj
697+ assert rj ["finalVotes" ] == {member1_id : True }, rj
668698 assert len (rj ["voteFailures" ]) == 1 , rj ["voteFailures" ]
669- member_id = network .consortium .get_member_by_local_id ("member0" ).service_id
670- assert rj ["voteFailures" ][member_id ]["reason" ] == f"Error: { error_body } " , rj [
699+ assert rj ["voteFailures" ][member0_id ]["reason" ] == f"Error: { error_body } " , rj [
671700 "voteFailures"
672701 ]
673702
@@ -692,6 +721,7 @@ def test_operator_proposals_and_votes(network, args):
692721 )
693722 assert r .status_code == 200 , r .body .text ()
694723 assert r .body .json ()["proposalState" ] == "Accepted" , r .body .json ()
724+ assert r .body .json ()["finalVotes" ] == {member_id : True }, r .body .json ()
695725
696726 r = c .post (
697727 "/gov/members/proposals:create" , always_accept_if_proposed_by_operator
@@ -1392,10 +1422,20 @@ def test_final_proposal_visibility(network, args):
13921422 LOG .info ("Confirm that finalVotes is present in submit-ballot response" )
13931423 body = response .body .json ()
13941424 assert "finalVotes" in body , body
1425+ assert set (body ["ballotSubmitters" ]) == {
1426+ booster .service_id ,
1427+ turncoat .service_id ,
1428+ fairweather .service_id ,
1429+ }, body
13951430
13961431 LOG .info ("Confirm that finalVotes is present in get-proposal response" )
13971432 body = consortium .get_proposal_raw (primary , third .proposal_id )
13981433 assert "finalVotes" in body , body
1434+ assert set (body ["ballotSubmitters" ]) == {
1435+ booster .service_id ,
1436+ turncoat .service_id ,
1437+ fairweather .service_id ,
1438+ }, body
13991439
14001440 LOG .info ("Confirm that expected values were actually written to the KV" )
14011441 # To avoid creating an extra endpoint in the app, we smuggle a read into a new
0 commit comments