Consensus Algorithms Comparison Interview Questions

Consensus algorithm comparison and general implementation interview questions.

Q1: Compare different consensus algorithms.

Answer:

Comparison Table:

AlgorithmTypeFinalityBlock TimeEnergyFault Tolerance
PaxosClassicImmediateN/ALow(n-1)/2 failures
BFTByzantineImmediateFastLowf Byzantine (n=3f+1)
TendermintBFTImmediate1-6sLow1/3 Byzantine
OuroborosPoSProbabilistic1sVery Low51% stake attack
BitcoinPoWProbabilistic10minVery High51% hash power
Ethereum PoSPoSCheckpoint12sVery Low1/3 stake attack
PolkadotNPoSFast6sVery Low1/3 stake attack
SolanaPoH + PoSProbabilistic0.4sVery Low1/3 stake attack

Trade-offs:

Safety vs Liveness:

  • Paxos/BFT/Tendermint: Strong safety, requires synchrony
  • PoW/PoS: Probabilistic safety, works asynchronously

Finality:

  • Immediate: Paxos, BFT, Tendermint
  • Probabilistic: Bitcoin, Ouroboros, Solana
  • Checkpoint: Ethereum PoS
  • Fast: Polkadot (GRANDPA)

Energy Efficiency:

  • Low: Paxos, BFT, Tendermint
  • Very Low: All PoS algorithms
  • Very High: PoW (Bitcoin)

Use Case Selection:

  • Distributed Systems: Paxos, BFT
  • Public Blockchains: PoW, PoS variants
  • High Throughput: Tendermint, Polkadot, Solana
  • Ultra-High Throughput: Solana (65K+ TPS)
  • Formal Verification: Ouroboros
  • Shared Security: Polkadot

Q2: How do you implement a simple consensus algorithm?

Answer:

Simple BFT Implementation:

 1class SimpleBFT:
 2    def __init__(self, node_id, total_nodes):
 3        self.node_id = node_id
 4        self.total_nodes = total_nodes
 5        self.f = (total_nodes - 1) // 3  # Max Byzantine nodes
 6        self.quorum = 2 * self.f + 1
 7        self.is_primary = (node_id == 0)
 8        self.log = {}
 9        self.sequence = 0
10    
11    def propose(self, request):
12        if not self.is_primary:
13            return None
14        
15        self.sequence += 1
16        proposal = {
17            'sequence': self.sequence,
18            'request': request,
19            'prepares': {self.node_id},
20            'commits': set()
21        }
22        self.log[self.sequence] = proposal
23        
24        # Broadcast pre-prepare
25        return {
26            'type': 'pre_prepare',
27            'sequence': self.sequence,
28            'request': request
29        }
30    
31    def handle_pre_prepare(self, message):
32        if self.is_primary:
33            return None
34        
35        sequence = message['sequence']
36        request = message['request']
37        
38        # Validate
39        if not self.validate_request(request):
40            return None
41        
42        # Store and broadcast prepare
43        self.log[sequence] = {
44            'request': request,
45            'prepares': {self.node_id},
46            'commits': set()
47        }
48        
49        return {
50            'type': 'prepare',
51            'sequence': sequence,
52            'node_id': self.node_id
53        }
54    
55    def handle_prepare(self, message):
56        sequence = message['sequence']
57        node_id = message['node_id']
58        
59        if sequence not in self.log:
60            return None
61        
62        self.log[sequence]['prepares'].add(node_id)
63        
64        # Check if we have quorum
65        if len(self.log[sequence]['prepares']) >= self.quorum:
66            # Broadcast commit
67            return {
68                'type': 'commit',
69                'sequence': sequence,
70                'node_id': self.node_id
71            }
72        
73        return None
74    
75    def handle_commit(self, message):
76        sequence = message['sequence']
77        node_id = message['node_id']
78        
79        if sequence not in self.log:
80            return None
81        
82        self.log[sequence]['commits'].add(node_id)
83        
84        # Check if we have quorum
85        if len(self.log[sequence]['commits']) >= self.quorum:
86            # Execute request
87            result = self.execute(self.log[sequence]['request'])
88            return {
89                'type': 'reply',
90                'sequence': sequence,
91                'result': result
92            }
93        
94        return None

Q3: What are the security properties of consensus algorithms?

Answer:

Safety Properties:

  1. Agreement: All honest nodes agree on same value
  2. Validity: Only valid values are chosen
  3. Integrity: Values cannot be tampered with

Liveness Properties:

  1. Termination: Algorithm eventually terminates
  2. Progress: System continues to make progress
  3. Responsiveness: Responds within bounded time

Fault Tolerance:

  • Crash Faults: Nodes stop responding
  • Byzantine Faults: Nodes behave arbitrarily
  • Network Faults: Messages delayed or lost

Attack Vectors:

  1. 51% Attack: Control majority of resources
  2. Sybil Attack: Create many fake identities
  3. Eclipse Attack: Isolate node from network
  4. Nothing-at-Stake: Vote on multiple chains (PoS)
  5. Long-Range Attack: Rewrite history (PoS)

Mitigation Strategies:

  • Checkpointing: Lock in finalized blocks
  • Slashing: Penalize malicious behavior
  • Time Locks: Delay withdrawals
  • Validator Rotation: Change validator set
  • Finality Gadgets: Separate finality mechanism

Related Snippets