124 lines
3.4 KiB
Go
124 lines
3.4 KiB
Go
package proxy
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"net"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
var minerIDSequence atomic.Int64
|
|
|
|
// NewMiner creates a Miner for an accepted net.Conn. Does not start reading yet.
|
|
//
|
|
// m := proxy.NewMiner(conn, 3333, nil)
|
|
func NewMiner(conn net.Conn, localPort uint16, tlsCfg *tls.Config) *Miner {
|
|
miner := &Miner{
|
|
id: minerIDSequence.Add(1),
|
|
state: MinerStateWaitLogin,
|
|
localPort: localPort,
|
|
mapperID: -1,
|
|
routeID: -1,
|
|
conn: conn,
|
|
connectedAt: time.Now().UTC(),
|
|
lastActivityAt: time.Now().UTC(),
|
|
}
|
|
|
|
if tlsCfg != nil {
|
|
if tlsConnection, ok := conn.(*tls.Conn); ok {
|
|
miner.tlsConn = tlsConnection
|
|
}
|
|
}
|
|
|
|
if conn != nil && conn.RemoteAddr() != nil {
|
|
miner.ip = remoteHost(conn.RemoteAddr().String())
|
|
}
|
|
|
|
return miner
|
|
}
|
|
|
|
func (m *Miner) ID() int64 { return m.id }
|
|
func (m *Miner) RPCID() string { return m.rpcID }
|
|
func (m *Miner) User() string { return m.user }
|
|
func (m *Miner) Password() string { return m.password }
|
|
func (m *Miner) Agent() string { return m.agent }
|
|
func (m *Miner) RigID() string { return m.rigID }
|
|
func (m *Miner) IP() string { return m.ip }
|
|
func (m *Miner) State() MinerState {
|
|
if m == nil {
|
|
return MinerStateClosing
|
|
}
|
|
|
|
m.stateMu.RLock()
|
|
state := m.state
|
|
m.stateMu.RUnlock()
|
|
return state
|
|
}
|
|
func (m *Miner) Diff() uint64 { return m.diff }
|
|
func (m *Miner) FixedByte() uint8 { return m.fixedByte }
|
|
func (m *Miner) MapperID() int64 { return m.mapperID }
|
|
func (m *Miner) RouteID() int64 { return m.routeID }
|
|
func (m *Miner) CustomDiff() uint64 { return m.customDiff }
|
|
func (m *Miner) TX() uint64 { return m.tx }
|
|
func (m *Miner) RX() uint64 { return m.rx }
|
|
func (m *Miner) LastActivityAt() time.Time { return m.lastActivityAt }
|
|
|
|
func (m *Miner) SetRPCID(value string) { m.rpcID = value }
|
|
func (m *Miner) SetUser(value string) { m.user = value }
|
|
func (m *Miner) SetPassword(value string) { m.password = value }
|
|
func (m *Miner) SetAgent(value string) { m.agent = value }
|
|
func (m *Miner) SetRigID(value string) { m.rigID = value }
|
|
func (m *Miner) SetState(value MinerState) {
|
|
if m == nil {
|
|
return
|
|
}
|
|
|
|
m.stateMu.Lock()
|
|
m.state = value
|
|
m.stateMu.Unlock()
|
|
}
|
|
func (m *Miner) SetDiff(value uint64) { m.diff = value }
|
|
func (m *Miner) SetFixedByte(value uint8) { m.fixedByte = value }
|
|
func (m *Miner) SetMapperID(value int64) { m.mapperID = value }
|
|
func (m *Miner) SetRouteID(value int64) { m.routeID = value }
|
|
func (m *Miner) SetCustomDiff(value uint64) { m.customDiff = value }
|
|
func (m *Miner) SetNiceHashEnabled(value bool) { m.extNH = value }
|
|
|
|
func (m *Miner) PrimeJob(job Job) {
|
|
if m == nil || !job.IsValid() {
|
|
return
|
|
}
|
|
m.currentJob = &job
|
|
m.diff = m.effectiveDifficulty(job)
|
|
}
|
|
|
|
func (m *Miner) Touch() {
|
|
m.lastActivityAt = time.Now().UTC()
|
|
}
|
|
|
|
func remoteHost(address string) string {
|
|
host, _, errorValue := net.SplitHostPort(address)
|
|
if errorValue != nil {
|
|
return address
|
|
}
|
|
return host
|
|
}
|
|
|
|
func (m *Miner) effectiveDifficulty(job Job) uint64 {
|
|
difficulty := job.DifficultyFromTarget()
|
|
if m == nil || m.customDiff == 0 {
|
|
return difficulty
|
|
}
|
|
if difficulty == 0 || difficulty <= m.customDiff {
|
|
return difficulty
|
|
}
|
|
return m.customDiff
|
|
}
|
|
|
|
func (m *Miner) effectiveTarget(job Job) string {
|
|
difficulty := m.effectiveDifficulty(job)
|
|
if difficulty == 0 {
|
|
return job.Target
|
|
}
|
|
return TargetForDifficulty(difficulty)
|
|
}
|