WS ticket dashboard auth, builder universal signing/size limits/fusion obfuscation/dropper bundles, Path Tracer WireGuard topology, SessionGate degraded mode and download timeouts, server bootstrap (data dir, cloudflared dedupe, config port precedence), agent mesh/miner/spread fixes. README refreshed; usb bundle repacked; PROBLEMS.md audit log updated.
120 lines
3.4 KiB
Go
120 lines
3.4 KiB
Go
package miner
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNewEngineNotNil(t *testing.T) {
|
|
e := NewEngine()
|
|
if e == nil || e.cache == nil {
|
|
t.Fatal("NewEngine should allocate cache")
|
|
}
|
|
}
|
|
|
|
func TestEngineSetJobInvalidSeed(t *testing.T) {
|
|
e := NewEngine()
|
|
if err := e.SetJob("zz", strings.Repeat("00", 76)); err == nil {
|
|
t.Fatal("invalid seed hex should error")
|
|
}
|
|
}
|
|
|
|
func TestEngineSetJobInvalidBlob(t *testing.T) {
|
|
e := NewEngine()
|
|
seed := strings.Repeat("ab", 32)
|
|
if err := e.SetJob(seed, "not-hex"); err == nil {
|
|
t.Fatal("invalid blob hex should error")
|
|
}
|
|
}
|
|
|
|
func TestEngineHashAtNonceNoVM(t *testing.T) {
|
|
e := NewEngine()
|
|
hash, blob, err := e.HashAtNonce(0)
|
|
if !errors.Is(err, ErrEngineNotReady) {
|
|
t.Fatalf("expected ErrEngineNotReady, got err=%v hash=%q blob=%q", err, hash, blob)
|
|
}
|
|
if hash != "" || blob != "" {
|
|
t.Fatalf("unready VM should return empty strings, got hash=%q blob=%q", hash, blob)
|
|
}
|
|
}
|
|
|
|
func TestEngineHashAtNonceShortBlob(t *testing.T) {
|
|
e := NewEngine()
|
|
seed := strings.Repeat("cd", 32)
|
|
if err := e.SetJob(seed, strings.Repeat("00", 20)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
hash, blob, err := e.HashAtNonce(1)
|
|
if !errors.Is(err, ErrBlobTooShort) {
|
|
t.Fatalf("expected ErrBlobTooShort, got err=%v hash=%q blob=%q", err, hash, blob)
|
|
}
|
|
if hash != "" || blob != "" {
|
|
t.Fatalf("short blob should return empty strings, got hash=%q blob=%q", hash, blob)
|
|
}
|
|
}
|
|
|
|
// TestEngineFullHash verifies that HashAtNonce produces a valid 32-byte hash
|
|
// when given a proper 76-byte Monero block header. This is the critical path
|
|
// that was previously broken due to missing SuperScalar program initialization.
|
|
func TestEngineFullHash(t *testing.T) {
|
|
// Known test vector from go-randomx's own test suite.
|
|
key := []byte("test key 000")
|
|
input := []byte("This is a test")
|
|
|
|
// Use the same seed the library uses: the raw key bytes hex-encoded.
|
|
seedHex := strings.ToLower(fmt.Sprintf("%x", key))
|
|
|
|
// Build a synthetic 76-byte blob (the engine only needs seed + blob; we use
|
|
// the "input" bytes zero-padded to 76 bytes so nonce sits at offset 39).
|
|
blobBytes := make([]byte, 76)
|
|
copy(blobBytes, input)
|
|
blobHex := fmt.Sprintf("%x", blobBytes)
|
|
|
|
e := NewEngine()
|
|
if err := e.SetJob(seedHex, blobHex); err != nil {
|
|
t.Fatalf("SetJob: %v", err)
|
|
}
|
|
hashHex, gotBlob, err := e.HashAtNonce(0)
|
|
if err != nil {
|
|
t.Fatalf("HashAtNonce: %v", err)
|
|
}
|
|
if len(hashHex) != 64 {
|
|
t.Fatalf("expected 64-char hash hex, got %d chars: %q", len(hashHex), hashHex)
|
|
}
|
|
if len(gotBlob) != 152 {
|
|
t.Fatalf("expected 152-char blob hex, got %d chars", len(gotBlob))
|
|
}
|
|
// Ensure two sequential nonces produce different hashes.
|
|
hashHex2, _, err := e.HashAtNonce(1)
|
|
if err != nil {
|
|
t.Fatalf("HashAtNonce(1): %v", err)
|
|
}
|
|
if hashHex == hashHex2 {
|
|
t.Fatal("nonce 0 and nonce 1 produced identical hashes — nonce injection broken")
|
|
}
|
|
}
|
|
|
|
// TestEngineReSeedChangesHash confirms the engine re-seeds when the seed changes.
|
|
func TestEngineReSeedChangesHash(t *testing.T) {
|
|
blobHex := strings.Repeat("0c", 76)
|
|
seed1 := strings.Repeat("aa", 32)
|
|
seed2 := strings.Repeat("bb", 32)
|
|
|
|
e := NewEngine()
|
|
if err := e.SetJob(seed1, blobHex); err != nil {
|
|
t.Fatalf("SetJob seed1: %v", err)
|
|
}
|
|
h1, _, _ := e.HashAtNonce(0)
|
|
|
|
if err := e.SetJob(seed2, blobHex); err != nil {
|
|
t.Fatalf("SetJob seed2: %v", err)
|
|
}
|
|
h2, _, _ := e.HashAtNonce(0)
|
|
|
|
if h1 == h2 {
|
|
t.Fatal("different seeds produced identical hash — re-seed is broken")
|
|
}
|
|
}
|