Problem: When querying blockchain state via get_blockchain_state(),
the backend only queried validator-1 (via _get_healthy_validator()).
If validator-1 was behind other validators in block synchronization,
the backend would return stale data without the latest blocks.
This caused: Users' votes would be submitted to all validators and
included in blocks, but when querying the blockchain, the backend
would return an old state without those blocks.
Root cause: No block synchronization between validators yet. When a
validator creates a block, it doesn't immediately get to all peers.
So different validators can have different chain lengths.
Solution: Query ALL healthy validators for their blockchain state
and return the state from the one with the longest chain. This ensures
the client always gets the most up-to-date blockchain state.
Implementation:
- Loop through all healthy_validators
- Query each one's blockchain endpoint
- Track the state with the highest block count
- Return that state
This is a best-effort approach while block synchronization is being
established between validators.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Votes were only being submitted to one validator selected via
round-robin, then expected inter-validator broadcasting to propagate the
transaction. But inter-validator transaction broadcasting wasn't working
reliably.
Solution: Submit each vote to ALL healthy validators simultaneously.
This ensures every validator receives the transaction directly, making it
available for block creation regardless of inter-validator communication.
Benefits:
- No dependency on P2P transaction broadcasting
- All validators have same pending transaction pool
- Any validator can create blocks with all pending transactions
- More robust and simpler than trying to maintain P2P mesh
Implementation:
- Modified submit_vote() to loop through all healthy_validators
- Submit same JSON-RPC request to each validator
- Log results from each submission
- Require at least one successful submission
This is simpler and more reliable than the previous architecture.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Add logging at each stage:
- Context manager entry/exit
- submit_vote() method entry
- Validator selection
- HTTP request details
- Response handling
This will help identify exactly where the vote submission is failing.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Votes were being rejected by validators with 'Invalid data format'
error because the transaction data wasn't in the correct format.
Root cause: The validator's eth_sendTransaction endpoint expects the 'data'
field to be:
1. A hex string prefixed with '0x'
2. The hex-encoded JSON of a Transaction object containing:
- voter_id
- election_id
- encrypted_vote
- ballot_hash
- timestamp
Solution:
- Update BlockchainClient.submit_vote() to properly encode transaction data
as JSON, then hex-encode it with 0x prefix
- Add ballot_hash parameter to submit_vote() method
- Update both call sites in votes.py to pass ballot_hash
- Generate ballot_hash if not provided for safety
This ensures votes are now properly formatted and accepted by validators,
allowing them to be submitted to the blockchain instead of falling back to
local blockchain.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
validator-2 was incorrectly configured to use port 8001 (should be 8002)
validator-3 was incorrectly configured to use port 8001 (should be 8003)
This was causing validator-2 and validator-3 to be unreachable from the
backend container, resulting in votes being submitted to the local fallback
blockchain instead of the PoA validators.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
The backend container needs to reach validators using their Docker service names
(validator-1, validator-2, validator-3) instead of localhost:PORT.
This fixes the 'validators unreachable' warning on backend startup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>