From 1910b5c87bd25e5afd19c0b18267d35c56822c4b Mon Sep 17 00:00:00 2001 From: Alexis Bruneteau Date: Fri, 7 Nov 2025 16:34:24 +0100 Subject: [PATCH] feat: Add blockchain submission to simple vote endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The POST /api/votes endpoint (used by frontend) was recording votes in the database but NOT submitting them to the PoA blockchain. This caused votes to appear in database but not on the blockchain. Changes: - Add vote submission to PoA validators in the simple endpoint - Add fallback to local blockchain if PoA validators unreachable - Include blockchain status in API response - Use ballot hash as vote data for blockchain submission This ensures votes are now submitted to the PoA blockchain when the frontend votes, and users can see their votes on the blockchain. 🤖 Generated with Claude Code Co-Authored-By: Claude --- e-voting-system/backend/routes/votes.py | 57 ++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/e-voting-system/backend/routes/votes.py b/e-voting-system/backend/routes/votes.py index c1f66c2..a9e7bf7 100644 --- a/e-voting-system/backend/routes/votes.py +++ b/e-voting-system/backend/routes/votes.py @@ -112,6 +112,60 @@ async def submit_simple_vote( ip_address=request.client.host if request else None ) + # Generate transaction ID for blockchain + import uuid + transaction_id = f"tx-{uuid.uuid4().hex[:12]}" + + # Submit vote to PoA blockchain + blockchain_client = get_blockchain_client() + await blockchain_client.refresh_validator_status() + + blockchain_response = { + "status": "pending" + } + + try: + async with BlockchainClient() as poa_client: + # Submit vote to PoA network + submission_result = await poa_client.submit_vote( + voter_id=current_voter.id, + election_id=election_id, + encrypted_vote=ballot_hash, # Use ballot hash as data + transaction_id=transaction_id + ) + blockchain_response = { + "status": "submitted", + "transaction_id": transaction_id, + "block_hash": submission_result.get("block_hash"), + "validator": submission_result.get("validator") + } + logger.info( + f"Vote submitted to PoA: voter={current_voter.id}, " + f"election={election_id}, tx={transaction_id}" + ) + except Exception as e: + # Fallback: Record in local blockchain + logger.warning(f"PoA submission failed: {e}. Falling back to local blockchain.") + try: + blockchain = blockchain_manager.get_or_create_blockchain(election_id) + block = blockchain.add_block( + encrypted_vote=ballot_hash, + transaction_id=transaction_id + ) + blockchain_response = { + "status": "submitted_fallback", + "transaction_id": transaction_id, + "block_index": block.index, + "warning": "Vote recorded in local blockchain (PoA validators unreachable)" + } + except Exception as fallback_error: + logger.error(f"Fallback blockchain also failed: {fallback_error}") + blockchain_response = { + "status": "database_only", + "transaction_id": transaction_id, + "warning": "Vote recorded in database but blockchain submission failed" + } + # Mark voter as having voted services.VoterService.mark_as_voted(db, current_voter.id) @@ -119,7 +173,8 @@ async def submit_simple_vote( "message": "Vote recorded successfully", "id": vote.id, "ballot_hash": ballot_hash, - "timestamp": vote.timestamp + "timestamp": vote.timestamp, + "blockchain": blockchain_response }