Files
chains/mpcvm/types/participant.go
T
zeekay a93f6e3dec build the VMs without the daemon in their closure
A plugin is its own binary; the daemon that loads it has no business being
linked into it. Twelve VMs reached into github.com/luxfi/node for four things,
and each one now programs against a home that is actually its own:

- fee admission (Policy, FlatPolicy, NoUserTxPolicy, Validate) joins the
  settlement half already in chains/fee. One fee package, and the nodefee alias
  that marked the split is gone.
- the cross-chain artifact types move to chains/artifacts.
- the factory the daemon registers is luxfi/vm/manager.Factory, and the version
  types are luxfi/version. Both are ordinary modules the daemon reads too, so a
  VM imports them directly rather than through anything of ours.

The GPU switch is deleted, not moved. It was a global set during daemon startup
that a separate process could never observe, so every plugin read its default;
FHEOptions.Backend is the switch that was really there.

go list -deps names no luxfi/node for aivm, bridgevm, dexvm, evm, fhevm,
graphvm, identityvm, keyvm, mpcvm, quantumvm, schain or zkvm, and the built
plugin binaries carry no such string. oraclevm and relayvm still do: they are
re-export shims over luxfi/oracle and luxfi/relay, which build their fee
policies upstream. Their tests keep naming the daemon's fee package because
that is the type their value has.
2026-09-03 21:10:40 -07:00

98 lines
3.1 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package types
import (
"crypto/sha256"
"encoding/binary"
"errors"
"sort"
)
// NodeID identifies a Lux validator. Same definition as the rest of
// the platform — 32 bytes, content-addressed.
type NodeID [32]byte
// Participant is one validator selected (via stake-weighted VRF) into
// the participant set of a ceremony. The substrate does not pick
// participants; the host chain (M-Chain or F-Chain) does, then hands
// the resulting set here.
type Participant struct {
Node NodeID
Index uint32 // canonical index inside the ParticipantSet (0..n-1)
Weight uint64 // stake weight at selection time, for accounting only
}
// ParticipantSet is the deterministic, ordered set of validators for
// one ceremony. The set is fixed at registration; resharing is a new
// ceremony with a new set, never an in-place mutation.
type ParticipantSet struct {
CeremonyID CeremonyID
Members []Participant // sorted ascending by NodeID; Index == position
}
// NewParticipantSet builds a ParticipantSet, sorting members by NodeID
// and assigning Index = position. Returns an error if the input has
// duplicate nodes or is empty.
func NewParticipantSet(ceremonyID CeremonyID, members []Participant) (*ParticipantSet, error) {
if len(members) == 0 {
return nil, errors.New("participant: empty set")
}
out := make([]Participant, len(members))
copy(out, members)
sort.Slice(out, func(i, j int) bool {
for k := 0; k < len(out[i].Node); k++ {
if out[i].Node[k] != out[j].Node[k] {
return out[i].Node[k] < out[j].Node[k]
}
}
return false
})
for i := 1; i < len(out); i++ {
if out[i-1].Node == out[i].Node {
return nil, errors.New("participant: duplicate node in set")
}
}
for i := range out {
out[i].Index = uint32(i)
}
return &ParticipantSet{CeremonyID: ceremonyID, Members: out}, nil
}
// Digest returns the canonical 32-byte digest of the set. Used as the
// participant_root when a ceremony is registered, and as input to the
// stake-weighted VRF for the next ceremony.
func (ps *ParticipantSet) Digest() [32]byte {
h := sha256.New()
h.Write(ps.CeremonyID[:])
var buf [12]byte
for _, m := range ps.Members {
h.Write(m.Node[:])
binary.BigEndian.PutUint32(buf[0:4], m.Index)
binary.BigEndian.PutUint64(buf[4:12], m.Weight)
h.Write(buf[:])
}
var out [32]byte
copy(out[:], h.Sum(nil))
return out
}
// Selector is implemented by the host chain (M-Chain or F-Chain). The
// substrate consumes a Selector to produce a ParticipantSet at
// ceremony registration time.
//
// Selectors must be:
//
// - deterministic: same input -> same output, byte for byte
// - permissionless: any validator with stake delegated to the chain
// is eligible (no allowlist)
// - stake-weighted: probability of selection is proportional to
// stake delegated to the chain at the cutoff epoch
//
// The substrate does not implement Selector; M-Chain and F-Chain each
// provide one wired to their stake delegation.
type Selector interface {
Select(ceremonyID CeremonyID, total uint16, seed [32]byte) (*ParticipantSet, error)
}