mirror of
https://github.com/luxfi/chains.git
synced 2026-09-24 00:26:00 +00:00
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.
120 lines
4.8 KiB
Go
120 lines
4.8 KiB
Go
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package fhevm
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/luxfi/chains/fee"
|
|
)
|
|
|
|
// TestGas_PerSchemeDistinct proves the cost model is real: a TFHE boolean, a
|
|
// BFV vector and a CKKS vector are priced differently, and doubling the ring
|
|
// dimension raises the price.
|
|
func TestGas_PerSchemeDistinct(t *testing.T) {
|
|
feeFor := func(scheme string) uint64 {
|
|
f, err := FeeFor(&Transaction{Type: TxRequestDecrypt, Scheme: scheme})
|
|
require.NoError(t, err)
|
|
return f
|
|
}
|
|
require.Less(t, feeFor("tfhe-n10"), feeFor("bfv-n13"), "small LWE ciphertexts are cheapest")
|
|
require.Less(t, feeFor("bfv-n13"), feeFor("ckks-n13"), "at equal N, CKKS costs more than BFV")
|
|
require.Less(t, feeFor("bfv-n13"), feeFor("bfv-n14"), "doubling the ring dimension must cost more")
|
|
require.Less(t, feeFor("ckks-n14"), feeFor("ckks-n15"), "doubling the ring dimension must cost more")
|
|
require.NotEqual(t, feeFor("bfv-n13"), feeFor("bgv-n13"), "distinct schemes must price distinctly")
|
|
}
|
|
|
|
// TestGas_AllOperationsMeetFloor proves every scheduled operation settles at or
|
|
// above the node admission floor, so settlement and admission never drift.
|
|
func TestGas_AllOperationsMeetFloor(t *testing.T) {
|
|
for op := range opBaseGas {
|
|
if usesScheme(op) {
|
|
for scheme := range schemeGas {
|
|
f, err := FeeFor(&Transaction{Type: op, Scheme: scheme})
|
|
require.NoError(t, err)
|
|
require.GreaterOrEqualf(t, f, fee.MinTxFeeFloor,
|
|
"op %d scheme %s fee %d below floor %d", op, scheme, f, fee.MinTxFeeFloor)
|
|
}
|
|
continue
|
|
}
|
|
f, err := FeeFor(&Transaction{Type: op})
|
|
require.NoError(t, err)
|
|
require.GreaterOrEqualf(t, f, fee.MinTxFeeFloor,
|
|
"op %d fee %d below floor %d", op, f, fee.MinTxFeeFloor)
|
|
}
|
|
require.GreaterOrEqual(t, MinScheduledFee(), fee.MinTxFeeFloor,
|
|
"the cheapest scheduled fee must satisfy the admission floor")
|
|
}
|
|
|
|
// TestGas_UnknownSchemeRejected proves an unrecognised scheme is refused (fail
|
|
// closed), never priced at the bare base cost.
|
|
func TestGas_UnknownSchemeRejected(t *testing.T) {
|
|
_, err := GasFor(&Transaction{Type: TxRegisterCiphertext, Scheme: "paillier"})
|
|
require.ErrorIs(t, err, ErrUnknownScheme)
|
|
|
|
_, err = GasFor(&Transaction{Type: TxRequestDecrypt, Scheme: ""})
|
|
require.ErrorIs(t, err, ErrUnknownScheme)
|
|
|
|
require.False(t, SupportedScheme("paillier"))
|
|
require.True(t, SupportedScheme(testScheme))
|
|
}
|
|
|
|
// TestGas_UnknownOperationRejected proves an unpriced transaction type cannot
|
|
// slip through at zero cost.
|
|
func TestGas_UnknownOperationRejected(t *testing.T) {
|
|
_, err := GasFor(&Transaction{Type: 200, Scheme: testScheme})
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// TestGas_RecordOpsIgnoreWhichScheme proves the fixed-size record writes do not
|
|
// care WHICH scheme is named — only how many bytes it takes to name it, which
|
|
// every operation pays for because every operation stores it.
|
|
func TestGas_RecordOpsIgnoreWhichScheme(t *testing.T) {
|
|
for _, op := range []uint8{TxGrantPermit, TxRevokePermit, TxFulfillDecrypt, TxAdvanceEpoch} {
|
|
a, err := FeeFor(&Transaction{Type: op, Scheme: "ckks-n15"})
|
|
require.NoError(t, err)
|
|
b, err := FeeFor(&Transaction{Type: op, Scheme: "tfhe-n10"})
|
|
require.NoError(t, err)
|
|
require.Equalf(t, a, b, "op %d must not care which scheme is named", op)
|
|
|
|
none, err := FeeFor(&Transaction{Type: op})
|
|
require.NoError(t, err)
|
|
require.Greaterf(t, a, none, "op %d must still pay for the bytes it stores", op)
|
|
}
|
|
}
|
|
|
|
// TestGas_EveryOperationIsPriced proves the schedule covers every transaction
|
|
// type the package defines — a new operation cannot ship unpriced.
|
|
func TestGas_EveryOperationIsPriced(t *testing.T) {
|
|
for _, op := range []uint8{
|
|
TxRegisterCiphertext, TxGrantPermit, TxRevokePermit,
|
|
TxRequestDecrypt, TxFulfillDecrypt, TxAdvanceEpoch,
|
|
} {
|
|
require.Containsf(t, opBaseGas, op, "transaction type %d has no base gas", op)
|
|
require.Containsf(t, opNames, op, "transaction type %d has no public name", op)
|
|
}
|
|
require.Len(t, opBaseGas, len(opNames), "every priced operation must have exactly one name")
|
|
}
|
|
|
|
// TestFeeForRefusesWhatItCannotPrice proves the fee surface fails closed on the
|
|
// same inputs the gas schedule does. A fee that defaulted to zero on an unknown
|
|
// operation would be an operation that settles nothing.
|
|
func TestFeeForRefusesWhatItCannotPrice(t *testing.T) {
|
|
if _, err := FeeFor(&Transaction{Type: 99}); err == nil {
|
|
t.Fatal("FeeFor priced an operation the schedule does not name")
|
|
}
|
|
if _, err := FeeFor(&Transaction{Type: TxRegisterCiphertext, Scheme: "rot13-n1"}); err == nil {
|
|
t.Fatal("FeeFor priced a scheme the schedule does not name")
|
|
}
|
|
f, err := FeeFor(&Transaction{Type: TxRegisterCiphertext, Scheme: testScheme})
|
|
if err != nil {
|
|
t.Fatalf("the control failed: %v", err)
|
|
}
|
|
if f == 0 {
|
|
t.Fatal("a priced operation settles nothing")
|
|
}
|
|
}
|