Under LP-0130's canonical roster, chains/thresholdvm/ hosts the M-Chain VM (MPC threshold signing). The package name "thresholdvm" was the last piece of T-Chain nomenclature still shipping in code — legacy from the pre-LP-134 shared-substrate design. Renamed to mpcvm/ so the package name matches the M-Chain letter and LP-7100 spec. - chains/thresholdvm/ → chains/mpcvm/ (dir + inner files + package decl) - Sed-replace thresholdvm → mpcvm across .go / .md / .yml / .json / .sh - Fee/settlement primitive references now say mpcvm - LLM.md canonical chain roster (LP-0130) already points at mpcvm/ F-Chain runtime pieces (fhe/, protocol/tfhe_keygen/, runtime/f_chain_adapter.go) stay under mpcvm/ for now — they consume the same shared threshold primitives. A follow-up extract to chains/fhevm/ can happen once F-Chain runtime graduates. Co-authored-by: Hanzo Dev <[email protected]>
4.7 KiB
Architecture
ThresholdVM is the shared library substrate beneath M-Chain and F-Chain. The substrate has zero runtime presence; it compiles into both chains' binaries.
The three pieces
+-----------------------------------------------------------+
| Quasar 3.0 |
| (consensus, certificate_subject binds all chain roots) |
+-----------+--------------------------+--------------------+
| |
| mchain_ceremony_root | fchain_fhe_root
| |
+--------v---------+ +---------v--------+
| M-Chain | | F-Chain |
| validators | | validators |
| + MPC drivers | | + GPU drivers |
| + lane registry | | + lane registry |
| (MChainCGGMP21, | | (FChainTFHE, |
| MChainFROST, | | FChainBootstr) |
| MChainRingTl) | | |
+--------+---------+ +---------+--------+
| |
| imports |
| |
+----------+---------------+
|
+--------v---------+
| mpcvm |
| (this library) |
| |
| types/ |
| protocol/*/iface |
| cert/lane,subj |
| runtime/*Adapter |
+------------------+
What lives where
| Concern | Owner |
|---|---|
| Ceremony state machine (Registered → Round1 → Round2 → Finalized) | substrate (types/ceremony.go) |
Share envelope (offset, len) indirection |
substrate (types/share.go) |
| Participant set + Selector contract | substrate (types/participant.go) |
| Cert lane registry (per-owner enforcement) | substrate (cert/lane.go) |
certificate_subject binding |
substrate (cert/subject.go) |
| CGGMP21 / FROST / Corona-general drivers | M-Chain (chains/mchain/protocol/*/) |
| TFHE bootstrap-key generation | M-Chain producer + F-Chain consumer |
| TFHE compute kernels | F-Chain (chains/fchain/) |
| Block production, gossip, p2p | each chain's VM |
| Validator selection (stake-weighted VRF) | each chain's Selector impl |
| Persistence | each chain's database |
Why orthogonal at the type level
The substrate's LaneRegistry carries an Owner field. Register
checks the verifier's lane against the owner's allowed range:
OwnerMChainaccepts lanes 5..7OwnerFChainaccepts lanes 8..9
A misrouted verifier (e.g. F-Chain trying to register a CGGMP21
verifier) returns an error from Register at boot. The chain fails
to start, not at runtime in the middle of a ceremony.
Similarly, runtime.MChainAdapter and runtime.FChainAdapter are
disjoint interfaces. A chain implementing both is a code smell that
shows up in code review (and in go doc output).
Why one substrate, two chains
The state machine is identical. The envelope is identical. The cert binding is identical. The only thing that differs across the two chains is the per-protocol payload — which is opaque to the substrate and dispatched by lane.
If we kept M-Chain and F-Chain on separate substrates, we would have two copies of the state machine, two copies of the share envelope, two copies of the subject binding. Drift is inevitable; bugs would fix on one side and not the other.
The substrate is the orthogonal piece. The chains are the operational pieces. PHILOSOPHY.md §3.
Cross-chain handoff
The only cross-chain ceremony today is TFHE bootstrap-key gen:
- M-Chain runs FROST DKG on the TFHE secret-key polynomial. The
ceremony has
Kind = KindTFHEKeygen,Lane = LaneMChainFROST. - M-Chain finalizes; the proof's payload is the serialized TFHE evaluation key.
- The substrate's handoff envelope wraps the M-Chain proof into a
F-Chain
SharewithLane = LaneFChainBootstrap. The wrapper's payload is(offset, len)into the upstream artifact buffer. - F-Chain ingests via
OnBootstrapHandoff, verifies the upstream M-Chain ceremony root from the round descriptor, installs the key, advancesfchain_fhe_root. - Quasar 3.0's
certificate_subjectfor the round binds bothmchain_ceremony_root(post-FROST) andfchain_fhe_root(post-install). Atomic from the network's view.
No new envelope type. The handoff is just two shares on two lanes with a deterministic wrapping.
References
| LP | Topic |
|---|---|
| LP-019 | Threshold MPC |
| LP-013 | FHE on GPU |
| LP-076 | Universal Threshold Cryptography |
| LP-132 | QuasarGPU Execution Adapter |
| LP-134 | Lux Chain Topology |
| LP-020 | Quasar Consensus 3.0 |