Removes the forbidden Avalanche term from code comments in chains/manager.go,
chains/quorum.go, and vms/proposervm/proposer/windower_determinism_test.go. Reworded to
preserve exact meaning; comments only, no identifier/behavior change.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The "round-scoped view-change ENABLED for chain K=21 alpha=15" line read as if K=21/α=15
were the finality committee — misleading. It is the Snowman SAMPLE preset. The α-of-K
cert and the view-change POL/precommit are sized to the LIVE validator set at runtime
(effectiveCommittee/bftCommittee; 5 validators → K=5/α=4), and the engine already logs
the effective (K,α) on each committee re-clamp. Relabel the fields presetK/presetAlpha
and add a note pointing at the runtime committee-clamp log. Log-only; no behavior change.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Restores mainnet C-Chain finality. The prior stall: with 5 live validators but
MainnetParams K=21/alpha=15, BOTH finality gates (assembleCertLocked cert-alpha
AND view-change POL) required 15 distinct votes — impossible from 5 validators,
so the chain froze (safe, no fork). consensus v1.35.33 sizes both gates from the
live validator count via effectiveCommittee (alpha=4 for n=5), inheriting the
minBFTCommittee K=4/alpha=3 floor (1085013 self-finality guard preserved);
Snowman K=21 sample untouched. node chains/quorum.go adds
validatorStakeSource.ValidatorCount (height-indexed, deterministic). EVM stays
v1.104.7 (head-state pin). Test: 5-validator MainnetParams control freezes,
fix converges in 0.35s.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Closes postmortem residual #1 (proposer-preference restart loop / mute-voter
wedge). Build-side companion to the defect #1 SetPreference validate-before-
assign hardening.
vm.preferred is only adopted after a successful getBlock, but a block fetchable
at preference time can later become unfetchable: an unaccepted sibling consensus
dropped, or a never-persisted outer block referenced after heavy sibling churn.
The old BuildBlock returned after the single getBlock(preferred) miss with
"failed to fetch preferred block", so every attempt failed in a tight loop and
the node's voter went mute (~170 err/s). Quasar cert-finality has no re-converge
poll, so the fleet never recovered on its own — the liveness wedge behind the
mainnet 1082879->1085755 window (heartbeat-pause + full-fleet-restart churn).
Fix: on an unfetchable preferred, build the child on last-accepted (always held:
committed state). The node keeps producing on a valid tip while the catch-up
path pulls the gap; a later SetPreference(held tip) re-advances the preference.
Only surface the original error when last-accepted is itself the unfetchable id.
Tests (hermetic, mirror vm_rejoin_wedge_test.go): spy inner VM asserts the fetch
sequence — BuildBlock consults last-accepted on an unheld preferred (old code
never did), and does not spuriously fetch when no distinct fallback exists.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Same content as v1.34.24 (v1.104.3-headpin == v1.104.7, retagged per semver
policy: real monotonic patch versions, no suffix tags). go.mod has no replace
directives; removes the leftover comment from an already-completed cascade.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Pins luxfi/evm v1.104.3-headpin: dedicated unbalanced GC pin on the accepted
head state root (transferred head-to-head in Accept + startup + direct
setters) so the head can never be evicted by the tipBuffer/Cap while idle —
the durable fix for the 1085200 'missing trie node at head' freeze. Also
carries vm v1.2.6 parity. Base: v1.34.22 (mainnet matcher lineage), no other
changes.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The COMPLETE mainnet reliability build. v1.35.29 adds FIX#1 (self-finality floor — a
transient bftCommittee count can never self-finalize without quorum; the 1085016 accept-
without-quorum safety hole) + FIX#3 (canonical vote aggregation — sibling wrappers of the
same inner block combine into ONE cert; the block-288 wrapper-split cert-termination stall)
+ the v4 clone-resign inner->outer fix (my v1.35.28 re-sign silently no-op'd on real wrapped
blocks). Matcher EVM v1.104.3-hotfix + Bug B UNCHANGED — execution-identical to mainnet.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Bundles BOTH reliability fixes on the mainnet-compatible line (the live test proved they
COMPOUND — Bug A catch-up alone can't reconcile the tip-loss Bug B causes on restart):
- Bug A (consensus v1.35.28, merged to consensus main): catch-up #1/#2/#3/#5 + vote-guard clone re-sign.
- Bug B (EVM v1.104.3-hotfix): head-state Reference one-liner — EXECUTION-IDENTICAL to mainnet
(golden roots identical RED vs GREEN), matcher EVM (precompile v0.19.0), NO settle-only.
go.mod delta vs mainnet v1.34.14 = consensus-only; EVM = matcher+Reference (the only exec delta is
the proven-identical GC pin). STAGED for mainnet recovery — NOT rolled (gated on RED + canary).
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
MAINNET-COMPATIBLE node-only patch: the v1.34.14 line + catch-up/preference fixes + vote-
guard, EVM PLUGIN UNCHANGED (EVM_VERSION=v1.104.3, precompile v0.19.0, chains v1.7.2, vm
v1.2.5 — byte-identical to mainnet; NO settle-only, NO state-transition change). go.mod delta
vs v1.34.14 = consensus ONLY. Consensus v1.35.28 touches vote/cert LIVENESS only (engine is
byte-identical across the lines); it carries #2 (GetBlock-guarded build-tip steer) + the
vote-guard clone-artifact re-sign fallback. Cherry-picked #1/#3/#5 (proposervm validate-
before-assign, EmptyNodeID->real peers, have-block!=not-behind cert-fetch) on the prior commit.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The recurring freeze: a validator that fell behind could never rejoin, spamming
"sentTo=0" and "failed to fetch preferred block" until bounced. Two node-layer
defects, both BFT-safe (compared against ava avalanchego proposervm):
#1 proposervm.SetPreference (vms/proposervm/vm.go): assigned vm.preferred BEFORE
fetching, so a build-tip the node doesn't hold POISONED vm.preferred forever
(BuildBlock errors on every attempt; Quasar cert-finality has no re-converge
poll). Now: getBlock (both post-fork + inner stores) FIRST, delegate to inner,
adopt the preference only on success; on a total miss keep the last held tip
and stay live. Identical to ava in every case its single-store invariant
produces; only adds recovery for Lux's build-tip steering (never bricks).
SetPreference is not an acceptance gate, so safety/agreement is untouched.
#3 peer selection (chains/manager.go): consensus signals "fetch a certified-but-
untracked block" via ids.EmptyNodeID; the old code Add(EmptyNodeID)+Send, so
GetAncestors went to ZERO peers and the cert-verified gap was never fetched.
Now: when nodeID is Empty, sample real connected peers that track this chain's
network (same selection pollFrontierOnce uses); the cert already gated the ask.
Adds vm_rejoin_wedge_test.go. (Defect #2 — the engine build-tip steering in
consensus/engine/chain — is the upstream root cause, tracked separately.)
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The migration env now requires the operator's observed floor target:
LUX_CONSENSUS_MIGRATE_STALE_LOCKS=apply:<decidedFloor> (1082879 for the
mainnet one-shot). A bare "apply" is refused loudly. Once the chain
recovers and the floor advances, a lingering env self-disarms (Skipped,
no write) instead of degrading into an every-boot prune of genuine
crash locks. Consensus v1.35.26 carries the paired red-review fixes:
self-disarm floor target, durable-finality cert gate, migrated-view
invalidation, height-bound resolver.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Consensus v1.35.25 adds the boot-time stale outer-wrapper lock migration that
unfreezes mainnet C-Chain 1082880 (the durable 3/2 split-lock the canonical=inner
roll left behind — locks stored by outer wrapper id, never re-canonicalized). This
wires it into chain creation:
- LUX_CONSENSUS_MIGRATE_STALE_LOCKS one-shot (K>1 view-change chains), run AFTER
NewRuntime seeds the durable locks and BEFORE Start drives any view:
"inspect" -> InspectLocks: prints the per-height trace table, mutates nothing
(the per-pod audit gate operators run before any write);
"apply" -> MigrateStaleLocks: idempotent, safety-gated canonicalize/prune
ABOVE the decided floor (finalized + vote-guard state <=floor and
the floor itself preserved verbatim); STOP -> fail-closed error.
logStaleLockReport renders the auditable trace table in both modes.
- DEFENSIVE view-change hygiene: refuse to start a view-change chain whose gossiper
is not a QuorumGossiper or that has no VoteSigner (prevotes/precommits would be
emitted into the void -> silent finality stall) — fail loud, not frozen.
Offline cross-pod audit uses consensus cmd/voteguard (CGO-free vote-guard decoder).
Keeps the v1.34.14 canonical fix (Part A proposervm + Part B consensus) intact.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The chain-VM plugins are built with '|| echo WARN' (optional) but hard-COPY'd in
the runtime stage (a build miss -> cryptic COPY failure). Replace the single
bridgevm test-s check with a guard over every mandatory plugin so a missing/empty
binary fails loudly at the build stage with the real cause.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The consensus engine's finality object is VotePosition.CanonicalID (the signed
accept vote binds it and EXCLUDES the outer envelope id). It reads it via a
structural canonicalCommitter assertion (engine/chain canonicalIDOf); until now
NO block type implemented it, so canonicalIDOf fell back to the OUTER proposervm
envelope id. On the stuck C-Chain the designated proposer re-wraps the SAME inner
block each slot -> 758 distinct outer ids over ONE inner block 25Q837Lw -> 758
distinct canonicals -> votes scatter -> no alpha-of-K cert -> frozen at 1082879.
postForkCommonComponents now returns the inner block's id as CanonicalID and the
inner parent's id as ParentCanonicalID, so every outer wrapper of one inner block
(and a forked parent) collapses to ONE consensus object. Enables the consensus
v1.35.23/24 canonical-representative determinism fix to actually engage; neither
part alone unfreezes mainnet.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
v1.34.12 crash-looped on boot:
panic: threshold: scheme BLS already registered
consensus <= v1.35.22 blank-imported the OLD crypto/threshold/bls in
quasar.go while node imports the NEW threshold/scheme/bls; both register
BLS into the crypto/threshold registry -> panic. consensus v1.35.24
repoints quasar.go to threshold/scheme/bls.
Verified on the FULL node binary dep closure (go list -deps ./main, 1028
pkgs): luxfi/crypto/threshold/bls = 0, luxfi/threshold/scheme/bls = 1 —
exactly one BLS registration path, the panic cannot recur.
Pins: consensus v1.35.24, chains v1.7.2, evm v1.104.3.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Supersedes the v1.34.11 image build, which failed in the Docker plugin
stage: chains v1.7.1 pulled consensus v1.25.35, whose polaris.go imports
the removed pulsar/ref/go/pkg/pulsar path — the quantumvm + mpcvm plugins
could not build and their hard COPY failed.
- chains v1.7.1 -> v1.7.2 (consensus bumped to v1.35.22 there; consistent
pulsar graph; all 10 chain VM plugins verified building standalone).
- Dockerfile CHAINS_REF v1.7.1 -> v1.7.2.
- consensus v1.35.21 -> v1.35.22 (Pike-clean of the ProposalKey liveness
fix; logic identical to v1.35.21).
Pins: consensus v1.35.22, chains v1.7.2, evm v1.104.3. Off origin/main,
no WIP.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
IMAGE/BUILD change (packaging only — the consensus behavior change ships
separately as luxfi/consensus v1.35.21). Two edits make the deployable
node image build with the fixed consensus and the current chain plugins:
- consensus pin v1.35.20 -> v1.35.21 (ProposalKey decomplection, commit
776a5119c: outer block IDs are transport aliases, proposal identity is
ProposalKey{ParentID,Height} — proposervm envelope churn can no longer
spawn own sibling candidates that split votes; the mainnet 1082880 fix).
- Dockerfile ARG CHAINS_REF v1.7.0 -> v1.7.1. v1.7.0 still shipped the
pre-rename `thresholdvm` dir, so the Dockerfile's `cd /tmp/chains/mpcvm`
plugin build produced nothing (swallowed by `|| echo WARN`) and the hard
COPY of the mpcvm plugin (tGVBwRxp...) failed — the v1.34.10 Docker build
break. v1.7.1 carries the mpcvm rename; the mpcvm plugin builds clean
(verified standalone, 16MB) and all 10 chain plugins are present.
Pins verified for the canary image: consensus v1.35.21 (=776a5119c),
chains v1.7.1, evm v1.104.3, cevm v0.19.0, dex v1.5.15. Built off
origin/main — no WIP from any other worktree.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Pins node to the published tags carrying this session's LP-0130 work:
ids/constants add M/F chain identifiers (drop T-Chain), genesis adds
M/FChainGenesis, chains has the mpcvm rename, consensus has the
mempool-churn pre-build gate + threshold scheme/bls repoint.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
v1.34.9 = v1.34.8 + the C-Chain EVM plugin rebuilt from evm v1.104.3
(= evm v1.104.1 + luxfi/vm v1.2.6). The only change is the plugin's
ZAP RPC server now serializes VM state calls, fixing the concurrent-map
crash (chain.State.verifiedBlocks) that killed the EVM subprocess under a
concurrent ParseBlock storm and froze Lux mainnet C-Chain at block 1082879.
Node binary, consensus, genesis, and all other plugins are unchanged;
block output is byte-identical, so v1.34.9 is consensus-compatible with the
running v1.34.8 fleet (verified on devnet/testnet before the mainnet roll).
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The BLS Scheme impl moved from crypto/threshold/bls to
luxfi/threshold/scheme/bls (all threshold impls now live in one module;
the interface stays in crypto/threshold). One-line blank-import path
change; no behavior change.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Pairs the proposervm stale-parent slot-snap churn-fix (f840336167) with consensus
v1.35.17 (view-change abandonment must never silence a height). Together they close the
distributed VC liveness stall that keeps mainnet C-Chain safe-but-paused: slot-snap kills
the stale-parent rebuild sibling explosion at the source (one stable candidate per slot),
and v1.35.17 keeps the round machinery driving the height to convergence instead of going
silent after rePoll's 8-attempt cap. Liveness-only; decided-floor / no-double-finalize
safety invariant untouched. Gated on the live idle-inclusive devnet re-storm + RED before
any testnet/mainnet roll.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Off a stale parent (idle past the proposer window → anyone-can-propose), buildChild
was stamping a raw wall-clock timestamp (Time().Truncate(1s)), so every rebuild of the
same inner block produced a DISTINCT envelope id. That is an unbounded, ever-growing
sibling set at one height: the round-scoped view-change can never gather α aligned
prevotes on a single candidate (no proof-of-lock forms) and finality stalls fleet-wide
(the distributed liveness stall).
Snap the child timestamp DOWN to the parent-anchored proposer-window grid
(parentTimestamp + slot*WindowDuration, slot = TimeToSlot(parent, now)) so all rebuilds
WITHIN one slot are byte-identical → one stable candidate the view-change converges on.
Safe by construction: TimeToSlot(parent, snapped) == slot == TimeToSlot(parent, now), so
the block's slot — hence ExpectedProposer's proposer-window / signed-unsigned verdict and
the derived epoch — is unchanged. Only slot>0 snapped, so a fresh in-window child keeps
its exact timestamp (zero live-chain change), and a snapped time is strictly > parent
(monotonic) and <= now (not advanced). Liveness-only; no safety surface touched.
Extracted as slotSnappedChildTimestamp + unit-proven (idempotence, slot-invariance,
monotonicity). Full proposervm suite green.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Two concurrent-map races on the consensus-adjacent validator-set path,
both surfaced by the 5-node storm re-gate, both RED-verified fixed:
1. m.caches concurrent map write (getValidatorSetCache check-then-insert,
reached via proposervm windower.ExpectedProposer across chains during
buildBlocksLocked): guarded with a dedicated cachesLock sync.Mutex
(atomic check-create-store; plain Mutex, no lost-update).
2. TrackedChains concurrent map read/write: getValidatorSetCache read the
network's runtime-mutable cfg.TrackedChains lock-free (the admin
setTrackedChains RPC .Add's it under peersLock). Decoupled via an
immutable startup snapshot (set.Of(cfg.TrackedChains.List()...) in
NewManager); the false 'immutable after startup' comment is corrected.
Snapshot is correct (caching is pure-perf; cache.Empty recomputes),
and the construction clone provably happens-before any writer (P-chain
init is synchronous, admin API serves only post-node.Dispatch()).
Gates multi-validator restart-storm crash-freedom (before validator #2).
-race regression tests reproduce both races pre-fix, clean post-fix
(-count=5). Tracked follow-up (same class, network's live alias, admin-API
default-off, NOT this path): config/internal.go:120-121 + health.go:30 —
fix before ever enabling the admin API.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Harden the bootstrap checkpoint — the one path that bypasses the beacon quorum —
into a cryptographically SIGNED weak-subjectivity anchor.
- Checkpoint carries an authority Signature over a domain-separated canonical
(id,height); CheckpointVerifier (injected, backed by a proven primitive —
Ed25519/BLS, never custom crypto) authenticates it. The policy stays crypto-free
exactly like AncestrySource/heightOf.
- AcceptsFrontier trusts a pinned checkpoint ONLY when the configured authority
signed that exact (id,height). Present-but-unsigned, signed-by-a-non-authority,
signature-transplanted-to-another-(id,height), and no-verifier-wired all FAIL
CLOSED. A compromised flag cannot inject a false sync anchor without also forging
the authority's signature. It is a cryptographic vouch, NEVER a ⅔-live-stake tally.
- No production path pins a checkpoint yet (opt-in operator escape hatch), so the
invariant is enforced for when it is activated; nothing to wire now.
Folds consensus v1.35.16 (single ⅔ formula + leaf-lock doctrine) into the node.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Picks up the DEX 0x9999 genesis-injection fix (evm v1.104.1): 0x9999's
EXTCODESIZE marker is no longer baked into pre-2025 genesis state, so the
archived Lux mainnet (0x3f4fa2a0), Lux testnet (0x1c5fe377) and Zoo mainnet
(0x7c548af4) RLPs re-import byte-identical. 0x9999 activates at its protocol
timestamp (2025-12-25) during replay. rpcChainVM protocol 42 unchanged.
Forward-integrated on v1.34.4 (bootstrap/finality split, consensus v1.35.15) —
v1.34.4 was already taken and still pinned evm v1.104.0. This is a minimal
patch on top: EVM pin only.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Make the bootstrap-trust vs live-finality boundary a HARD API split so neither
can impersonate the other — the mass-recovery deadlock was bootstrap reusing the
finality quorum (>2/3 of CURRENT stake), which is unsatisfiable when the
recovery targets are themselves down validators.
- FinalityQuorum.HasFinality(weight,total): the live rule, strict >2/3 of current
stake (unchanged). Renamed from ConsensusQuorum to the reviewer's exact spec.
- BootstrapTrust.AcceptsFrontier(replies): selects a weak-subjective sync anchor
from AUTHENTICATED CONFIGURED beacons — a response FLOOR (MinResponses) plus a
supermajority over the RESPONDERS, NEVER over the whole set. Distinct type, so
bootstrap cannot call the finality predicate (INVARIANT 3: acceptance != finality;
the node re-executes every synced block before re-entering consensus).
- Contrast proven: 3-of-5 bootstrap ACCEPTS a frontier, yet HasFinality(3/5) is
false and STAYS false after sync — bootstrap is not a finality bypass.
Folds consensus v1.35.15 (the global unlock-before-call-out invariant + the
n=1..10 quorum acceptance matrix) into the node binary.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
consensus v1.35.13 -> v1.35.14 (decomplect: removed the selfVoter shortcut that
self-deadlocked on t.mu.RLock — the live n=1 freeze; K==1 now finalizes solely via the
inline finalizer, one path). EVM_VERSION v1.103.0 -> v1.104.0 (= v1.103.0 + accept-empty:
a consensus-finalized empty block Accepts, so VM.Accept can never fail-closed on an empty
first block — the stale-evm-pin gap). Unblocks single-validator Zoo mainnet/testnet +
Hanzo (all frozen at block 0).
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The v1.34.1 n=1 fix passed unit tests but the LIVE single-validator chains still
froze (Zoo mainnet/testnet, Hanzo, Pars, all block-0). Root cause (neo's live repro,
confirmed through the full runtime path): a reentrant-RWMutex self-deadlock — the
single-node selfVoter called engine.ReceiveVote synchronously while buildBlocksLocked
held t.mu, so ReceiveVote's t.mu.RLock deadlocked on the same goroutine (node hangs at
'single-node mode: self-voting', inline finalize never runs, block never decides).
consensus v1.35.13 dispatches the selfVoter's ReceiveVote on a fresh goroutine (no
reentrant lock) — the block now DECIDES through the real NewRuntime path (proven by
TestBlue_SingleValidator_DecidesThroughFullRuntimePath: hangs pre-fix, passes post-fix).
The bump also carries the n=1 synthesize fix (v1.35.11) and the dormant 1→N
decentralization guard (v1.35.12). EVM_VERSION unchanged (v1.103.0) — single-validator
blocks are tx-driven / non-empty.
Gates Zoo mainnet + Zoo testnet + Hanzo (all single-validator).
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Prod-line (v1.34.x finality-admission) bump carrying the consensus fix for the
single-validator (K=1) DECIDE stall that wedged all three sovereign
single-validator chains (Zoo 200200, Hanzo 36963, Pars 494949): a K==1 block now
finalizes even when its self-vote is unverifiable against a not-yet-resolvable
single-validator set (synthesized 1-of-1 cert; per-height FinalizeBranch gate is
the safety). n>1 C-Chains (mainnet/testnet) unaffected — they never hit the K()==1
branch.
The bump also carries the (dormant) bounded phantom-floor reconcile
(v1.35.9/v1.35.10) — additive engine methods that this prod-line node never calls
(manager.go on main has no ReconcilePhantomFloor wiring), so behavior is unchanged.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Adds the per-deployment opt-in flag: when LUX_CONSENSUS_VIEW_CHANGE=true and K>1, sets
consensusParams.ViewChange=true so devnet/testnet activate the round-scoped view-change
without a mainnet default (mainnet owner-gated). The engine fail-secure HALTS if the committee
fails 2a-n>f, so enabling never weakens safety. Bumps consensus v1.35.6->v1.35.7 (removes dead
safeConfig dup). This is what makes v1.32.13's prevote transport actually activatable.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Adds the p2p transport for the consensus round-scoped view-change:
- quorumKindPrevote (kind 3) in the quorum-gossip envelope + decodeQuorumGossip accepts it.
- blockHandler.Gossip demux routes kind 3 -> engine.HandleIncomingPrevote(payload) (the engine
decodes+verifies height/round/canonical/sig from the payload, domain LUX/chain/prevote/v1,
and tallies toward a POL).
- networkGossiper.BroadcastPrevote(chainID,networkID,height,round,canonical,voteBytes) frames
kind 3 + broadcasts to ALL validators, mirroring BroadcastVote.
Type-checks against the round-scoped consensus (local replace, chains pkg builds clean).
Requires: consensus tag (with ViewChange + HandleIncomingPrevote + BroadcastPrevote) -> node
go.mod bump -> ARC build -> node v1.32.13 (also carries v1.32.12 evm v1.101.3 descent fix +
isBootstrapped truth fix). ViewChange is opt-in per network (default off); enable on devnet/
testnet only, NO mainnet.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Bootstrap descent no longer stalls on ancestry blocks ahead of the accepted height:
evm v1.101.3 decomplects BlockGasCost from ParseBlock (parse decodes; Verify enforces).
Carries the v1.32.11 isBootstrapped-truth + ancestry-fetch hardening.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Definitive probe: does the descent's served ancestry batch contain the requested
tip (want), and what are the parsed ids vs the serve-side ids — pins whether the
tip survives the Bytes()->ParseBlock round-trip (proposervm wrapping).
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
INFO-level logging on both sides of the descent so we can isolate send-vs-serve:
- SEND: sampleAncestorBeacons (weights/connected/ahead/sample), Ancestors SENT
(sampleSize/sentTo), GOT batch / TIMEOUT / msgBuild-fail.
- SERVE: GetContext RECV, walk-miss (which block + i), SERVED 0 (firstFound),
SERVING (containers).
- ROUTING: deliverBootstrapAncestors (dataLen/decodedBlocks/chFound/delivered).
To be reverted once the root cause is pinned. Devnet diagnostic build only.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>