mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
CRITICAL: VerifyQuasarSigWithContext no longer returns true for IsThreshold sigs — verifies BLS bytes against group key. CRITICAL: BlockCert.Verify returns false; VerifyWithKeys requires real crypto verification. HIGH: NewEngine/NewQuasar reject threshold < 2 (NewTestEngine/ NewTestQuasar for single-node testing). 13 security regression tests added.
266 lines
8.8 KiB
Go
266 lines
8.8 KiB
Go
// Example: Full Quasar Protocol - FPC + Wave + Horizon Demonstration
|
||
//
|
||
// This demonstrates the complete Quasar consensus protocol showing how:
|
||
// - FPC provides dynamic thresholds
|
||
// - Wave achieves metastable convergence
|
||
// - Horizon detects DAG finality
|
||
// - All together achieve <1s quantum finality
|
||
//
|
||
// Run: go run main.go
|
||
|
||
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"time"
|
||
|
||
"github.com/luxfi/consensus"
|
||
"github.com/luxfi/consensus/core/dag"
|
||
"github.com/luxfi/consensus/protocol/wave/fpc"
|
||
"github.com/luxfi/ids"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("╔═══════════════════════════════════════════════════════════════╗")
|
||
fmt.Println("║ Lux Quasar: Full Protocol Demonstration ║")
|
||
fmt.Println("║ FPC + Wave + Horizon + Post-Quantum Finality ║")
|
||
fmt.Println("╚═══════════════════════════════════════════════════════════════╝")
|
||
fmt.Println()
|
||
|
||
demonstrateFPC()
|
||
demonstrateWaveConsensus()
|
||
demonstrateHorizonFinality()
|
||
demonstrateQuasarFlow()
|
||
|
||
fmt.Println("✅ Quasar protocol demonstration complete!")
|
||
fmt.Println()
|
||
}
|
||
|
||
func demonstrateFPC() {
|
||
fmt.Println("━━━ Part 1: Fast Probabilistic Consensus (FPC) ━━━")
|
||
fmt.Println()
|
||
|
||
seed := fpc.DeriveEpochSeed(0, []byte("lux-demo"), nil)
|
||
selector, err := fpc.NewSelector(0.5, 0.8, seed)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
k := 20
|
||
|
||
fmt.Println(" FPC prevents stuck states with dynamic thresholds")
|
||
fmt.Printf(" Theta range: [0.5, 0.8] (50%%-80%% quorum)\n")
|
||
fmt.Printf(" Sample size: %d validators\n", k)
|
||
fmt.Println()
|
||
|
||
fmt.Println(" Threshold selection (PRF-based):")
|
||
thresholdSet := make(map[int]bool)
|
||
|
||
for round := uint64(0); round < 10; round++ {
|
||
threshold := selector.SelectThreshold(round, k)
|
||
thresholdSet[threshold] = true
|
||
theta := float64(threshold) / float64(k)
|
||
fmt.Printf(" Round %2d: α=%2d/%d (θ=%.3f) %s\n",
|
||
round, threshold, k, theta, bar(theta, 20))
|
||
}
|
||
|
||
fmt.Printf("\n ✓ %d unique thresholds prevent stuck states\n", len(thresholdSet))
|
||
fmt.Println()
|
||
}
|
||
|
||
func demonstrateWaveConsensus() {
|
||
fmt.Println("━━━ Part 2: Wave Consensus (Block Finalization) ━━━")
|
||
fmt.Println()
|
||
|
||
cfg := consensus.DefaultConfig()
|
||
chain := consensus.NewChain(cfg)
|
||
|
||
ctx := context.Background()
|
||
chain.Start(ctx)
|
||
defer chain.Stop()
|
||
|
||
// Create and finalize block
|
||
block := &consensus.Block{
|
||
ID: consensus.ID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},
|
||
ParentID: consensus.GenesisID,
|
||
Height: 1,
|
||
Time: time.Now(),
|
||
Payload: []byte("Quasar block with quantum finality"),
|
||
}
|
||
|
||
fmt.Printf(" Block: %x...\n", block.ID[:8])
|
||
|
||
start := time.Now()
|
||
chain.Add(ctx, block)
|
||
|
||
// Simulate votes
|
||
for i := 0; i < 20; i++ {
|
||
nodeID := consensus.NodeID{byte(i + 1)}
|
||
vote := consensus.NewVote(block.ID, consensus.VotePreference, nodeID)
|
||
chain.RecordVote(ctx, vote)
|
||
|
||
if (i+1)%5 == 0 {
|
||
fmt.Printf(" Votes: %2d/20 %s\n", i+1, bar(float64(i+1)/20.0, 30))
|
||
}
|
||
}
|
||
|
||
elapsed := time.Since(start)
|
||
status := chain.GetStatus(block.ID)
|
||
|
||
fmt.Printf("\n Status: %v\n", status)
|
||
fmt.Printf(" Time: %v\n", elapsed)
|
||
|
||
if status == consensus.StatusAccepted {
|
||
fmt.Println(" ✅ Block finalized with BFT guarantees")
|
||
}
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
func demonstrateHorizonFinality() {
|
||
fmt.Println("━━━ Part 3: Horizon DAG Finality Algorithms ━━━")
|
||
fmt.Println()
|
||
|
||
genesis := ids.Empty
|
||
b1, _ := ids.ToID([]byte("block1_left_____________________"))
|
||
b2, _ := ids.ToID([]byte("block2_right____________________"))
|
||
b3, _ := ids.ToID([]byte("block3_merge____________________"))
|
||
|
||
store := createMockDAG(genesis, b1, b2, b3)
|
||
|
||
fmt.Println(" DAG Structure: Genesis → (B1, B2) → B3")
|
||
fmt.Println()
|
||
|
||
// Test all algorithms
|
||
fmt.Println(" Horizon Algorithms Working:")
|
||
fmt.Printf(" ✓ IsReachable: %v\n", dag.IsReachable[ids.ID](store, genesis, b3))
|
||
fmt.Printf(" ✓ LCA: %s\n", dag.LCA[ids.ID](store, b1, b2))
|
||
fmt.Printf(" ✓ SafePrefix: %d finalized\n", len(dag.ComputeSafePrefix[ids.ID](store, []ids.ID{b3})))
|
||
fmt.Printf(" ✓ ChooseFrontier: %d selected\n", len(dag.ChooseFrontier[ids.ID]([]ids.ID{b1, b2, b3})))
|
||
|
||
horizons := []dag.EventHorizon[ids.ID]{
|
||
{Checkpoint: genesis, Height: 0, Validators: []string{"set0"}, Signature: []byte("sig0")},
|
||
}
|
||
newH := dag.Horizon[ids.ID](store, horizons)
|
||
fmt.Printf(" ✓ Horizon: Height %d → %d\n", 0, newH.Height)
|
||
fmt.Printf(" ✓ BeyondHorizon: %v\n", dag.BeyondHorizon[ids.ID](store, b3, newH))
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
func demonstrateQuasarFlow() {
|
||
fmt.Println("━━━ Part 4: Complete Quasar Protocol ━━━")
|
||
fmt.Println()
|
||
|
||
fmt.Println(" Quasar 2-Round Quantum Finality:")
|
||
fmt.Println()
|
||
fmt.Println(" ┌─────────────────────────────────────────┐")
|
||
fmt.Println(" │ ROUND 1: Classical Consensus (~500ms) │")
|
||
fmt.Println(" ├─────────────────────────────────────────┤")
|
||
fmt.Println(" │ • FPC dynamic threshold selection │")
|
||
fmt.Println(" │ • Wave metastable sampling (k=20) │")
|
||
fmt.Println(" │ • Confidence building (β=20) │")
|
||
fmt.Println(" │ • BLS aggregate signatures │")
|
||
fmt.Println(" └─────────────────────────────────────────┘")
|
||
fmt.Println()
|
||
fmt.Println(" ┌─────────────────────────────────────────┐")
|
||
fmt.Println(" │ ROUND 2: Quantum Finality (~300ms) │")
|
||
fmt.Println(" ├─────────────────────────────────────────┤")
|
||
fmt.Println(" │ • Horizon DAG finality detection │")
|
||
fmt.Println(" │ • Flare certificate verification (≥2f+1) │")
|
||
fmt.Println(" │ • Corona lattice signatures (PQ) │")
|
||
fmt.Println(" │ • Event horizon advancement │")
|
||
fmt.Println(" └─────────────────────────────────────────┘")
|
||
fmt.Println()
|
||
fmt.Println(" ═══════════════════════════════════════════")
|
||
fmt.Println(" Total: <1 second quantum-resistant finality")
|
||
fmt.Println(" ═══════════════════════════════════════════")
|
||
fmt.Println()
|
||
fmt.Println(" Protocol Features:")
|
||
fmt.Println(" ✓ Safety: No conflicting finalization")
|
||
fmt.Println(" ✓ Liveness: Sub-second finality")
|
||
fmt.Println(" ✓ Byzantine Tolerance: f < n/3")
|
||
fmt.Println(" ✓ Quantum Resistance: Corona + BLS")
|
||
fmt.Println()
|
||
}
|
||
|
||
func bar(ratio float64, width int) string {
|
||
filled := int(ratio * float64(width))
|
||
s := "["
|
||
for i := 0; i < width; i++ {
|
||
if i < filled {
|
||
s += "█"
|
||
} else {
|
||
s += "░"
|
||
}
|
||
}
|
||
return s + "]"
|
||
}
|
||
|
||
// Mock DAG store
|
||
type dagStore struct {
|
||
dag *mockDAG
|
||
}
|
||
|
||
type mockDAG struct {
|
||
blocks map[ids.ID]mockBlock
|
||
children map[ids.ID][]ids.ID
|
||
}
|
||
|
||
type mockBlock struct {
|
||
id ids.ID
|
||
parents []ids.ID
|
||
round uint64
|
||
author string
|
||
}
|
||
|
||
type mockBlockView struct {
|
||
block mockBlock
|
||
}
|
||
|
||
func (m *mockBlockView) ID() ids.ID { return m.block.id }
|
||
func (m *mockBlockView) Parents() []ids.ID { return m.block.parents }
|
||
func (m *mockBlockView) Author() string { return m.block.author }
|
||
func (m *mockBlockView) Round() uint64 { return m.block.round }
|
||
|
||
func (s *dagStore) Head() []ids.ID {
|
||
var heads []ids.ID
|
||
for id := range s.dag.blocks {
|
||
if len(s.dag.children[id]) == 0 {
|
||
heads = append(heads, id)
|
||
}
|
||
}
|
||
return heads
|
||
}
|
||
|
||
func (s *dagStore) Get(v ids.ID) (dag.BlockView[ids.ID], bool) {
|
||
block, ok := s.dag.blocks[v]
|
||
if !ok {
|
||
return nil, false
|
||
}
|
||
return &mockBlockView{block: block}, true
|
||
}
|
||
|
||
func (s *dagStore) Children(v ids.ID) []ids.ID {
|
||
return s.dag.children[v]
|
||
}
|
||
|
||
func createMockDAG(genesis, b1, b2, b3 ids.ID) *dagStore {
|
||
return &dagStore{
|
||
dag: &mockDAG{
|
||
blocks: map[ids.ID]mockBlock{
|
||
genesis: {id: genesis, parents: nil, round: 0, author: "system"},
|
||
b1: {id: b1, parents: []ids.ID{genesis}, round: 1, author: "node1"},
|
||
b2: {id: b2, parents: []ids.ID{genesis}, round: 1, author: "node2"},
|
||
b3: {id: b3, parents: []ids.ID{b1, b2}, round: 2, author: "node3"},
|
||
},
|
||
children: map[ids.ID][]ids.ID{
|
||
genesis: {b1, b2},
|
||
b1: {b3},
|
||
b2: {b3},
|
||
b3: {},
|
||
},
|
||
},
|
||
}
|
||
}
|