20 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 748ea99f91 go 1.26.8
One toolchain across the estate. The tree carried 1.26.0, .1, .3, .4 and .5
at once, so which compiler built a binary depended on which repo it came
from.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-09 00:00:05 -07:00
zeekayandHanzo Dev a12bcbed4c e2e/clob: require the dex that is published, not the one beside the checkout
The e2e module reached github.com/luxfi/dex through a replace to ../../../dex,
which resolves on one machine and fails on every other; the require it masked
still said v1.5.4. It now requires v1.14.37, the tag the checkout beside it
sits nearest to, and the replace is gone. The replace to ../.. stays: that one
points inside this repository, which is how a nested module builds against
the tree it lives in.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 09:36:06 -07:00
zeekay 9ae0bb824e Pin past the versions the proxy can no longer serve
The bulk retag moved published tags. go.sum and sum.golang.org hold the
original bytes, proxy.golang.org answers not-found, and the direct fetch
disagrees, so builds stopped at a checksum before reaching a compiler.
Pin forward to versions the proxy still serves.
2026-09-01 11:10:20 -07:00
zeekay d4474142f1 dex, e2e, LLM.md: pin the hook and market surfaces, and point e2e at current deps
The D-Chain, hook and market surfaces had behaviour no test observed. e2e/clob
moves to the module versions this repo builds against. LLM.md records the two
orthogonal calldata bounds — Cursor for how many bytes, Unsigned/Signed for
which values — and why hand-writing either is the bug they exist to close.
2026-08-28 15:39:28 -07:00
zeekay 7f15be16d9 e2e: point the suite at this repo, and make its three broken scenarios real
e2e/go.mod required github.com/luxfi/precompile v0.5.27 with no replace, so the
suite compiled against a published artifact 33 patch releases behind the tree it
lives in. e2e/clob already had `replace => ../..`; the parent module never did.
The consequence was not that the tests were weak, it was that they could not
observe this repo at all — seven of them had been failing against real code and
nothing could report it. Adding the replace also removes the checksum failure
they hit on the way in: the v0.5.27 tag was force-moved after publication, so
github now serves bytes that do not match what sum.golang.org attests, and the
suite could not resolve its own parent.

With the replace in place, the seven pre-existing failures are visible, and all
seven were the tests being wrong:

  StableSwap x4 — the calldata was written by hand at each of four call sites
  with a one-byte token count and the amplification factor last. getD and getDy
  read a four-byte count and take the amplification before the balances. The
  layout now lives in encodeGetD/encodeGetDy and nowhere else, which is what
  stops it drifting again.

  CGGMP21 — threshold ECDSA on secp256k1, handed a P-256 key. The precompile
  refused it correctly. Now generates a real secp256k1 key and signature.

  FROST — verifies secp256k1 x-only Schnorr via curve.Secp256k1{}.LiftX; the
  test built an edwards25519 key, on the strength of a comment claiming FROST
  keys are Ed25519-compatible, which is not true of this implementation.

  Ed25519 — took 32 bytes from rand.Read and required them to be a canonical
  scalar, which holds about one time in sixteen, then hand-rolled a SHA-256
  Schnorr with s = k - e*x. RFC 8032 uses SHA-512 and s = r + e*a, and the
  precompile calls ed25519.Verify, so it could not have verified even with a
  valid scalar. Now signs with crypto/ed25519.

Keys come from a seeded source so a failure reproduces. Added the negative
cases these lacked entirely: signature bound to its message, every bit-flip
refused, all-zero key refused, truncated and over-long frames refused, and
gas charged on refusal. FROST keeps only its refusal cases here — the positive
path needs the threshold library's domain-separated challenge, which belongs in
frost/real_sig_test.go rather than in a second copy.

Also removes cmd/safekatdump and cmd/safekatverify. safekatdump's doc comment
claimed it "generates real known-answer test (KAT) vectors"; it generates a
fresh key and a fresh signature from rand.Reader on every run and safekatverify
then checks that our verifier accepts what our signer just produced. That
passes unchanged if the implementation is uniformly wrong on both sides, which
is the failure a KAT exists to catch. Nothing consumed the output: no Makefile
target, no CI step, no checked-in fixture, and no reference to either program
anywhere outside their own doc comments. Genuine frozen vectors now live in the
packages, under go test, where they run.

e2e/clob is left alone: it replaces github.com/luxfi/dex with a sibling working
checkout, so it currently fails on an undefined symbol from that tree's
in-progress state rather than anything here.
2026-08-28 09:18:12 -07:00
zeekayandHanzo Dev 03fe8b3c8e deps: reconcile luxfi/pq v1.0.3 onto the hash the tag actually resolves to
The v1.0.3 tag was re-pointed by a history rewrite that scrubbed a downstream
brand name from one comment line in mode.go, so the recorded zip hash no longer
matched the remote and clean-cache builds failed with a checksum SECURITY ERROR.

The new content is canonical and the difference is that single comment — no API,
no behaviour, and the module go.mod is byte-identical across both, so the
recorded /go.mod hash is unchanged. Hash re-derived by the toolchain, not
hand-written. luxfi/pq v1.1.1 retracts v1.0.3 so the moved tag stays visible
instead of being laundered away here.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 22:43:41 -07:00
zeekayandHanzo Dev 5dd6ecc90d deps: drop poisoned luxfi/threshold v1.9.4 pin → v1.12.0
The v1.9.4 tag was re-cut upstream; its content no longer matches the
recorded go.sum hash (checksum mismatch). Bump the indirect pin to the
clean v1.12.0 tag so the poisoned version leaves the module graph.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-03 15:58:59 -07:00
zeekay 9cfae862cf dex(0x9999): always-on settlement precompile, runtime params, zero per-net config
0x9999 — the native C<->D atomic DEX settlement money path — is now ALWAYS-ON:
present + active on every chain that loads the EVM plugin, from genesis, with NO
dexSettleConfig genesis/upgrade entry. This is the production-launch design; the
per-net config-gate is killed. Forward-perfect, one activation way.

Activation: modules.Module gains an AlwaysOn flag (+ modules.AlwaysOnModules()).
SettleModule sets AlwaysOn=true. The Configurator is retained only to satisfy the
interface; for an always-on module the host never invokes Configure (no activating
config). SettleConfig collapses to a parameter-free {Upgrade} marker that always
Verifies — 0x9999 takes no per-net parameters.

Params resolved at RUNTIME, not config (Configure has no consensus context, so it
cannot resolve them):
  - protocolFeeController: built-in DefaultDAOTreasury (set in init). One canonical
    DAO governance authority across every network; not a compromised dev key.
  - networkID / cChainID: already sourced at runtime via contract.AtomicState.
  - dChainID (THE crux): contract.AtomicState gains DChainID(). The 4 native-client
    sites that read loadDChainTarget(stateDB) now read atomicState.DChainID(), which
    the host resolves from the chain topology (consensus-context "D"/dexvm alias).
    ids.Empty (no dexvm on this network) closes the seam — fail-secure, no mint.

Money-path logic is byte-for-byte unchanged: DeriveIntentID/DerivePositionCommitID,
lock/stage/credit, conservation, exactly-once, rail discriminator, FIX-2 one-batch
flush, nonReentrant/custody guards all untouched. The ONLY change is HOW the
precompile activates and obtains its params (runtime, not config). The Empty-dChain
revert is preserved (strengthened: SubmitSwapIntent/SubmitPositionCommit now revert
on Empty instead of falling back to the C-Chain's own id).

Dead config machinery removed (one way, no dead code): SetSettle{ChainIdentity,
DChainTarget}, loadDChainTarget, loadSettleChainIdentity, cfg{Net,CChain,DChain}IDKey
slots, the STM read-set entries for them, and the now-unused kvAdapter Configure bridge.

Tests: full dex suite 335/335 PASS, 0 fail, 0 skip (CGO_ENABLED=0; the test binary's
only CGO dep is luxfi/accel, unrelated to the pure-Go money path). Harness feeds the
D peer via the runtime AtomicState capability, mirroring production exactly — proof
that the money path is intact with zero config.

go.sum: reconcile e2e threshold v1.9.4 to the origin-canonical hash (upstream re-tag).
2026-06-21 09:03:37 -07:00
zeekay e5ce587b45 precompile: V4=CLOB facade adapter (0x9010) + real starkfri verifier + restore inference precompile
dex/: 0x9010 inert-default CLOB facade -> ZAP D-Chain (no embedded AMM; RED H1/H3/H4 fixed).
starkfri/: bind the REAL p3q STARK/FRI verifier (cSHAKE256/Goldilocks) via cgo (//go:build
starkfri_p3q) + RegisterDefaultVerifier CAS fix; KAT accept-real/reject-tampered; 986 verify/s.
inference/: RESTORE the 6 files commit 6f97f5d accidentally deleted (real int8 transformer
precompile 0x0300..0003, byte-equal to aivm GPU; cmd/blue builds+runs deterministically).
Zero go.mod replace. precompile repo builds clean; go vet clean.
2026-06-17 17:26:06 -07:00
zeekay 7e7eda5b2e precompile/dex: V4=CLOB facade adapter, inert by default (no embedded AMM)
engine_embedded.go deleted; default backend = newInertEngine (ErrDEXBackendNotConfigured)
so the precompile is inert without a configured D-Chain endpoint. engine_zap.go speaks the
frozen zapwire CLOB frame over luxfi/rpc ZAPDial. RED fixes: H1 replay idempotency, H4
BLAKE3 cancel-auth, H3/C2 ERC-20 settlement conservation guard (removed magic-slot poke;
native LUX direct). Zero go.mod replace; integration test isolated in e2e/.
Verified green pure-Go + -race; all consensus-safety gates pass.
2026-06-17 13:31:58 -07:00
zeekay 1f7b80f7da go: 1.26.3 → 1.26.4 (security: crypto/x509, mime, net/textproto) 2026-06-06 22:06:44 -07:00
zeekay f4728d20b4 deps: bump luxfi/vm v1.2.0, sampler v1.1.0, staking v1.5.0 (relicense)
Picks up the 2026-06-06 relicensing:
- luxfi/vm v1.2.0 → Lux Ecosystem License v1.2 (was Lux Research v1.0).
  License-only retag of the extracted runtime; patent reservation
  preserved for runtime optimization surfaces, royalty-free for
  Descending Chains.
- luxfi/sampler v1.1.0 → BSD-3-Clause (was Lux Research v1.0).
  License restored to match the luxfi/node provenance (originally
  extracted from node/utils/sampler).
- luxfi/staking v1.5.0 → BSD-3-Clause (was Lux Research v1.0).
  License restored to match the luxfi/node provenance.

No code changes in this commit — go.mod/go.sum only.
2026-06-06 19:00:35 -07:00
zeekay a6217b8057 deps(e2e): bump p2p v1.21.1, vm v1.1.11 (Wave 2G-Cascade) 2026-06-06 06:33:41 -07:00
zeekay 636478f0aa fix: gofmt -s across repo (CI format check) 2026-06-02 23:27:11 -07:00
zeekay aadb570cbd precompile/fhe: close Mul DoS — re-derive gas at real 12M mainnet limit + activation gate
The pre-2026 adversarial test sized the FHE Mul gas (750_000) against a
30M block gas limit, but the real Lux primary-network C-Chain genesis
gasLimit is 12_000_000 (genesis/configs/mainnet/cchain.json line 16).
At 750k gas/Mul + 12M block limit, 16 Muls fit per tx; at ~78s per Mul
on commodity ARM (Apple M1 Max, measured 2026-06-01), one tx stalls a
validator for >20 minutes against a 2s block-target. Sustained: chain
halt at <0.4 LUX cost.

Fix is two-axis and bench-driven:

1. Re-derive every FHE Gas* constant against measured wall-clock and a
   1ms-per-(12_000-gas) calibration. New GasMul = 936_000_000 (78s ×
   12k); GasAdd = 180_000_000 (15s × 12k); etc. These exceed the 12M
   block-gas-limit, which is the protection: zero Muls fit per block,
   so no DoS surface remains.

2. Add an activation gate in fhe.module.Configure that refuses fheConfig
   when the chain's effective gasLimit < GasMul × MinSafeGasMulRatio.
   The gate uses a new feature-detection interface
   contract.FeeConfigReporter (mirrors the StrictPQReporter pattern):
   ChainConfigs that implement it engage the gate; those that don't
   (cross-chain integrators) remain permissive. The error type is
   contract.ErrFHEUnsafeGasLimit.

Tests:
- adversarial_test.go reworked into three explicit fixtures:
  TestFHEGasCost_Mul_DoSResistance_{30M_Reference,12M_Mainnet,
  20M_PostFeeManager}. Each asserts max ops/block × per-op-ms <= budget.
- module_test.go: 7 activation-gate cases (refuses at 12M/20M/30M;
  permits at >= GasMul; permissive without FeeConfigReporter; nil chain
  config; wrong config type).
- dos_audit.go + dos_audit_test.go: in-tree cross-precompile DoS audit
  table walked by tests at both 12M and 20M gasLimit. ML-DSA, SLH-DSA,
  Magnetar, Pulsar, BLS12-381 pairing, ZK Groth16, FROST, CGGMP21, VRF,
  HQC, P3Q all measured safe; FHE rows priced out (the activation gate
  is what surfaces them explicitly).
- bench_test.go: BenchmarkFHE{Mul,Add}_Uint8 — the canonical
  measurement-derivation hooks. Re-run on each arch to regenerate
  WallClockMs* constants.
- contract/feeconfig_test.go: 8 cases for RequireGasLimit (no reporter;
  nil chainConfig; reporter above/at/below threshold; reporter
  abstains; time-aware feeConfigManagerConfig flip; nil block context).

The e2e/fhe_private_auction test was pinning the OLD gas constants
verbatim; updated to assert the bench-derived calibration so a future
constant drift surfaces as test failure rather than silent regression.

NO CAVEAT. Either the gas is sufficient (gasLimit >= GasMul ×
MinSafeGasMulRatio) OR the precompile refuses to activate. The FHE
precompile is currently in the "refuses to activate" regime on real
mainnet C-Chain (gasLimit=12M < 936M required). Recovery is operator-
side: raise gasLimit via feeConfigManagerConfig OR land a faster TFHE
evaluator (see memory/vulkan_tfhe_pbs_fast_path.md — 20.4x landed,
need 78x to close the gap).
2026-06-01 21:25:19 -07:00
zeekay ca69a884d9 fix(e2e): drop ../ relative replace, bump precompile v0.4.7→v0.5.24 + indirects 2026-05-21 16:38:18 -07:00
zeekay cffbf960ae decomplect: rip IsDurango from precompileconfig.ChainConfig interface (activate-all-implicitly — no upgrade gates left) 2026-05-19 08:27:28 -07:00
zeekay 1f53dc1caf fhe: defend Run() against nil AccessibleState; switch e2e to stateful harness
Two correlated fixes prompted by the e2e FHE auction scenario:

1. fhe/contract.go: every FHE op reads or writes ciphertext storage via
   the StateDB. Calling FHEContract.Run with accessibleState=nil (the
   stateless harness path) nil-derefs the first handler that touches
   storage. Add a top-of-Run() guard returning ErrInvalidInput instead.

2. e2e/scenarios/fhe_private_auction_test.go: was using
   harness.CallWithGas (no state). Switch to CallStatefulWithGas with
   a MockAccessibleState so the precompile actually has somewhere to
   read/write ciphertexts; without it, the test was just probing the
   selector dispatcher's nil-deref behavior.

The FHE encrypt error path is independent — encrypt still returns
'operation not implemented' when the global FHE network key isn't
initialized, which is the expected behavior in unit tests. The test
gracefully skips downstream add/gt assertions when no real handles
materialize.
2026-05-13 16:10:12 -07:00
zeekay 90eef16960 go.mod: bump go directive to 1.26.3 (security advisory) 2026-05-12 20:55:01 -07:00
zeekay 3d48a72d2e feat: precompiles — anchor, babyjubjub EIP-2494, coverage, slug validation 2026-03-02 02:00:00 +00:00