Files
evm/core/parallel/gpu_bridge_test.go
zeekay 458178730d evm: derive plugin VM ID from luxfi/constants.EVMID; bump luxfi/gpu v1.0.1
- cmd/vmid prints constants.EVMID — Go source of truth for the C-Chain VM
  ID. Build scripts and Makefile now call this instead of hardcoding the
  base58 string. Drops a stale subnet-evm ID (ag3GReYP…) from the Makefile.
- scripts/build.sh: default output is build/evm; INSTALL=1 installs under
  the derived VMID at \$LUX_PLUGIN_DIR. Codesigns on darwin in-line so a
  fresh binary doesn't get SIGKILLed by gatekeeper post-cp.
- core/parallel/gpu_bridge.go: build tag flipped from \`!nogpu\` (opt-out)
  to \`gpu\` (opt-in) so default builds don't drag in luxfi/gpu cgo.
- go.mod: luxfi/gpu v0.30.0 → v1.0.1. v0.30.0 referenced removed MLX
  symbols (mlx_from_slice_int64 etc.); v1.0.1 migrated to lux/gpu.h and
  builds cleanly with -tags gpu and -tags \"cevm gpu\".
- LLM.md: build commands updated; \"no canonical / no aliases\" reflects
  reality (single VMID, one filename, derived from Go).
2026-05-11 22:36:46 -07:00

154 lines
4.0 KiB
Go

// Copyright (C) 2025-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
//go:build cgo && darwin && gpu
package parallel
import (
"math/big"
"testing"
)
// TestRecoverV_LegacyValid verifies valid legacy V values (27, 28).
func TestRecoverV_LegacyValid(t *testing.T) {
tests := []struct {
v uint64
wantID uint8
wantOK bool
}{
{27, 0, true},
{28, 1, true},
}
for _, tt := range tests {
id, ok := recoverV(big.NewInt(int64(tt.v)), nil)
if ok != tt.wantOK || id != tt.wantID {
t.Errorf("recoverV(%d, nil) = (%d, %v), want (%d, %v)",
tt.v, id, ok, tt.wantID, tt.wantOK)
}
}
}
// TestRecoverV_InvalidV verifies that V=0 is rejected.
func TestRecoverV_InvalidV(t *testing.T) {
_, ok := recoverV(big.NewInt(0), nil)
if ok {
t.Fatal("V=0 must be rejected for legacy transactions")
}
_, ok = recoverV(big.NewInt(1), nil)
if ok {
t.Fatal("V=1 must be rejected for legacy transactions (not 27 or 28)")
}
_, ok = recoverV(big.NewInt(26), nil)
if ok {
t.Fatal("V=26 must be rejected for legacy transactions")
}
_, ok = recoverV(big.NewInt(29), nil)
if ok {
t.Fatal("V=29 must be rejected for legacy transactions")
}
}
// TestRecoverV_EIP155 verifies EIP-155 V values for chain ID 1.
func TestRecoverV_EIP155(t *testing.T) {
chainID := big.NewInt(1)
// EIP-155: v = chainId * 2 + 35 + recovery_id
// Chain 1: v=37 => recovery 0, v=38 => recovery 1
id, ok := recoverV(big.NewInt(37), chainID)
if !ok || id != 0 {
t.Fatalf("recoverV(37, chainID=1): got (%d, %v), want (0, true)", id, ok)
}
id, ok = recoverV(big.NewInt(38), chainID)
if !ok || id != 1 {
t.Fatalf("recoverV(38, chainID=1): got (%d, %v), want (1, true)", id, ok)
}
}
// TestRecoverV_OverflowChainID verifies that a chain ID with >63 bits
// is rejected (prevents uint64 overflow).
func TestRecoverV_OverflowChainID(t *testing.T) {
// 64-bit chain ID: BitLen > 63
bigChainID := new(big.Int).Lsh(big.NewInt(1), 64) // 2^64
_, ok := recoverV(big.NewInt(37), bigChainID)
if ok {
t.Fatal("chain ID with >63 bits must be rejected")
}
}
// TestRecoverV_OverflowV verifies that a V value with >63 bits is rejected.
func TestRecoverV_OverflowV(t *testing.T) {
bigV := new(big.Int).Lsh(big.NewInt(1), 64) // 2^64
_, ok := recoverV(bigV, big.NewInt(1))
if ok {
t.Fatal("V with >63 bits must be rejected")
}
}
// TestPadTo32_Normal verifies padding of normal values.
func TestPadTo32_Normal(t *testing.T) {
n := big.NewInt(0xFF)
padded := padTo32(n)
if len(padded) != 32 {
t.Fatalf("expected 32 bytes, got %d", len(padded))
}
if padded[31] != 0xFF {
t.Fatalf("expected last byte 0xFF, got 0x%x", padded[31])
}
// All leading bytes should be zero
for i := 0; i < 31; i++ {
if padded[i] != 0 {
t.Fatalf("byte %d should be 0, got 0x%x", i, padded[i])
}
}
}
// TestPadTo32_Exactly32 verifies that a 32-byte value is returned as-is.
func TestPadTo32_Exactly32(t *testing.T) {
n := new(big.Int).Lsh(big.NewInt(1), 248) // 32 bytes
b := n.Bytes()
if len(b) > 32 {
t.Skip("test precondition: value is exactly 32 bytes")
}
padded := padTo32(n)
if len(padded) != 32 {
t.Fatalf("expected 32 bytes, got %d", len(padded))
}
}
// TestPadTo32_Oversized verifies that values >32 bytes return nil.
func TestPadTo32_Oversized(t *testing.T) {
// 33 bytes: 2^264
n := new(big.Int).Lsh(big.NewInt(1), 264)
padded := padTo32(n)
if padded != nil {
t.Fatal("oversized value (>32 bytes) must return nil")
}
}
// TestPadTo32_Zero verifies zero value.
func TestPadTo32_Zero(t *testing.T) {
padded := padTo32(big.NewInt(0))
if len(padded) != 32 {
t.Fatalf("expected 32 bytes, got %d", len(padded))
}
for i, b := range padded {
if b != 0 {
t.Fatalf("byte %d should be 0, got 0x%x", i, b)
}
}
}
// TestSecp256k1HalfN_IsPositive ensures the half-N constant is computed.
func TestSecp256k1HalfN_IsPositive(t *testing.T) {
if secp256k1halfN.Sign() <= 0 {
t.Fatal("secp256k1halfN must be positive")
}
if secp256k1halfN.BitLen() < 200 {
t.Fatalf("secp256k1halfN seems too small: %d bits", secp256k1halfN.BitLen())
}
}