Complete private Monero miner control stack.

Implement Windows agent with RandomX mining and WebSocket fleet reporting, wire dashboard settings into the builder with saved exe paths, and add project README.
This commit is contained in:
drjones
2026-05-26 22:51:47 -07:00
commit 6c42f2b600
48 changed files with 10001 additions and 0 deletions

65
agent/miner/engine.go Normal file
View File

@@ -0,0 +1,65 @@
package miner
import (
"encoding/hex"
"sync"
"git.gammaspectra.live/P2Pool/go-randomx"
)
const nonceOffset = 39
const nonceSize = 4
type Engine struct {
mu sync.RWMutex
cache *randomx.Randomx_Cache
vm *randomx.VM
seedHex string
blob []byte
}
func NewEngine() *Engine {
cache := randomx.Randomx_alloc_cache(0)
return &Engine{cache: cache}
}
func (e *Engine) SetJob(seedHex, blobHex string) error {
seed, err := hex.DecodeString(seedHex)
if err != nil {
return err
}
blob, err := hex.DecodeString(blobHex)
if err != nil {
return err
}
e.mu.Lock()
defer e.mu.Unlock()
if e.seedHex != seedHex {
e.cache.Randomx_init_cache(seed)
e.vm = e.cache.VM_Initialize()
e.seedHex = seedHex
}
e.blob = append([]byte(nil), blob...)
return nil
}
func (e *Engine) HashAtNonce(nonce uint32) (hashHex string, blobHex string, err error) {
e.mu.RLock()
defer e.mu.RUnlock()
if e.vm == nil || len(e.blob) < nonceOffset+nonceSize {
return "", "", nil
}
work := append([]byte(nil), e.blob...)
work[nonceOffset] = byte(nonce)
work[nonceOffset+1] = byte(nonce >> 8)
work[nonceOffset+2] = byte(nonce >> 16)
work[nonceOffset+3] = byte(nonce >> 24)
out := make([]byte, 32)
e.vm.CalculateHash(work, out)
return hex.EncodeToString(out), hex.EncodeToString(work), nil
}