86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package stratum
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"git.gammaspectra.live/P2Pool/consensus/v4/types"
|
|
fasthex "github.com/tmthrgd/go-hex"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
type MinerTrackingEntry struct {
|
|
Lock sync.RWMutex
|
|
Counter atomic.Uint64
|
|
LastTemplate atomic.Uint64
|
|
Templates map[uint64]*Template
|
|
LastJob time.Time
|
|
}
|
|
|
|
const JobIdentifierSize = 8 + 4 + 4 + 4 + types.HashSize
|
|
|
|
type JobIdentifier [JobIdentifierSize]byte
|
|
|
|
func JobIdentifierFromString(s string) (JobIdentifier, error) {
|
|
var h JobIdentifier
|
|
if buf, err := fasthex.DecodeString(s); err != nil {
|
|
return h, err
|
|
} else {
|
|
if len(buf) != JobIdentifierSize {
|
|
return h, errors.New("wrong job id size")
|
|
}
|
|
copy(h[:], buf)
|
|
return h, nil
|
|
}
|
|
}
|
|
func JobIdentifierFromValues(templateCounter uint64, extraNonce, sideRandomNumber, sideExtraNonce uint32, templateId types.Hash) JobIdentifier {
|
|
var h JobIdentifier
|
|
binary.LittleEndian.PutUint64(h[:], templateCounter)
|
|
binary.LittleEndian.PutUint32(h[8:], extraNonce)
|
|
binary.LittleEndian.PutUint32(h[8+4:], sideRandomNumber)
|
|
binary.LittleEndian.PutUint32(h[8+4+4:], sideExtraNonce)
|
|
copy(h[8+4+4+4:], templateId[:])
|
|
return h
|
|
}
|
|
|
|
func (id JobIdentifier) TemplateCounter() uint64 {
|
|
return binary.LittleEndian.Uint64(id[:])
|
|
}
|
|
|
|
func (id JobIdentifier) ExtraNonce() uint32 {
|
|
return binary.LittleEndian.Uint32(id[8:])
|
|
}
|
|
|
|
func (id JobIdentifier) SideRandomNumber() uint32 {
|
|
return binary.LittleEndian.Uint32(id[8+4:])
|
|
}
|
|
|
|
func (id JobIdentifier) SideExtraNonce() uint32 {
|
|
return binary.LittleEndian.Uint32(id[8+4+4:])
|
|
}
|
|
|
|
func (id JobIdentifier) TemplateId() types.Hash {
|
|
return types.HashFromBytes(id[8+4+4+4 : 8+4+4+4+types.HashSize])
|
|
}
|
|
|
|
func (id JobIdentifier) String() string {
|
|
return fasthex.EncodeToString(id[:])
|
|
}
|
|
|
|
// GetJobBlob Gets old job data based on returned id
|
|
func (e *MinerTrackingEntry) GetJobBlob(jobId JobIdentifier, nonce uint32) []byte {
|
|
e.Lock.RLock()
|
|
defer e.Lock.RUnlock()
|
|
|
|
if t, ok := e.Templates[jobId.TemplateCounter()]; ok {
|
|
buffer := bytes.NewBuffer(make([]byte, 0, len(t.Buffer)))
|
|
if err := t.Write(buffer, nonce, jobId.ExtraNonce(), jobId.SideRandomNumber(), jobId.SideExtraNonce(), jobId.TemplateId()); err != nil {
|
|
return nil
|
|
}
|
|
return buffer.Bytes()
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|