FILE / ScuroNeko/go-deepseek
pow/pow.go
Исходный файл и его история в репозитории.
142 lines
2.9 KiB
Go
142 lines
2.9 KiB
Go
package pow
|
|
|
|
/*
|
|
#cgo CXXFLAGS: -std=c++17 -O3 -mavx2 -pthread
|
|
#cgo LDFLAGS: -lstdc++ -pthread
|
|
|
|
#include <stdlib.h>
|
|
#include "pow.h"
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"unsafe"
|
|
)
|
|
|
|
var (
|
|
// ErrNotFound indicates that no nonce satisfies the challenge difficulty.
|
|
ErrNotFound = errors.New("PoW solution not found")
|
|
// ErrInvalidArgument indicates malformed or unsupported solver input.
|
|
ErrInvalidArgument = errors.New("invalid PoW argument")
|
|
// ErrInternalCppError indicates an exception in the native solver.
|
|
ErrInternalCppError = errors.New("internal C++ solver error")
|
|
)
|
|
|
|
// Challenge contains the inputs required to solve a DeepSeekHashV1 challenge.
|
|
type Challenge struct {
|
|
Algorithm string `json:"algorithm"`
|
|
Challenge string `json:"challenge"`
|
|
Salt string `json:"salt"`
|
|
Difficulty uint64 `json:"difficulty"`
|
|
ExpireAt uint64 `json:"expire_at"`
|
|
Signature string `json:"signature"`
|
|
TargetPath string `json:"target_path"`
|
|
}
|
|
|
|
// Solve validates and solves c, returning a nonce smaller than Difficulty.
|
|
func (c Challenge) Solve() (uint64, error) {
|
|
if c.Algorithm != "" && c.Algorithm != "DeepSeekHashV1" {
|
|
return 0, fmt.Errorf(
|
|
"unsupported PoW algorithm %q",
|
|
c.Algorithm,
|
|
)
|
|
}
|
|
|
|
if len(c.Challenge) != 64 {
|
|
return 0, fmt.Errorf(
|
|
"%w: challenge must contain 64 hexadecimal characters",
|
|
ErrInvalidArgument,
|
|
)
|
|
}
|
|
|
|
if c.Salt == "" {
|
|
return 0, fmt.Errorf(
|
|
"%w: salt is empty",
|
|
ErrInvalidArgument,
|
|
)
|
|
}
|
|
|
|
if c.Difficulty <= 0 {
|
|
return 0, fmt.Errorf(
|
|
"%w: difficulty must be positive",
|
|
ErrInvalidArgument,
|
|
)
|
|
}
|
|
|
|
base := c.Salt +
|
|
"_" +
|
|
strconv.FormatUint(c.ExpireAt, 10) +
|
|
"_"
|
|
|
|
return Solve(base, c.Challenge, c.Difficulty)
|
|
}
|
|
|
|
// Solve searches the range [0, difficulty) for a nonce whose DeepSeekHashV1
|
|
// digest equals challengeHex.
|
|
func Solve(
|
|
base string,
|
|
challengeHex string,
|
|
difficulty uint64,
|
|
) (uint64, error) {
|
|
if base == "" {
|
|
return 0, fmt.Errorf(
|
|
"%w: base is empty",
|
|
ErrInvalidArgument,
|
|
)
|
|
}
|
|
|
|
if len(challengeHex) != 64 {
|
|
return 0, fmt.Errorf(
|
|
"%w: challenge must contain 64 hexadecimal characters",
|
|
ErrInvalidArgument,
|
|
)
|
|
}
|
|
|
|
if difficulty <= 0 {
|
|
return 0, fmt.Errorf(
|
|
"%w: difficulty must be positive",
|
|
ErrInvalidArgument,
|
|
)
|
|
}
|
|
|
|
baseBytes := []byte(base)
|
|
challengeBytes := []byte(challengeHex)
|
|
|
|
result := C.deepseek_pow_solve(
|
|
(*C.char)(unsafe.Pointer(&baseBytes[0])),
|
|
C.size_t(len(baseBytes)),
|
|
(*C.char)(unsafe.Pointer(&challengeBytes[0])),
|
|
C.size_t(len(challengeBytes)),
|
|
C.int64_t(difficulty),
|
|
)
|
|
|
|
switch {
|
|
case result >= 0:
|
|
return uint64(result), nil
|
|
|
|
case result == -1:
|
|
return 0, ErrNotFound
|
|
|
|
case result == -2:
|
|
return 0, fmt.Errorf(
|
|
"%w: null pointer passed to C++",
|
|
ErrInvalidArgument,
|
|
)
|
|
|
|
case result == -3:
|
|
return 0, ErrInvalidArgument
|
|
|
|
case result == -4:
|
|
return 0, ErrInternalCppError
|
|
|
|
default:
|
|
return 0, fmt.Errorf(
|
|
"unexpected C++ solver result: %d",
|
|
int64(result),
|
|
)
|
|
}
|
|
}
|