m2pool-core/internal/server/randomxT/hash_randomx.go

118 lines
2.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 <randomx.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
*/
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
}