git.gammaspectra.live/P2Pool/consensus/v3@v3.8.0/p2pool/stratum/miner.go (about) 1 package stratum 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "errors" 7 "git.gammaspectra.live/P2Pool/consensus/v3/types" 8 fasthex "github.com/tmthrgd/go-hex" 9 "sync" 10 "sync/atomic" 11 "time" 12 ) 13 14 type MinerTrackingEntry struct { 15 Lock sync.RWMutex 16 Counter atomic.Uint64 17 LastTemplate atomic.Uint64 18 Templates map[uint64]*Template 19 LastJob time.Time 20 } 21 22 const JobIdentifierSize = 8 + 4 + 4 + 4 + types.HashSize 23 24 type JobIdentifier [JobIdentifierSize]byte 25 26 func JobIdentifierFromString(s string) (JobIdentifier, error) { 27 var h JobIdentifier 28 if buf, err := fasthex.DecodeString(s); err != nil { 29 return h, err 30 } else { 31 if len(buf) != JobIdentifierSize { 32 return h, errors.New("wrong job id size") 33 } 34 copy(h[:], buf) 35 return h, nil 36 } 37 } 38 func JobIdentifierFromValues(templateCounter uint64, extraNonce, sideRandomNumber, sideExtraNonce uint32, templateId types.Hash) JobIdentifier { 39 var h JobIdentifier 40 binary.LittleEndian.PutUint64(h[:], templateCounter) 41 binary.LittleEndian.PutUint32(h[8:], extraNonce) 42 binary.LittleEndian.PutUint32(h[8+4:], sideRandomNumber) 43 binary.LittleEndian.PutUint32(h[8+4+4:], sideExtraNonce) 44 copy(h[8+4+4+4:], templateId[:]) 45 return h 46 } 47 48 func (id JobIdentifier) TemplateCounter() uint64 { 49 return binary.LittleEndian.Uint64(id[:]) 50 } 51 52 func (id JobIdentifier) ExtraNonce() uint32 { 53 return binary.LittleEndian.Uint32(id[8:]) 54 } 55 56 func (id JobIdentifier) SideRandomNumber() uint32 { 57 return binary.LittleEndian.Uint32(id[8+4:]) 58 } 59 60 func (id JobIdentifier) SideExtraNonce() uint32 { 61 return binary.LittleEndian.Uint32(id[8+4+4:]) 62 } 63 64 func (id JobIdentifier) TemplateId() types.Hash { 65 return types.HashFromBytes(id[8+4+4+4 : 8+4+4+4+types.HashSize]) 66 } 67 68 func (id JobIdentifier) String() string { 69 return fasthex.EncodeToString(id[:]) 70 } 71 72 // GetJobBlob Gets old job data based on returned id 73 func (e *MinerTrackingEntry) GetJobBlob(jobId JobIdentifier, nonce uint32) []byte { 74 e.Lock.RLock() 75 defer e.Lock.RUnlock() 76 77 if t, ok := e.Templates[jobId.TemplateCounter()]; ok { 78 buffer := bytes.NewBuffer(make([]byte, 0, len(t.Buffer))) 79 if err := t.Write(buffer, nonce, jobId.ExtraNonce(), jobId.SideRandomNumber(), jobId.SideExtraNonce(), jobId.TemplateId()); err != nil { 80 return nil 81 } 82 return buffer.Bytes() 83 } else { 84 return nil 85 } 86 }