deps: bump consensus v1.25.20 / crypto v1.19.22 / chains v1.3.18 / runtime v1.1.3; wire LocalBFTParams for local dev nets

Publishes the consensus quorum-finality cascade into node:
- consensus v1.25.19 -> v1.25.20 (chain quorum-cert finality, LocalBFTParams)
- crypto v1.19.21 -> v1.19.22 (BLS deserialization/aggregation hardening)
- chains v1.3.17 -> v1.3.18, runtime v1.1.1 -> v1.1.3 (value-path tags)

selectConsensusParams now routes explicitly-local dev networks (devnet 3 /
localnet 1337, EXACT IDs not a range) to consensus.LocalBFTParams (K=4/α=3,
f=1) — the minimal real-BFT committee. Default K=20 is unsatisfiable on a
few localhost validators (α=14 unreachable -> P-Chain freezes at height 0).
K=4 makes quorum reachable while still clearing ValidateForValueNetwork and
the CRITICAL-2 multi-node-is-BFT regression. A custom value L1 (high
networkID) keeps the large Default set. precompile resolves to v0.5.56
(MVS-correct: chains v1.3.18's own requirement; node has no evm/dex dep).

go mod verify: all modules verified; chains quorum params tests green.
This commit is contained in:
zeekay
2026-06-23 01:43:41 -07:00
parent 4150bc12a8
commit b88a2e3fac
4 changed files with 80 additions and 18 deletions
+31 -6
View File
@@ -38,16 +38,38 @@ import (
validators "github.com/luxfi/validators"
)
// isLocalDevNetwork reports whether networkID is an explicitly-local developer
// network: devnet (3) or localnet (1337). These are EXACT IDs (per luxfi/constants
// convention), NOT a range — a custom value L1 with a high networkID (e.g. an
// L1 whose chainID == networkID) is a VALUE network and must NOT match here.
// Local dev networks are the only IDs that run the minimal-BFT committee
// (LocalBFTParams, K=4) instead of the large-committee Default (K=20), because a
// handful of localhost validators cannot reach an α=14-of-K=20 quorum.
func isLocalDevNetwork(networkID uint32) bool {
return networkID == constants.DevnetID || networkID == constants.LocalID
}
// selectConsensusParams picks the consensus parameters for a chain.
//
// - sybilProtection == false (--dev / single-node): K=1, the sole validator's
// accept is the 1-of-1 quorum (no peer signatures).
// - sybilProtection == true (multi-node): a BYZANTINE-fault-tolerant param set
// selected by network — NEVER LocalParams() (K=3/α=2, f=0, which a single
// Byzantine validator forks; this was CRITICAL-2). Mainnet→K=21, Testnet→
// K=11, every other multi-node net→Default K=20. All satisfy f≥1 and the
// 2α−K ≥ f+1 overlap bound (ValidateForValueNetwork is also asserted at the
// call site as a fail-closed backstop).
// - sybilProtection == true, VALUE network: a large BYZANTINE-fault-tolerant
// param set — NEVER LocalParams() (K=3/α=2, f=0, which a single Byzantine
// validator forks; this was CRITICAL-2). Mainnet→K=21, Testnet→K=11, every
// other value net→Default K=20.
// - sybilProtection == true, LOCAL DEV network (devnet 3 / localnet 1337):
// LocalBFTParams() (K=4/α=3, f=1) — the MINIMAL real-BFT committee. Default
// K=20 is unsatisfiable on a few localhost validators: α=14 affirmative votes
// are unreachable with 3-4 validators, so no block ever finalizes and the
// P-Chain freezes at height 0 (no C-Chain is ever created). K=4 makes quorum
// reachable (3 of 4) while staying genuinely BFT — it still clears
// ValidateForValueNetwork (K≥4, f≥1) and the CRITICAL-2 multi-node-is-BFT
// regression, so production safety is untouched. (A local devnet should run
// ≥4 validators to realise f=1; with 3 it degrades to near-unanimous f=0,
// which is safe though not live under a fault.)
//
// All branches satisfy the 2α−K ≥ f+1 overlap bound; the manager call site also
// asserts ValidateForValueNetwork as a fail-closed backstop (K=4 passes it).
func selectConsensusParams(sybilProtection bool, networkID uint32) consensusconfig.Parameters {
if !sybilProtection {
return consensusconfig.SingleValidatorParams()
@@ -58,6 +80,9 @@ func selectConsensusParams(sybilProtection bool, networkID uint32) consensusconf
case constants.TestnetID:
return consensusconfig.TestnetParams()
default:
if isLocalDevNetwork(networkID) {
return consensusconfig.LocalBFTParams()
}
return consensusconfig.DefaultParams()
}
}
+37
View File
@@ -60,6 +60,43 @@ func TestSelectConsensusParams_MultiNodeIsBFT(t *testing.T) {
}
}
// TestSelectConsensusParams_LocalDevIsSatisfiableBFT proves that an explicitly-
// local dev network (devnet 3 / localnet 1337) selects the MINIMAL real-BFT set
// (LocalBFTParams: K=4/α=3, f=1) — satisfiable by a handful of localhost
// validators — and NOT the large Default (K=20/α=14), whose α=14 quorum is
// unreachable with 3-4 validators (the freeze-at-height-0 bug). It must still be
// genuinely BFT (f≥1) and pass the value backstop (K=4 ≥ 4), so production
// safety / CRITICAL-2 is untouched: a custom VALUE L1 (high networkID) still gets
// the large Default set, never the local one.
func TestSelectConsensusParams_LocalDevIsSatisfiableBFT(t *testing.T) {
for _, networkID := range []uint32{constants.DevnetID, constants.LocalID} {
p := selectConsensusParams(true /* sybilProtection */, networkID)
// Satisfiable on a small committee: α must be small (K=4 → α=3), NOT 14.
if p.K != 4 || p.AlphaPreference != 3 {
t.Fatalf("local dev net %d: want minimal-BFT K=4/α=3, got K=%d/α=%d (Default K=20 is unsatisfiable on localhost)",
networkID, p.K, p.AlphaPreference)
}
// Still genuinely BFT (f≥1) — does NOT regress CRITICAL-2.
if p.ByzantineFaultTolerance() < 1 {
t.Fatalf("local dev net %d: K=%d is not BFT (f=%d)", networkID, p.K, p.ByzantineFaultTolerance())
}
// Must clear the value backstop the manager asserts before engine start.
if err := p.ValidateForValueNetwork(networkID); err != nil {
t.Fatalf("local dev net %d: minimal-BFT params must pass the value backstop, got %v", networkID, err)
}
}
// A custom value L1 with a high networkID is NOT a local dev network: it must
// keep the large Default set (the isLocalDevNetwork predicate is EXACT, not a
// >=1337 range that would wrongly catch value L1s).
const customValueL1 = uint32(909090)
if p := selectConsensusParams(true, customValueL1); p.K != consensusconfig.DefaultParams().K {
t.Fatalf("custom value L1 %d must get Default K=%d, got K=%d (must NOT match the local-dev path)",
customValueL1, consensusconfig.DefaultParams().K, p.K)
}
}
// TestSelectConsensusParams_SingleNodeIsK1 proves --dev / sybil-disabled selects
// the K=1 single-validator regime (the sole validator's accept is the 1-of-1
// quorum) — and NOT a multi-node BFT set.
+4 -4
View File
@@ -26,8 +26,8 @@ require (
github.com/huin/goupnp v1.3.0
github.com/jackpal/gateway v1.1.1
github.com/jackpal/go-nat-pmp v1.0.2
github.com/luxfi/consensus v1.25.19
github.com/luxfi/crypto v1.19.21
github.com/luxfi/consensus v1.25.20
github.com/luxfi/crypto v1.19.22
github.com/luxfi/database v1.20.3
github.com/luxfi/ids v1.2.15
github.com/luxfi/keychain v1.0.2
@@ -120,7 +120,7 @@ require (
github.com/luxfi/accel v1.2.4
github.com/luxfi/api v1.0.15
github.com/luxfi/atomic v1.0.0
github.com/luxfi/chains v1.3.17
github.com/luxfi/chains v1.3.18
github.com/luxfi/codec v1.1.5
github.com/luxfi/compress v0.0.5
github.com/luxfi/constants v1.5.8
@@ -137,7 +137,7 @@ require (
github.com/luxfi/p2p v1.21.1
github.com/luxfi/resource v0.0.1
github.com/luxfi/rpc v1.1.0
github.com/luxfi/runtime v1.1.1
github.com/luxfi/runtime v1.1.3
github.com/luxfi/sdk v1.17.9
github.com/luxfi/sys v0.1.0
github.com/luxfi/timer v1.0.2
+8 -8
View File
@@ -302,24 +302,24 @@ github.com/luxfi/atomic v1.0.0 h1:xUV60MuzRvXngaQ1sM0yVC2v4TRoLlUGkkH7M9PS4yw=
github.com/luxfi/atomic v1.0.0/go.mod h1:0G2mTlQ6TXWHICUHrUUPu1/qAiIyR4gSZ2tva9ci/bI=
github.com/luxfi/cache v1.2.1 h1:kAzOS55/hmYeNKR+0HAKv4ma48Y6JjkI8UQeqdZ8bfI=
github.com/luxfi/cache v1.2.1/go.mod h1:co7JTxZZHpKT31Yh01LFp5aZOxmoUg157FhBLQdQHVU=
github.com/luxfi/chains v1.3.17 h1:GjcBK+haTuaq9DtTb+1hWycZox3Yy14jHWk43MoyAW8=
github.com/luxfi/chains v1.3.17/go.mod h1:MArifjc+fRtZH6M009L47YPJFDMEjjJbHy2BJ/8nxTE=
github.com/luxfi/chains v1.3.18 h1:CaKtVZ2LkPgBiaZkDEl+RPsO2iXTXsOfVDwSj2ukhdE=
github.com/luxfi/chains v1.3.18/go.mod h1:MArifjc+fRtZH6M009L47YPJFDMEjjJbHy2BJ/8nxTE=
github.com/luxfi/codec v1.1.5 h1:KBq8uvYm5Dy+E1heG8WBmqbqu8kstlFyE5ASBBB+C8I=
github.com/luxfi/codec v1.1.5/go.mod h1:/ugIv5iEgI+VAuPIetzxNT0eJaEjOID/mrIsgIjJh8g=
github.com/luxfi/compress v0.0.5 h1:4tEUHw5MK1bu5UOjfYCt4OKMiH7yykIgmGPRA/BfJTM=
github.com/luxfi/compress v0.0.5/go.mod h1:Cc1yxD2pfzrvpO32W2GDwLKff+CylHEvzZh2Ko8RSIU=
github.com/luxfi/concurrent v0.0.3 h1:eJyv1fhaC0jMLMw6+QS774cUmp7GK+ouMgvLCqnC7cc=
github.com/luxfi/concurrent v0.0.3/go.mod h1:Aj/FR5NpM0cB2P4Nt3+tz9+dV6V+LUW4HuMgSjwq5hw=
github.com/luxfi/consensus v1.25.19 h1:PXKstFDBvZP3ZToZj6yay9kZ5Mkwt2f72xMvpKUNi5Q=
github.com/luxfi/consensus v1.25.19/go.mod h1:dqywMwPfTweP5siGctYkeS1iNM1mdOKJ5Eq6lYH3dOQ=
github.com/luxfi/consensus v1.25.20 h1:5S/GaPpSrMrGPn9/jPRWSXUZ1Zqy57J3K3aSY0AMQmA=
github.com/luxfi/consensus v1.25.20/go.mod h1:8gAYHLYsMvXoYz262gvusIoDRxHBrMqj6Fyj8uSnaYE=
github.com/luxfi/constants v1.5.8 h1:iNP9AWNUcM4Tps7jYnx49CwtCWAC9mYRxJfGou2za0g=
github.com/luxfi/constants v1.5.8/go.mod h1:Pu5jWHdnUtQRbWC43yTUjU/pbIIKMDOd2a2yroSfo48=
github.com/luxfi/container v0.0.4 h1:BXhF82WyfqVP5mjlNcr7tP0Fcnvl0Ap1rkiu+rq5XuM=
github.com/luxfi/container v0.0.4/go.mod h1:Z3SpmMF5d4t77MM0nHYXURpn+EMVaeu1fhbd/3BGaek=
github.com/luxfi/corona v0.7.9 h1:NQe9V/80CdKLvbaVRE2uepxvxg9KHbWfcGRKWrzLSHc=
github.com/luxfi/corona v0.7.9/go.mod h1:SfS7xo/k4uoteEYwYy+QCMPzTU8EIEbLnbWKx5ENVCw=
github.com/luxfi/crypto v1.19.21 h1:x7s/Yy1BYMv5sbbWsZk+mUU007Z0HX/Ta4/RkrNHiw0=
github.com/luxfi/crypto v1.19.21/go.mod h1:0tfz+EbAjsW1QBWB0cte9kdjB5XhhYFmCr8BkZRux48=
github.com/luxfi/crypto v1.19.22 h1:qVXLyPR+nf6qqLbxA5KTbZmgNNxpqT9E7+3nppdRCq0=
github.com/luxfi/crypto v1.19.22/go.mod h1:0tfz+EbAjsW1QBWB0cte9kdjB5XhhYFmCr8BkZRux48=
github.com/luxfi/crypto/ipa v1.2.4 h1:6xfwhI9/HrcDkF3Ti5/NxsNQIWbwYDJmRSNIHRQ/xfU=
github.com/luxfi/crypto/ipa v1.2.4/go.mod h1:43J6f6rcfUMrZt4cQectMOZb6Ps+fAEj8ZTPC3Kk+gE=
github.com/luxfi/database v1.20.3 h1:fzBfd3bCGiUAlLAaMtMTB4aX78tNTSo4Z0kOA14LtAc=
@@ -382,8 +382,8 @@ github.com/luxfi/resource v0.0.1 h1:mTh+ICWSy548GTUSSyx7V/X5dV18oEwxZeQEYGJQhD4=
github.com/luxfi/resource v0.0.1/go.mod h1:wWpZktciYwIi6RNqA+fHwzmPrUJa7PRX7urfwT+spRE=
github.com/luxfi/rpc v1.1.0 h1:B/PJbK399th1mHRDSufhCpVbAciZqId3LsaWhIGNWH4=
github.com/luxfi/rpc v1.1.0/go.mod h1:s0bI7/Wg1ZdFdG/cQK+4pZNdEmUsXNBA3HeZRZ+XLeM=
github.com/luxfi/runtime v1.1.1 h1:vOMe82PL3bpSbslS7p69dKRpbr2qW2vOOAwej3UkkmU=
github.com/luxfi/runtime v1.1.1/go.mod h1:fmG6+Zxj4wSNlXwiUfDthQDY+SfxVu6S0fX2lL6VbrE=
github.com/luxfi/runtime v1.1.3 h1:6Yp/PKwQCohjXmBR9GA+gamdSAp+xA2rdN6J/74Y4aw=
github.com/luxfi/runtime v1.1.3/go.mod h1:r1uonDnxRCnPz6N6WYwaC72HW95KbFIAyChnJyxePGs=
github.com/luxfi/sampler v1.1.0 h1:u3iRDl7V06ARh0e85h3HT+aZ1saCFo2yMMsh+dCJbqk=
github.com/luxfi/sampler v1.1.0/go.mod h1:kJa53S3tC9+VSbuV3RFu68MmbCCBlr2UM39LOClQ/Hs=
github.com/luxfi/sdk v1.17.9 h1:a+95GjAtiY1bYsRYE2SmKhYzG4vcMWhXDq/uAXJlBO4=