mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
Reorganize consensus packages following Go conventions and best practices: Protocol Consolidation: - Move prism/, photon/, wave/ → protocol/ directory - Consolidate all protocol implementations under single namespace - Follows standard library pattern (encoding/json, encoding/xml) Package Naming: - Rename validators/ → validator/ (singular, lowercase per Go convention) - Aligns with stdlib patterns (net/http, database/sql) Import Path Updates: - Update all 241 Go files with new import paths - github.com/luxfi/consensus/prism → protocol/prism - github.com/luxfi/consensus/photon → protocol/photon - github.com/luxfi/consensus/wave → protocol/wave - github.com/luxfi/consensus/validators → validator Benefits: - Clear separation: core (contracts) vs protocol (algorithms) vs engine (runtime) - Improved discoverability (all protocols under protocol/) - Consistent with Go naming conventions - Zero breaking changes to core APIs - Easier to add new protocol implementations Test Results: - All 67+ tests passing across 21 packages - 100% test coverage maintained - No performance regression Structure: consensus/ ├── core/ # Pure contracts (interfaces, zero deps) ├── protocol/ # Consensus algorithms & mechanics │ ├── prism/ # Polling/quorum primitives │ ├── photon/ # Unary consensus │ ├── wave/ # N-ary consensus (FPC) │ └── ... # Other protocol phases ├── engine/ # Runtime glue (runs protocols) └── validator/ # Validator management (singular)
206 lines
7.0 KiB
Go
206 lines
7.0 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
// Error variables for parameter validation
|
|
var (
|
|
ErrParametersInvalid = errors.New("invalid consensus parameters")
|
|
ErrInvalidK = errors.New("k must be >= 1")
|
|
ErrInvalidAlpha = errors.New("alpha must be between 0.5 and 1.0")
|
|
ErrInvalidBeta = errors.New("beta must be >= 1")
|
|
ErrBlockTimeTooLow = errors.New("block time must be >= 1ms")
|
|
ErrRoundTimeoutTooLow = errors.New("round timeout must be >= block time")
|
|
)
|
|
|
|
// Parameters defines consensus parameters
|
|
type Parameters struct {
|
|
K int
|
|
Alpha float64 // For compatibility with Quasar
|
|
Beta uint32 // For compatibility with Quasar
|
|
AlphaPreference int
|
|
AlphaConfidence int
|
|
BetaVirtuous int
|
|
BetaRogue int
|
|
ConcurrentPolls int
|
|
ConcurrentRepolls int
|
|
OptimalProcessing int
|
|
MaxOutstandingItems int
|
|
MaxItemProcessingTime time.Duration
|
|
Parents int
|
|
BatchSize int
|
|
BlockTime time.Duration // For compatibility
|
|
RoundTO time.Duration // For compatibility
|
|
}
|
|
|
|
// DefaultParams returns default parameters with 69% threshold
|
|
func DefaultParams() Parameters {
|
|
return Parameters{
|
|
K: 20,
|
|
Alpha: 0.69, // 69% threshold for BFT
|
|
Beta: 14, // Adjusted for 69% (was 15)
|
|
AlphaPreference: 14, // 70% of K for 69% threshold
|
|
AlphaConfidence: 14, // Matches AlphaPreference for 69%
|
|
BetaVirtuous: 14, // Virtuous confidence for 69%
|
|
BetaRogue: 20, // Rogue confidence remains high
|
|
ConcurrentPolls: 4,
|
|
ConcurrentRepolls: 4,
|
|
OptimalProcessing: 10,
|
|
MaxOutstandingItems: 1024,
|
|
MaxItemProcessingTime: 2 * time.Minute,
|
|
Parents: 2, // Reduced for efficiency
|
|
BatchSize: 30,
|
|
BlockTime: 100 * time.Millisecond,
|
|
RoundTO: 250 * time.Millisecond,
|
|
}
|
|
}
|
|
|
|
// MainnetParams returns mainnet parameters with 69% threshold
|
|
func MainnetParams() Parameters {
|
|
p := DefaultParams()
|
|
p.K = 21
|
|
p.AlphaPreference = 15 // ~71% of K for 69% threshold
|
|
p.AlphaConfidence = 15 // Matches AlphaPreference
|
|
p.BetaVirtuous = 15 // Virtuous confidence for 69%
|
|
p.BlockTime = 200 * time.Millisecond
|
|
p.RoundTO = 400 * time.Millisecond
|
|
return p
|
|
}
|
|
|
|
// TestnetParams returns testnet parameters with 69% threshold
|
|
func TestnetParams() Parameters {
|
|
p := DefaultParams()
|
|
p.K = 11
|
|
p.Alpha = 0.69 // 69% threshold
|
|
p.Beta = 8 // Adjusted for 69%
|
|
p.AlphaPreference = 8 // ~73% of K for 69% threshold
|
|
p.AlphaConfidence = 8 // Matches AlphaPreference
|
|
p.BetaVirtuous = 8 // Virtuous confidence for 69%
|
|
p.BlockTime = 100 * time.Millisecond
|
|
p.RoundTO = 225 * time.Millisecond
|
|
return p
|
|
}
|
|
|
|
// LocalParams returns local parameters with 69% threshold
|
|
func LocalParams() Parameters {
|
|
p := DefaultParams()
|
|
p.K = 5
|
|
p.Alpha = 0.69 // 69% threshold
|
|
p.Beta = 4 // Adjusted for 69%
|
|
p.AlphaPreference = 4 // 80% of K for 69% threshold
|
|
p.AlphaConfidence = 4 // Matches AlphaPreference
|
|
p.BetaVirtuous = 4 // Virtuous confidence for 69%
|
|
p.BlockTime = 10 * time.Millisecond
|
|
p.RoundTO = 45 * time.Millisecond
|
|
return p
|
|
}
|
|
|
|
// XChainParams returns X-Chain parameters with 69% threshold
|
|
func XChainParams() Parameters {
|
|
p := DefaultParams()
|
|
p.K = 5
|
|
p.Alpha = 0.69 // 69% threshold
|
|
p.Beta = 4 // Adjusted for 69%
|
|
p.AlphaPreference = 4 // 80% of K for 69% threshold
|
|
p.AlphaConfidence = 4 // Matches AlphaPreference
|
|
p.BetaVirtuous = 4 // Virtuous confidence for 69%
|
|
p.BlockTime = 1 * time.Millisecond
|
|
p.RoundTO = 5 * time.Millisecond
|
|
return p
|
|
}
|
|
|
|
// SingleValidatorParams returns parameters for single validator mainnet (K=1)
|
|
// This configuration is used for POA mode with a single staking validator
|
|
func SingleValidatorParams() Parameters {
|
|
return Parameters{
|
|
K: 1, // Single validator
|
|
Alpha: 1.0, // 100% threshold (only one validator)
|
|
Beta: 1, // Immediate finalization
|
|
AlphaPreference: 1, // Single validator preference
|
|
AlphaConfidence: 1, // Single validator confidence
|
|
BetaVirtuous: 1, // Immediate virtuous confidence
|
|
BetaRogue: 1, // No rogue behavior possible
|
|
ConcurrentPolls: 1, // Single poll at a time
|
|
ConcurrentRepolls: 1, // Single repoll if needed
|
|
OptimalProcessing: 1, // Process one at a time
|
|
MaxOutstandingItems: 256, // Reduced for single validator
|
|
MaxItemProcessingTime: 30 * time.Second, // Faster timeout for single validator
|
|
Parents: 1, // Single parent for linear chain
|
|
BatchSize: 10, // Smaller batches for single validator
|
|
BlockTime: 100 * time.Millisecond, // Fast block time
|
|
RoundTO: 200 * time.Millisecond, // Quick round timeout
|
|
}
|
|
}
|
|
|
|
// WithBlockTime returns a copy of Parameters with updated block time
|
|
func (p Parameters) WithBlockTime(blockTime time.Duration) Parameters {
|
|
p.BlockTime = blockTime
|
|
// Adjust round timeout based on block time
|
|
if blockTime <= time.Millisecond {
|
|
p.RoundTO = 5 * time.Millisecond
|
|
} else if blockTime < 10*time.Millisecond {
|
|
p.RoundTO = 25 * time.Millisecond
|
|
} else if blockTime < 100*time.Millisecond {
|
|
p.RoundTO = 250 * time.Millisecond
|
|
} else {
|
|
p.RoundTO = blockTime * 2
|
|
}
|
|
return p
|
|
}
|
|
|
|
// Validate validates parameters (compatibility method)
|
|
func (p Parameters) Validate() error {
|
|
return p.Valid()
|
|
}
|
|
|
|
// Valid validates parameters with 69% threshold enforcement
|
|
func (p Parameters) Valid() error {
|
|
// Check K, Alpha, Beta first - these are always required
|
|
if p.K < 1 {
|
|
return ErrInvalidK
|
|
}
|
|
// Enforce 69% threshold minimum (with small tolerance for rounding)
|
|
if p.Alpha < 0.68 || p.Alpha > 1.0 {
|
|
return ErrInvalidAlpha
|
|
}
|
|
if p.Beta < 1 {
|
|
return ErrInvalidBeta
|
|
}
|
|
if p.BlockTime > 0 && p.BlockTime < time.Millisecond {
|
|
return ErrBlockTimeTooLow
|
|
}
|
|
if p.BlockTime > 0 && p.RoundTO > 0 && p.RoundTO < p.BlockTime {
|
|
return ErrRoundTimeoutTooLow
|
|
}
|
|
|
|
// Only validate other fields if they are set (non-zero)
|
|
if p.AlphaPreference != 0 && (p.AlphaPreference < 0 || p.AlphaPreference > p.K) {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.AlphaConfidence != 0 && (p.AlphaConfidence < 0 || p.AlphaConfidence > p.K) {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.BetaVirtuous < 0 {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.BetaRogue != 0 && p.BetaRogue < p.BetaVirtuous {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.ConcurrentPolls != 0 && p.ConcurrentPolls < 1 {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.OptimalProcessing != 0 && p.OptimalProcessing < 1 {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.MaxOutstandingItems != 0 && p.MaxOutstandingItems < 1 {
|
|
return ErrParametersInvalid
|
|
}
|
|
if p.MaxItemProcessingTime != 0 && p.MaxItemProcessingTime <= 0 {
|
|
return ErrParametersInvalid
|
|
}
|
|
|
|
return nil
|
|
}
|