Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
feat: option to disable the interactive console (#22)
Browse files Browse the repository at this point in the history
* feat: option to disable the interactive console

* feat: print summary
  • Loading branch information
jon4hz authored Aug 13, 2022
1 parent 45f7423 commit c2907fd
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 89 deletions.
19 changes: 15 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"context"
"fmt"
"io"
"log"
"os"
"os/signal"
Expand All @@ -11,6 +12,7 @@ import (
"syscall"
"time"

"github.com/chzyer/readline"
"github.com/deroproject/derohe/rpc"
"github.com/go-logr/logr"
"github.com/muesli/coral"
Expand Down Expand Up @@ -42,6 +44,7 @@ func init() {
rootCmd.Flags().BoolVarP(&cfg.Miner.Testnet, "testnet", "t", false, "use testnet")
rootCmd.Flags().StringVarP(&cfg.Miner.PoolURL, "daemon-rpc-address", "r", "pool.whalesburg.com:4300", "stratum pool url")
rootCmd.Flags().IntVarP(&cfg.Miner.Threads, "mining-threads", "m", runtime.GOMAXPROCS(0), "number of threads to use")
rootCmd.Flags().BoolVar(&cfg.Miner.NonInteractive, "non-interactive", false, "non-interactive mode")

rootCmd.Flags().BoolVar(&cfg.Logger.Debug, "debug", false, "enable debug mode")
rootCmd.Flags().Int8Var(&cfg.Logger.CLogLevel, "console-log-level", 0, "console log level")
Expand Down Expand Up @@ -94,9 +97,17 @@ func rootHandler(cmd *coral.Command, args []string) error {
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

cli, err := console.New()
if err != nil {
log.Fatalln("failed to create console:", err)
var (
cli *readline.Instance
out io.Writer = os.Stdout
)
if !cfg.Miner.NonInteractive {
var err error
cli, err = console.New()
if err != nil {
log.Fatalln("failed to create console:", err)
}
out = cli.Stdout()
}

exename, err := os.Executable()
Expand All @@ -107,7 +118,7 @@ func rootHandler(cmd *coral.Command, args []string) error {
if err != nil {
return fmt.Errorf("Error while opening log file err: %s filename %s", err, exename+".log")
}
logger := logging.New(cli.Stdout(), f, cfg.Logger)
logger := logging.New(out, f, cfg.Logger)

ctx, cancel := context.WithCancel(cmd.Context())
stc := newStratumClient(ctx, cfg.Miner.PoolURL, cfg.Miner.Wallet, logger)
Expand Down
9 changes: 5 additions & 4 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ type Config struct {
}

type Miner struct {
Wallet string
Testnet bool
PoolURL string
Threads int
Wallet string
Testnet bool
PoolURL string
Threads int
NonInteractive bool
}

type Logger struct {
Expand Down
75 changes: 3 additions & 72 deletions internal/dero-stratum-miner/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import (
"runtime"
"strconv"
"strings"
"time"

"github.com/chzyer/readline"
"github.com/jon4hz/hashconv"
"github.com/whalesburg/dero-stratum-miner/internal/version"
)

Expand Down Expand Up @@ -75,77 +73,10 @@ func (c *Client) startConsole() {
}
}

func (c *Client) refreshConsole() {
lastCounter := uint64(0)
lastCounterTime := time.Now()

var (
lastUpdate = time.Now()
mining bool

miningString string
heightString string
diffString string
)

for {
select {
case <-c.ctx.Done():
return
default:
}

// we assume that the miner stopped if the conolse wasn't updated within the last five seconds.
if time.Since(lastUpdate) > time.Second*5 {
if mining {
miningString = "\033[31mNot Mining"
testnetString := ""
if c.config.Testnet {
testnetString = "\033[31m Testnet"
}
c.setPrompt(heightString, diffString, miningString, testnetString)
mining = false
}
} else {
mining = true
}

// only update prompt if needed
if lastCounter != c.counter {
if mining {
heightString = fmt.Sprintf("\033[33mHeight %.0f", c.job.Height)

switch {
case c.job.Difficulty > 1000000000:
diffString = fmt.Sprintf("\033[32mDiff %.1fG", float32(c.job.Difficulty)/1000000000.0)
case c.job.Difficulty > 1000000:
diffString = fmt.Sprintf("\033[32mDiff %.1fM", float32(c.job.Difficulty)/1000000.0)
case c.job.Difficulty > 1000:
diffString = fmt.Sprintf("\033[32mDiff %.1fK", float32(c.job.Difficulty)/1000.0)
case c.job.Difficulty > 0:
diffString = fmt.Sprintf("\033[32mDiff %d", c.job.Difficulty)
}

miningSpeed := float64(c.counter-lastCounter) / (float64(uint64(time.Since(lastCounterTime))) / 1000000000.0)
c.hashrate = uint64(miningSpeed)
lastCounter = c.counter
lastCounterTime = time.Now()
miningString = fmt.Sprintf("Mining @ %s/s", hashconv.Format(int64(miningSpeed)))
}

testnetString := ""
if c.config.Testnet {
testnetString = "\033[31m Testnet"
}

c.setPrompt(heightString, diffString, miningString, testnetString)
lastUpdate = time.Now()
}
time.Sleep(1 * time.Second)
}
}

func (c *Client) setPrompt(heightString, diffString, miningString, testnetString string) {
if c.console == nil {
return
}
c.console.SetPrompt(fmt.Sprintf("\033[1m\033[32mDero-Stratum-Miner: \033[0m%s %s \033[33mShares %d Rejected %d \033[32m%s>%s>>\033[0m ", heightString, diffString, c.GetTotalShares(), c.GetRejectedShares(), miningString, testnetString))
c.console.Refresh()
}
30 changes: 21 additions & 9 deletions internal/dero-stratum-miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ type Client struct {
console *readline.Instance
logger logr.Logger

mu sync.RWMutex
job *stratum.Job
jobCounter int64
iterations int
hashrate uint64
mu sync.RWMutex
job *stratum.Job
jobCounter int64
iterations int
hashrate uint64
mining bool
miningString string
diffString string
heightString string

shareCounter uint64
rejectedCounter uint64
Expand All @@ -59,7 +63,10 @@ func New(ctx context.Context, cancel context.CancelFunc, config *config.Miner, s
}

func (c *Client) Close() error {
return c.console.Close()
if c.console != nil {
return c.console.Close()
}
return nil
}

func (c *Client) Start() error {
Expand All @@ -71,7 +78,11 @@ func (c *Client) Start() error {
c.config.Threads = 255
}

go c.refreshConsole()
go c.gatherStats()
if c.config.NonInteractive {
go c.noniSummary()
}

go c.getwork()

for i := 0; i < c.config.Threads; i++ {
Expand All @@ -80,8 +91,9 @@ func (c *Client) Start() error {

go c.reportHashrate()

// this method will block until the context is canceled
c.startConsole()
if !c.config.NonInteractive {
c.startConsole()
}
return nil
}

Expand Down
102 changes: 102 additions & 0 deletions internal/dero-stratum-miner/stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package miner

import (
"fmt"
"time"

"github.com/jon4hz/hashconv"
)

func (c *Client) gatherStats() {
var (
lastCounter = uint64(0)
lastCounterTime = time.Now()
lastUpdate = time.Now()
miningString string
diffString string
heightString string
)

for {
select {
case <-c.ctx.Done():
return
default:
}

// we assume that the miner stopped if the conolse wasn't updated within the last five seconds.
if time.Since(lastUpdate) > time.Second*5 {
if c.mining {
miningString = "\033[31mNot Mining"
testnetString := ""
if c.config.Testnet {
testnetString = "\033[31m Testnet"
}
c.setPrompt(heightString, diffString, miningString, testnetString)
c.mining = false
}
} else {
c.mining = true
}

// only update prompt if needed
if lastCounter != c.counter {
if c.mining {
c.heightString = fmt.Sprintf("%.0f", c.job.Height)
heightString = fmt.Sprintf("\033[33mHeight %s", c.heightString)

switch {
case c.job.Difficulty > 1_000_000_000:
c.diffString = fmt.Sprintf("%.1fG", float32(c.job.Difficulty)/1_000_000_000.0)
diffString = fmt.Sprintf("\033[32mDiff %s", c.diffString)
case c.job.Difficulty > 1_000_000:
c.diffString = fmt.Sprintf("%.1fM", float32(c.job.Difficulty)/1_000_000.0)
diffString = fmt.Sprintf("\033[32mDiff %s", c.diffString)
case c.job.Difficulty > 1000:
c.diffString = fmt.Sprintf("%.1fK", float32(c.job.Difficulty)/1000.0)
diffString = fmt.Sprintf("\033[32mDiff %s", c.diffString)
case c.job.Difficulty > 0:
c.diffString = fmt.Sprintf("%d", c.job.Difficulty)
diffString = fmt.Sprintf("\033[32mDiff %s", c.diffString)
}

miningSpeed := float64(c.counter-lastCounter) / (float64(uint64(time.Since(lastCounterTime))) / 1_000_000_000.0)
c.hashrate = uint64(miningSpeed)
lastCounter = c.counter
lastCounterTime = time.Now()
c.miningString = fmt.Sprintf("%s/s", hashconv.Format(int64(miningSpeed)))
miningString = fmt.Sprintf("Mining @ %s", c.miningString)
}

testnetString := ""
if c.config.Testnet {
testnetString = "\033[31m Testnet"
}

c.setPrompt(heightString, diffString, miningString, testnetString)
lastUpdate = time.Now()
}
time.Sleep(1 * time.Second)
}
}
func (c *Client) noniSummary() {
ticker := time.NewTicker(time.Second * 30)
for {
select {
case <-ticker.C:
c.printSummary()
case <-c.ctx.Done():
return
}
}
}

func (c *Client) printSummary() {
c.logger.Info("Summary",
"height", c.heightString,
"diff", c.diffString,
"accepted", c.GetAcceptedShares(),
"rejected", c.GetRejectedShares(),
"hashrate", c.miningString,
)
}

0 comments on commit c2907fd

Please sign in to comment.