Files
zeekayandHanzo Dev 5b30b8b035 bridgevm: rip out vestigial BLS custody subsystem — custody is M-Chain
B-Chain does NOT do threshold custody keygen/signing. Custody is
M-Chain's job: dealerless CGGMP21/FROST distributed keygen via
luxfi/threshold (cmp.Keygen/frost.Keygen — multi-round protocols over a
message router; no trusted dealer, the group secret is never assembled
by any validator). B-Chain requests keygen/reshare/sign from M-Chain
over Warp (CrossChainMPCRequest) and only VERIFIES the resulting CMP
threshold signatures (block.Verify → mpcConfig, accel_verify.go).

bridgevm carried a SECOND, parallel MPC subsystem — a BLS MPCKeyManager
that did its own in-VM keygen (until this session, via a trusted dealer)
feeding BridgeSigner/DeliveryConfirmationSigner/BridgeMessageValidator.
It duplicated custody, used the wrong scheme (BLS vs the live CMP path),
and was never in block.Verify. Deleted entirely — one and one way.

Removed:
- mpc.go (MPCKeyManager, SigningSession)
- bridge_signing.go (BridgeSigner, DeliveryConfirmationSigner,
  BridgeMessageValidator, MPCCoordinator, BridgeMessage/DeliveryConfirmation)
- vm_mpc_integration.go (InitializeMPCKeys, TriggerKeygen, ProcessBridgeMessage)
- vm.go: the 5 BLS fields + their init block (no key material is
  generated on B-Chain now)
- feegate.go: gateUserBridgeMessage (BLS-message fee gate) → replaced by
  gateUserBridgeFee(uint64) on the live path (LP-0130 §8)

Relocated / repointed:
- ErrInvalidBridgeSignature → accel_verify.go (the live CMP verify path)
- rpc.go MPCReady/MPCPublicKey → vm.mpcGroupPublicKey() (reads the CMP
  custody group point from mpcConfig, i.e. M-Chain's key), never a
  B-Chain-held secret

Build + vet + full bridgevm tests green.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-03 13:57:33 -07:00

61 lines
1.9 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package bridgevm
import (
"errors"
"testing"
"github.com/luxfi/log"
"github.com/luxfi/node/vms/types/fee"
)
// newBridgeVMWithPolicy wires a VM with the canonical FlatPolicy
// directly, bypassing the full Initialize (which requires the M-Chain
// custody keygen handshake, 1M LUX bond validation, etc.).
func newBridgeVMWithPolicy(networkID uint32) *VM {
v := &VM{log: log.NewNoOpLogger()}
v.networkID = networkID
v.feePolicy = newFeePolicy(networkID)
return v
}
func TestBridgeVM_FeePolicy_AttachedAtInit(t *testing.T) {
v := newBridgeVMWithPolicy(96369)
if v.FeePolicy() == nil {
t.Fatal("FeePolicy() = nil; want non-nil FlatPolicy")
}
if got := v.FeePolicy().MinTxFee(); got != fee.MinTxFeeFloor {
t.Errorf("MinTxFee() = %d, want %d", got, fee.MinTxFeeFloor)
}
if err := fee.Validate(v.FeePolicy()); err != nil {
t.Errorf("fee.Validate = %v, want nil", err)
}
}
// The fee gate (LP-0130 §8) refuses a zero-fee bridge transfer before any
// M-Chain signing capacity is consumed.
func TestBridgeVM_FeeGate_RejectsZeroFee(t *testing.T) {
v := newBridgeVMWithPolicy(96369)
if err := v.gateUserBridgeFee(0); !errors.Is(err, fee.ErrInsufficientFee) {
t.Fatalf("gateUserBridgeFee(0) = %v, want ErrInsufficientFee", err)
}
}
func TestBridgeVM_FeeGate_AcceptsMinFee(t *testing.T) {
v := newBridgeVMWithPolicy(96369)
if err := v.gateUserBridgeFee(fee.MinTxFeeFloor); err != nil {
t.Fatalf("gateUserBridgeFee(min) = %v, want nil", err)
}
}
// Custody group key is nil until M-Chain completes dealerless keygen —
// B-Chain never generates key material itself.
func TestBridgeVM_NoLocalCustodyKey(t *testing.T) {
v := newBridgeVMWithPolicy(96369)
if key := v.mpcGroupPublicKey(); key != nil {
t.Fatalf("mpcGroupPublicKey() = %x, want nil (no B-Chain keygen)", key)
}
}