Files
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

60 lines
2.1 KiB
Go

// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package chain
import (
"github.com/luxfi/chains/fee"
"github.com/luxfi/constants"
"github.com/luxfi/ids"
)
// Fee is what a chain charges to admit a user transaction, and the check that
// refuses one paying less.
//
// It is a DECLARATION at the boundary, orthogonal to settlement: this says
// what the chain costs to submit to, while the actual per-operation debit and
// burn happen inside consensus against the payer's on-chain balance
// (github.com/luxfi/chains/fee). A chain declares one of these at Initialize;
// the node's boot-time fee.Validate reads it.
//
// The zero Fee admits nothing, so a chain that forgets to declare one refuses
// every caller rather than admitting every caller.
type Fee struct {
policy fee.Policy
asset ids.ID
}
// Floor is the canonical declaration for a chain that accepts user-submitted
// work: the network's UTXO asset at the minimum transaction fee. A chain with
// a user-facing entry MUST charge at least this, or fee.Validate flags it
// at boot as a zero-fee user-facing chain.
func Floor(networkID uint32) Fee {
asset := constants.UTXOAssetIDFor(networkID)
return Fee{
policy: fee.FlatPolicy{Fee: fee.MinTxFeeFloor, AssetID: asset},
asset: asset,
}
}
// Closed is the declaration for a chain that accepts no user transactions at
// all — one driven by validators through consensus, or one that only reads.
// Every caller is refused, so an entry that exposes itself as user-callable
// still refuses explicitly instead of by omission.
func Closed() Fee {
return Fee{policy: fee.NoUserTxPolicy{}, asset: fee.NoUserTxPolicy{}.FeeAssetID()}
}
// Admit refuses a payment the declaration does not cover. Every user-facing
// entry that produces an on-chain effect passes through here before the effect
// is reachable.
func (f Fee) Admit(paid uint64) error {
if f.policy == nil {
return fee.ErrChainAcceptsNoUserTxs
}
return f.policy.ValidateFee(paid, f.asset)
}
// Policy is the declaration itself, for diagnostics and the boot-time gate.
func (f Fee) Policy() fee.Policy { return f.policy }