Skip to content

Commit

Permalink
multi: utilize a dynamic client timeout.
Browse files Browse the repository at this point in the history
This integrates a dynamic client timeout based on
the network being mined on by the pool. This also
resolves hightlighted review issues an updates
some log outputs.
  • Loading branch information
dnldd committed Feb 15, 2021
1 parent 208d643 commit f802a91
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 20 deletions.
2 changes: 1 addition & 1 deletion cmd/miner/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (m *Miner) keepAlive(ctx context.Context) {
m.encoder = json.NewEncoder(m.conn)
m.reader = bufio.NewReader(m.conn)

log.Debugf("miner connected to %s", m.config.Pool)
log.Tracef("miner connected to %s", m.config.Pool)

m.connectedMtx.Lock()
m.connected = true
Expand Down
2 changes: 1 addition & 1 deletion cmd/miner/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ func loadConfig() (*config, []string, error) {
// done. This prevents the warning on help messages and invalid
// options. Note this should go directly before the return.
if configFileError != nil {
log.Debugf("%v", configFileError)
log.Tracef("%v", configFileError)
}

return &cfg, remainingArgs, nil
Expand Down
10 changes: 10 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ type config struct {
poolFeeAddrs []dcrutil.Address
dcrdRPCCerts []byte
net *params
clientTimeout time.Duration
}

// serviceOptions defines the configuration options for the daemon as a service on
Expand Down Expand Up @@ -858,5 +859,14 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err
}

// Define the client timeout to be approximately four block times
// per the active network, except for simnet.
switch cfg.ActiveNet {
case chaincfg.TestNet3Params().Name, chaincfg.MainNetParams().Name:
cfg.clientTimeout = cfg.net.TargetTimePerBlock * 4
default:
cfg.clientTimeout = time.Second * 30
}

return &cfg, remainingArgs, nil
}
1 change: 1 addition & 0 deletions dcrpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func newPool(db pool.Database, cfg *config) (*miningPool, error) {
CoinbaseConfTimeout: cfg.CoinbaseConfTimeout,
MonitorCycle: cfg.MonitorCycle,
MaxUpgradeTries: cfg.MaxUpgradeTries,
ClientTimeout: cfg.clientTimeout,
}

var err error
Expand Down
5 changes: 3 additions & 2 deletions pool/chainstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,9 @@ func (cs *ChainState) handleChainUpdates(ctx context.Context) {
cs.cfg.Cancel()
continue
}
log.Infof("Mined work %s confirmed by connected block #%d",
header.PrevBlock.String(), header.Height)
log.Infof("Mined work %s confirmed by connected block #%d (%s)",
header.PrevBlock.String(), header.Height,
header.BlockHash().String())

// Signal the gui cache of the confirmed mined work.
cs.cfg.SignalCache(Confirmed)
Expand Down
32 changes: 18 additions & 14 deletions pool/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ const (
// client's hash rate is calculated.
hashCalcThreshold = time.Second * 20

// clientTimeout represents the read/write timeout for the client. This is
// currently set to approximately four block times.
clientTimeout = time.Minute * 20

// rollWorkCycle represents the tick interval for asserting the need for
// timestamp-rolled work.
rollWorkCycle = time.Second
Expand Down Expand Up @@ -552,7 +548,7 @@ func (c *Client) handleSubmitWorkRequest(ctx context.Context, req *Request, allo
sErr := NewStratumError(Unknown, err)
resp := SubmitWorkResponse(*req.ID, false, sErr)
c.ch <- resp
return errs.PoolError(errs.Difficulty, err.Error())
return errs.PoolError(errs.LowDifficulty, err.Error())
}
hash := header.BlockHash()
hashTarget := new(big.Rat).SetInt(standalone.HashToBig(&hash))
Expand All @@ -565,12 +561,12 @@ func (c *Client) handleSubmitWorkRequest(ctx context.Context, req *Request, allo
// Only submit work to the network if the submitted blockhash is
// less than the pool target for the client.
if hashTarget.Cmp(tgt) > 0 {
err := fmt.Errorf("submitted work from %s is not less than its "+
"corresponding pool target", id)
err := fmt.Errorf("submitted work %s from %s is not less than its "+
"corresponding pool target", hash.String(), id)
sErr := NewStratumError(LowDifficultyShare, err)
resp := SubmitWorkResponse(*req.ID, false, sErr)
c.ch <- resp
return errs.PoolError(errs.Difficulty, err.Error())
return errs.PoolError(errs.PoolDifficulty, err.Error())
}
atomic.AddInt64(&c.submissions, 1)

Expand Down Expand Up @@ -598,9 +594,9 @@ func (c *Client) handleSubmitWorkRequest(ctx context.Context, req *Request, allo
resp := SubmitWorkResponse(*req.ID, true, nil)
c.ch <- resp

desc := fmt.Sprintf("submitted work from %s is not "+
"less than the network target difficulty", id)
return errs.PoolError(errs.Difficulty, desc)
desc := fmt.Sprintf("submitted work %s from %s is not "+
"less than the network target difficulty", hash.String(), id)
return errs.PoolError(errs.NetworkDifficulty, desc)
}

// Generate and send the work submission.
Expand Down Expand Up @@ -747,10 +743,10 @@ func (c *Client) read() {
}

// updateWork updates a client with a timestamp-rolled current work with the
// provided work prioritization. This should be called after a client
// provided clean job status. This should be called after a client
// completes a work submission,after client authentication and when the
// client is stalling on current work.
func (c *Client) updateWork(prioritize bool) {
func (c *Client) updateWork(cleanJob bool) {
const funcName = "updateWork"
// Only timestamp-roll current work for authorized and subscribed clients.
c.statusMtx.RLock()
Expand Down Expand Up @@ -799,7 +795,7 @@ func (c *Client) updateWork(prioritize bool) {
return
}
workNotif := WorkNotification(job.UUID, prevBlock, genTx1, genTx2,
blockVersion, nBits, nTime, prioritize)
blockVersion, nBits, nTime, cleanJob)
select {
case c.ch <- workNotif:
c.mtx.RLock()
Expand Down Expand Up @@ -864,10 +860,18 @@ func (c *Client) process() {

case Submit:
err := c.handleSubmitWorkRequest(c.ctx, req, allowed)
if errors.Is(err, errs.NetworkDifficulty) {
// Submissions less than the network difficulty should
// not be treated as errors.
log.Trace(err)
continue
}

if err != nil {
log.Error(err)
continue
}

if allowed {
c.updateWork(true)
}
Expand Down
6 changes: 4 additions & 2 deletions pool/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ type EndpointConfig struct {
// MaxUpgradeTries represents the maximum number of consecutive miner
// monitoring and upgrade tries.
MaxUpgradeTries uint32
// ClientTimeout represents the read/write timeout for the client.
ClientTimeout time.Duration
}

// connection wraps a client connection and a done channel.
Expand Down Expand Up @@ -172,7 +174,7 @@ func (e *Endpoint) connect(ctx context.Context) {
WithinLimit: e.cfg.WithinLimit,
HashCalcThreshold: hashCalcThreshold,
MaxGenTime: e.cfg.MaxGenTime,
ClientTimeout: clientTimeout,
ClientTimeout: e.cfg.ClientTimeout,
SignalCache: e.cfg.SignalCache,
MonitorCycle: e.cfg.MonitorCycle,
MaxUpgradeTries: e.cfg.MaxUpgradeTries,
Expand All @@ -192,7 +194,7 @@ func (e *Endpoint) connect(ctx context.Context) {
e.wg.Add(1)
go client.run()

log.Debugf("Mining client connected. extranonce1=%s, addr=%s",
log.Tracef("Mining client connected. extranonce1=%s, addr=%s",
client.extraNonce1, client.addr)

close(msg.Done)
Expand Down
1 change: 1 addition & 0 deletions pool/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func testEndpoint(t *testing.T) {
},
MonitorCycle: time.Minute,
MaxUpgradeTries: 5,
ClientTimeout: time.Second * 30,
}
endpoint, err := NewEndpoint(eCfg, "0.0.0.0:3030")
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions pool/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ type HubConfig struct {
// MaxUpgradeTries represents the maximum number of consecutive miner
// monitoring and upgrade tries.
MaxUpgradeTries uint32
// ClientTimeout represents the read/write timeout for the client.
ClientTimeout time.Duration
}

// Hub maintains the set of active clients and facilitates message broadcasting
Expand Down Expand Up @@ -327,6 +329,7 @@ func NewHub(cancel context.CancelFunc, hcfg *HubConfig) (*Hub, error) {
SignalCache: h.SignalCache,
MonitorCycle: h.cfg.MonitorCycle,
MaxUpgradeTries: h.cfg.MaxUpgradeTries,
ClientTimeout: h.cfg.ClientTimeout,
}

h.endpoint, err = NewEndpoint(eCfg, h.cfg.MinerListen)
Expand Down

0 comments on commit f802a91

Please sign in to comment.