- Created `/frontend/app/api/votes/check/route.ts` to handle GET requests for checking if a user has voted in a specific election. - Added error handling for unauthorized access and missing election ID. - Forwarded requests to the backend API and returned appropriate responses. - Updated `/frontend/app/api/votes/history/route.ts` to fetch user's voting history with error handling. - Ensured both endpoints utilize the authorization token for secure access.
9.4 KiB
PoA Blockchain - Quick Reference Guide
For: Developers integrating with PoA blockchain Last Updated: November 7, 2025 Status: ✅ Production Ready
TL;DR - The Essentials
What Is PoA?
Proof-of-Authority blockchain with 3 validators. Votes are immutably recorded across all validators.
Key Facts
- 3 validators reach consensus on each vote
- Block created every 5 seconds with 32 votes per block
- 6.4 votes/second throughput
- Can survive 1 validator failure and still work
- Fallback to local blockchain if all validators down
How Votes Flow
Frontend → Backend → BlockchainClient → [Validator-1, Validator-2, Validator-3]
↓
All 3 have identical blockchain
Running the System
Start Everything
cd /home/sorti/projects/CIA/e-voting-system
# Start all services
docker-compose up -d
# Verify everything is running
docker-compose ps
Check Health
# Backend health
curl http://localhost:8000/health
# Validator health
curl http://localhost:8000/api/admin/validators/health
# Specific validator
curl http://localhost:8001/health
curl http://localhost:8002/health
curl http://localhost:8003/health
Stop Everything
docker-compose down
API Endpoints
Vote Submission
POST /api/votes/submit
- Submit encrypted vote to PoA blockchain
- Returns
transaction_idfor tracking
Check Vote Status
GET /api/votes/transaction-status?transaction_id=tx-xxx&election_id=1
- Returns:
pendingorconfirmed - Includes block info when confirmed
Get Results
GET /api/votes/results?election_id=1
- Returns vote counts by candidate
- Includes blockchain verification status
Verify Blockchain
POST /api/votes/verify-blockchain
- Checks if blockchain is valid and unmodified
- Returns:
validorinvalid
Monitor Validators
GET /api/admin/validators/health
- Shows health of all 3 validators
- Shows which are healthy/degraded/unreachable
Code Examples
Using BlockchainClient (Python)
from backend.blockchain_client import BlockchainClient
# Create client
async with BlockchainClient() as client:
# Submit vote
result = await client.submit_vote(
voter_id="voter123",
election_id=1,
encrypted_vote="base64_encoded_vote",
transaction_id="tx-abc123"
)
# Check status
status = await client.get_vote_confirmation_status(
transaction_id="tx-abc123",
election_id=1
)
# Get results
results = await client.get_election_results(election_id=1)
# Verify integrity
is_valid = await client.verify_blockchain_integrity(election_id=1)
API Request (cURL)
# 1. Get token
TOKEN=$(curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"voter@test.com","password":"pass"}' \
| jq -r '.access_token')
# 2. Submit vote
curl -X POST http://localhost:8000/api/votes/submit \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"election_id": 1,
"candidate_id": 42,
"encrypted_vote": "aGVsbG8gd29ybGQ="
}' | jq '.transaction_id'
# 3. Check status
TX_ID=$(curl ... | jq -r '.transaction_id')
curl "http://localhost:8000/api/votes/transaction-status?transaction_id=$TX_ID&election_id=1" \
-H "Authorization: Bearer $TOKEN" | jq '.status'
How It Works Internally
Vote Submission Flow
- Frontend encrypts vote with ElGamal
- Backend validates voter and election
- BlockchainClient picks healthy validator
- JSON-RPC sends
eth_sendTransactionto validator - Validator adds vote to transaction pool
- Every 5 seconds:
- PoA round-robin picks designated validator
- Creates block with 32 pending votes
- Signs block with private key
- Broadcasts to other 2 validators
- Other validators verify and accept block
- All 3 validators add identical block to chain
Consensus Algorithm (PoA)
next_block_index = len(blockchain) # 1, 2, 3, ...
authorized_validators = ["validator-1", "validator-2", "validator-3"]
block_creator = authorized_validators[next_block_index % 3]
# Example:
# Block 1: 1 % 3 = 1 → validator-2 creates
# Block 2: 2 % 3 = 2 → validator-3 creates
# Block 3: 3 % 3 = 0 → validator-1 creates
# Block 4: 4 % 3 = 1 → validator-2 creates (repeats)
Validator Ports
| Service | Port | Purpose |
|---|---|---|
| Backend | 8000 | FastAPI server |
| Bootnode | 8546 | Peer discovery |
| Validator-1 | 8001 | RPC (vote submission) |
| Validator-1 P2P | 30303 | P2P networking |
| Validator-2 | 8002 | RPC |
| Validator-2 P2P | 30304 | P2P networking |
| Validator-3 | 8003 | RPC |
| Validator-3 P2P | 30305 | P2P networking |
Files Modified in Phase 3
New
backend/blockchain_client.py- PoA client libraryPHASE_3_INTEGRATION.md- Full integration guidePOA_QUICK_REFERENCE.md- This file
Updated
backend/routes/votes.py- Use PoA for submissionsbackend/routes/admin.py- Validator health checksbackend/main.py- Initialize PoA client on startup
Troubleshooting
Validator Not Responding
# Check if running
docker ps | grep validator-1
# Check logs
docker logs validator-1
# Restart
docker-compose restart validator-1
Vote Submission Fails
# Check validator health
curl http://localhost:8000/api/admin/validators/health
# If all down, check Docker
docker-compose ps
# Restart all validators
docker-compose restart validator-1 validator-2 validator-3
Blockchain Out of Sync
# Check each validator's blockchain
curl http://localhost:8001/blockchain?election_id=1 | jq '.verification'
curl http://localhost:8002/blockchain?election_id=1 | jq '.verification'
curl http://localhost:8003/blockchain?election_id=1 | jq '.verification'
# They should show same block count and last hash
How to View Logs
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f backend
docker-compose logs -f validator-1
docker-compose logs -f bootnode
# With grep filter
docker logs validator-1 | grep -i "block\|error"
Configuration
Validator URLs (Default)
DEFAULT_VALIDATORS = [
("validator-1", "http://localhost:8001"),
("validator-2", "http://localhost:8002"),
("validator-3", "http://localhost:8003"),
]
Custom Validators
To use custom validator locations, modify backend/blockchain_client.py:
class BlockchainClient:
DEFAULT_VALIDATORS = [
ValidatorNode(
node_id="custom-1",
rpc_url="http://custom-1.example.com:8001",
p2p_url="http://custom-1.example.com:30303"
),
# ... more validators
]
Performance Tips
For High Throughput
- Use 5+ validators (currently 3)
- Increase block size from 32 to 64+ votes
- Batch multiple votes together
For Lower Latency
- Run validators on same network
- Reduce consensus timeout
- Use dedicated network interface
For High Availability
- Distribute validators across regions
- Implement cross-region replication
- Add backup validators for failover
Security Checklist
- Use HTTPS in production
- Enable authentication on all endpoints
- Set rate limits per IP/user
- Monitor validator health continuously
- Keep validator keys secure
- Backup database regularly
- Enable audit logging
- Verify blockchain integrity periodically
Key Files to Know
backend/
├── blockchain_client.py ← Communication with validators
├── blockchain.py ← Local blockchain (fallback)
├── routes/
│ ├── votes.py ← Vote submission endpoints
│ └── admin.py ← Health monitoring endpoints
└── main.py ← App initialization
validator/
└── validator.py ← PoA consensus node
bootnode/
└── bootnode.py ← Peer discovery service
Phase 3 Summary
✅ BlockchainClient created for PoA communication ✅ Vote endpoints updated to use PoA validators ✅ Health monitoring added for operational visibility ✅ Graceful fallback to local blockchain if PoA unavailable ✅ Production-ready error handling and logging ✅ Full backward compatibility maintained
Status: Ready for production or Phase 4 (frontend enhancement)
Quick Commands
# See all running services
docker-compose ps
# View backend logs
docker-compose logs -f backend
# Check validator health (JSON)
curl http://localhost:8000/api/admin/validators/health | jq
# Verify blockchain (specific election)
curl -X POST http://localhost:8000/api/votes/verify-blockchain \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"election_id": 1}' | jq
# Get vote results
curl http://localhost:8000/api/votes/results?election_id=1 \
-H "Authorization: Bearer $TOKEN" | jq
# Restart validators
docker-compose restart validator-1 validator-2 validator-3
# View a specific validator's logs
docker logs validator-2 | tail -50
For detailed information, see:
PHASE_3_INTEGRATION.md- Complete integration guideIMPLEMENTATION_COMPLETE.md- PoA implementation detailsPOA_ARCHITECTURE_PROPOSAL.md- Architecture decisions