Chasing these one at a time was whack-a-mole — every repair surfaced the next
moved tag (age, pq, threshold, zap, consensus, constants, sdk, keys…). This is
the systematic pass instead: every distinct luxfi/hanzoai module@version in the
workspace (692 of them) was resolved against proxy.golang.org + a direct fetch,
and any go.sum line disagreeing with what is actually served was corrected.
Not an attack, and checked rather than assumed: for each case the proxy and a
direct fetch AGREE with each other and differ from the recorded hash. Two
independent transports agreeing means nothing is rewriting bytes in flight —
the tags moved at source. sum.golang.org still holds the original, but
GOPRIVATE covers github.com/luxfi/* with GOSUMDB=off, so our own modules never
consult the checksum DB and a moved tag splits consumers silently instead of
failing at publish time.
Only the recorded hash changes. No selected version moves, and `go mod tidy`
was deliberately NOT run, so nothing is upgraded as a side effect.
Verified: `go list -m all` resolves with no checksum error.
The durable fix is upstream: treat a published version as immutable. Cut
x.y.z+1 instead of moving a tag — with GOSUMDB off, no consumer can detect it.
luxfi/precompile/pqcrypto (the bundled "unified PQ" package) was removed. Its
live role is ML-KEM at 0x012201, now the standalone luxfi/precompile/mlkem —
which wraps luxfi/crypto/mlkem. Same ContractAddress, same 6-arg
StatefulPrecompiledContract Run, so the adapter is untouched. registry.go
already blank-imports mlkem (line 32); the pqcrypto line was pure dead weight.
Resolves the pqcrypto build break against precompile@v0.19.3. (coreth carries
further, unrelated legacy dep-skew — warp.UnsignedMessage, geth v1.16.99 in its
own go.mod — that is a separate modernization, not this change.)
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
The startup --import-chain-data path (importRLPBlocks) updated the on-disk
acceptedBlockDB to the imported tip but never refreshed the in-memory consensus
chain.State, which initChainState() had already set to the pre-import genesis
tip. Result: on the FIRST import boot the consensus layer stays at height 0
while the EVM head is the imported tip, and the proposervm wedges
("BuildBlock: preferred block not fetchable", preferred=empty id) until a
restart re-reads acceptedBlockDB.
The admin_importChain RPC path already calls the post-import callback
(eth/api_admin.go) which refreshes chain.State.lastAcceptedBlock and notifies
the consensus engine. The startup path now calls the same tested, nil-safe
callback (CallPostImportCallback).
Empirically proven on lux-testnet 96368 / node v1.36.17: first import boot
wedged at tip 251; with this the first boot finalizes past the import tip with
no restart. Imported-state execution / block-251 stateRoot is unchanged.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>