feat: Add blockchain submission to simple vote endpoint

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 <noreply@anthropic.com>
This commit is contained in:
Alexis Bruneteau 2025-11-07 16:34:24 +01:00
parent 67199379ed
commit 1910b5c87b

View File

@ -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
}