package randomxT /* #cgo CFLAGS: -I/home/lizixuan/桌面/tari-server/internal/server/include #cgo LDFLAGS: -L/home/lizixuan/桌面/tari-server/internal/server/lib/randomx -lrandomx #include #include #include #include */ import "C" import ( "fmt" "unsafe" "golang.org/x/sys/cpu" ) type RandomXValidator struct { cache *C.randomx_cache vm *C.randomx_vm flags C.randomx_flags seed []byte } // NewRandomXValidator 初始化 cache + vm func NewRandomXValidator(seed []byte) (*RandomXValidator, error) { if len(seed) != 32 { return nil, fmt.Errorf("seed must be 32 bytes") } var flags C.randomx_flags = 0 // 检测 AES-NI 支持 if cpu.X86.HasAES { flags |= C.RANDOMX_FLAG_HARD_AES } else { fmt.Println("[RandomX] CPU 不支持 AES-NI,将使用纯软件模式") } // ⚠️ 默认启用 JIT(如果系统禁止会报错) flags |= C.RANDOMX_FLAG_JIT // 分配 cache cache := C.randomx_alloc_cache(flags) if cache == nil { return nil, fmt.Errorf("failed to alloc cache") } C.randomx_init_cache(cache, unsafe.Pointer(&seed[0]), C.size_t(len(seed))) // 创建 vm vm := C.randomx_create_vm(flags, cache, nil) if vm == nil { C.randomx_release_cache(cache) return nil, fmt.Errorf("failed to create randomx vm") } return &RandomXValidator{ cache: cache, vm: vm, flags: flags, seed: append([]byte{}, seed...), }, nil } // SetSeed 更新 seed(替换 cache,并重置 vm) func (v *RandomXValidator) SetSeed(seed []byte) error { if len(seed) != 32 { return fmt.Errorf("seed must be 32 bytes") } // 如果相同 seed,不用更新 if string(seed) == string(v.seed) { return nil } C.randomx_init_cache(v.cache, unsafe.Pointer(&seed[0]), C.size_t(len(seed))) C.randomx_vm_set_cache(v.vm, v.cache) v.seed = append(v.seed[:0], seed...) return nil } // Destroy 释放 vm + cache func (v *RandomXValidator) Destroy() { if v.vm != nil { C.randomx_destroy_vm(v.vm) v.vm = nil } if v.cache != nil { C.randomx_release_cache(v.cache) v.cache = nil } } // BuildPowHash 计算区块哈希 func (v *RandomXValidator) BuildPowHash(blockBlob, nonce []byte) ([]byte, []byte, error) { if v.vm == nil { return nil, nil, fmt.Errorf("vm is nil") } if len(nonce) != 4 { return nil, nil, fmt.Errorf("nonce must be 4 bytes") } blockHeader := make([]byte, len(blockBlob)) copy(blockHeader, blockBlob) copy(blockHeader[39:43], nonce) var hash [32]byte C.randomx_calculate_hash(v.vm, unsafe.Pointer(&blockHeader[0]), C.size_t(len(blockHeader)), unsafe.Pointer(&hash[0]), ) return hash[:], blockHeader, nil }