# Build executables
go build -o bin/node.exe cmd/node/main.go
go build -o bin/testclient.exe cmd/testclient/main.go
go build -o bin/keygen.exe cmd/keygen/main.go# 1. Generate keys (only do this once)
bash scripts/generate_keys.sh
# 2. Start all nodes (in one terminal)
bash scripts/run_nodes.sh
# 3. Run test client (in another terminal)
bash scripts/run_csv_test.sh testcases/test_input.csv
# Or manually:
./bin/testclient.exe testcases/test_input.csvIf you want more control, start each node in separate terminals:
./bin/node.exe n1 50051
./bin/node.exe n2 50052
./bin/node.exe n3 50053
./bin/node.exe n4 50054
./bin/node.exe n5 50055
./bin/node.exe n6 50056
./bin/node.exe n7 50057Then run test client:
./bin/testclient.exe testcases/test_input.csvAfter each test set:
log <nodeID>- view node's logdb <nodeID>- view node's datastorestatus <seq> <nodeID>- view status of sequence at nodeview <nodeID>- view all view changes at nodeallstatus <seq>- view status at all nodesnext- continue to next test
- 7 replicas (n1-n7), f=2
- 10 clients (A-J), each starts with 10 units
- View change timeout: 5 seconds
- Client timeout: 8 seconds per retry
- Client sends request to primary
- Primary broadcasts PRE-PREPARE (assigns sequence number)
- Backups send PREPARE to primary
- Primary broadcasts PREPARE_COLLECTOR (contains 2f prepares)
- All nodes send COMMIT to primary
- Primary broadcasts COMMIT_COLLECTOR (contains 2f+1 commits)
- All nodes execute and reply to client
- Timer-based detection when primary fails
- Exponential backoff on repeated failures
- NEW-VIEW messages include prepared requests from old view
crash- node stops participatingsign- corrupt message signaturesdark(targets)- drop messages to specific nodestime- delay messagesequivocation(targets)- send conflicting messages to different nodes
cmd/
node/main.go - node entry point
testclient/main.go - test client
keygen/main.go - key generation
pkg/
pbft/ - core protocol implementation
client/ - client logic
byzantine/ - byzantine attack behaviors
crypto/ - ed25519 signatures
storage/ - state persistence and datastore
util/ - config and logging
proto/
pbft.proto - protobuf definitions
scripts/
generate_keys.sh - generate ed25519 keys for all nodes/clients
run_nodes.sh - start all nodes
run_csv_test.sh - run test with csv file
cleanup.sh - clean temp files
testcases/
test_input.csv - test cases
test_input2.csv - more test cases
This project includes an Optimistic Phase Reduction bonus feature that improves performance by skipping the commit phase when all replicas are responsive.
Key Features:
- Fast Path: Skips commit phase when all 3f+1 prepares received within timeout
- Automatic Fallback: Reverts to normal 3-phase protocol on timeout or Byzantine behavior
- Performance: 50% reduction in messages, 25% reduction in latency (in ideal conditions)
- Configurable: Enable/disable via
pkg/util/config.go
Test it:
./bin/testclient.exe testcases/test_optimistic.csvSee OPTIMISTIC_PHASE_REDUCTION.md for complete documentation.
The system includes a checkpointing mechanism for garbage collection and state recovery.
- Nodes log to
tmp/logs/ - State saved in
tmp/state/ - Keys in
tmp/keys/ - Run
bash scripts/cleanup.shto clear temp files