73 lines
2 KiB
Go
73 lines
2 KiB
Go
package proxy
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"math"
|
|
"strconv"
|
|
)
|
|
|
|
// Job holds the current work unit received from a pool. Immutable once assigned.
|
|
//
|
|
// j := proxy.Job{
|
|
// Blob: "0707d5ef...b01",
|
|
// JobID: "4BiGm3/RgGQzgkTI",
|
|
// Target: "b88d0600",
|
|
// Algo: "cn/r",
|
|
// }
|
|
type Job struct {
|
|
Blob string // hex-encoded block template (160 hex chars = 80 bytes)
|
|
JobID string // pool-assigned identifier
|
|
Target string // 8-char hex little-endian uint32 difficulty target
|
|
Algo string // algorithm e.g. "cn/r", "rx/0"; "" if not negotiated
|
|
Height uint64 // block height (0 if pool did not provide)
|
|
SeedHash string // RandomX seed hash hex (empty if not RandomX)
|
|
ClientID string // pool session ID that issued this job (for stale detection)
|
|
}
|
|
|
|
// IsValid returns true if Blob and JobID are non-empty.
|
|
//
|
|
// if !job.IsValid() { return }
|
|
func (j Job) IsValid() bool {
|
|
return j.Blob != "" && j.JobID != ""
|
|
}
|
|
|
|
// BlobWithFixedByte returns a copy of Blob with hex characters at positions 78-79
|
|
// (blob byte index 39) replaced by the two-digit lowercase hex of fixedByte.
|
|
//
|
|
// partitioned := job.BlobWithFixedByte(0x2A) // chars 78-79 become "2a"
|
|
func (j Job) BlobWithFixedByte(fixedByte uint8) string {
|
|
if len(j.Blob) < 80 {
|
|
return j.Blob
|
|
}
|
|
|
|
blob := []byte(j.Blob)
|
|
blob[78] = lowerHexDigit(fixedByte >> 4)
|
|
blob[79] = lowerHexDigit(fixedByte & 0x0F)
|
|
return string(blob)
|
|
}
|
|
|
|
// DifficultyFromTarget converts the 8-char little-endian hex Target field to a uint64 difficulty.
|
|
//
|
|
// diff := job.DifficultyFromTarget() // "b88d0600" → ~100000
|
|
func (j Job) DifficultyFromTarget() uint64 {
|
|
if len(j.Target) != 8 {
|
|
return 0
|
|
}
|
|
|
|
targetBytes, errorValue := hex.DecodeString(j.Target)
|
|
if errorValue != nil || len(targetBytes) != 4 {
|
|
return 0
|
|
}
|
|
|
|
targetValue := binary.LittleEndian.Uint32(targetBytes)
|
|
if targetValue == 0 {
|
|
return math.MaxUint64
|
|
}
|
|
|
|
return uint64(math.Floor(float64(math.MaxUint32) / float64(targetValue)))
|
|
}
|
|
|
|
func lowerHexDigit(value uint8) byte {
|
|
return strconv.FormatUint(uint64(value), 16)[0]
|
|
}
|