warpmsg is the one place bridgevm, mpcvm and zkvm turn a payload into a signed
cross-chain envelope. It copied whatever the signer returned into a fixed
96-byte array without checking the length. Signer is an interface, so that
width is a runtime fact: a short signature was silently zero-padded and a long
one silently truncated, and either way the envelope came out well-formed and
unverifiable -- a message the sender believes it sent and no receiver can ever
accept, with no error anywhere.
oraclevm's accel host documented an error for a nil VM and never checked,
deferring the failure to whichever method the operator called first.
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]>
Standardize all of chains on github.com/luxfi/warp v1.23.0 (the standalone
ZAP-native warp that precompile/evm/bridgevm already use). zkvm/fhe and
thresholdvm/fhe are migrated OFF github.com/luxfi/node/vms/platformvm/warp;
there are now ZERO platformvm/warp imports in chains.
The build->sign->wrap sequence (previously copy-pasted in three places and
split across two warp libraries) now lives in exactly one place:
internal/warpmsg.BuildSigned(signer, networkID, sourceChainID, payload)
-> (*warp.Envelope, error). It builds a content Message (NewMessage), signs
it over the Beam domain with the node BLS key, and wraps the signature at
validator bit index 0 into a single-signer Envelope. All three send sites
call it:
- bridgevm/vm.go reshare-request gossip
- zkvm/fhe/coprocessor FHE task-result callback
- thresholdvm/fhe/relayer decryption fulfillment
v1.23.0 split the signature from the Message: the signed/transmittable unit
is now *warp.Envelope (Message + Beam BitSetSignature + PQ lanes), not a
combined Message. The receive path moves with it: onMessage callbacks and
WarpHandler.HandleMessage now carry *warp.Envelope and read authenticated
content from env.Message. MPC/BLS single-signer semantics are preserved
exactly (bit-0 signer, Beam-domain BLS, receiver aggregates/verifies the
BitSetSignature against the canonical validator set via warp.VerifyEnvelope).
CGO_ENABLED=0 build/vet clean; bridgevm/zkvm/thresholdvm test suites green.