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  }