TASK
Implementation
Simulate a Byzantine node that sends contradictory messages to different peers (equivocation). Show that PBFT correctly handles this.
Request: {"type": "simulate_equivocation", "msg_id": 1, "byzantine_node": "n2", "sequence": 1, "messages_sent": {
"to_n1": {"prepare": {"value": "A"}},
"to_n3": {"prepare": {"value": "B"}},
"to_n4": {"prepare": {"value": "A"}}
}}
Response: {"type": "simulate_equivocation_ok", "in_reply_to": 1, "equivocation_detected": true, "evidence": {"node": "n2", "conflicting_values": ["A", "B"]}, "consensus_safe": true, "chosen_value": "A", "reason": "majority_agreed_on_A"}
Request: {"type": "equivocation_report", "msg_id": 2}
Response: {"type": "equivocation_report_ok", "in_reply_to": 2, "byzantine_nodes_detected": ["n2"], "total_equivocations": 1}Sample Test Cases
Equivocation is detectedTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1","n2","n3","n4"]}}
{"src":"c1","dest":"n1","body":{"type":"simulate_equivocation","msg_id":2,"byzantine_node":"n2","sequence":1,"messages_sent":{"to_n1":{"prepare":{"value":"A"}},"to_n3":{"prepare":{"value":"B"}},"to_n4":{"prepare":{"value":"A"}}}}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Equivocation report lists Byzantine nodesTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1","n2","n3","n4"]}}
{"src":"c1","dest":"n1","body":{"type":"simulate_equivocation","msg_id":2,"byzantine_node":"n2","sequence":1,"messages_sent":{"to_n1":{"prepare":{"value":"X"}},"to_n3":{"prepare":{"value":"Y"}},"to_n4":{"prepare":{"value":"X"}}}}}
{"src":"c1","dest":"n1","body":{"type":"equivocation_report","msg_id":3}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Hints
Hint 1▾
Equivocation: a Byzantine node sends different messages to different peers
Hint 2▾
Detection: peers compare received messages and find contradictions
Hint 3▾
Evidence: two signed messages from the same node with different values for the same sequence
Hint 4▾
PBFT handles this because 2f+1 matching messages are required for commit
Hint 5▾
The contradictory node is effectively ignored when it cannot produce enough matching messages
OVERVIEW
Theoretical Hub
Concept overview coming soon
Key Concepts
equivocationcontradictory messagesevidence collectionByzantine detection
main.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
import sys
import json
def main():
# Your implementation here
for line in sys.stdin:
msg = json.loads(line)
print(json.dumps(msg), flush=True)
if __name__ == "__main__":
main()