Browse Source

Fix difficulty comparison

pool
Sammy Libre 7 years ago
parent
commit
9a9d2cc5d4
  1. 4
      stratum/api.go
  2. 7
      stratum/blocks.go
  3. 13
      stratum/miner.go
  4. 3
      stratum/stratum.go
  5. 9
      util/util.go
  6. 17
      util/util_test.go

4
stratum/api.go

@ -40,9 +40,9 @@ func (s *StratumServer) StatsIndex(w http.ResponseWriter, r *http.Request) { @@ -40,9 +40,9 @@ func (s *StratumServer) StatsIndex(w http.ResponseWriter, r *http.Request) {
if t := s.currentBlockTemplate(); t != nil {
stats["height"] = t.height
stats["diff"] = t.difficulty
stats["diff"] = t.diffInt64
roundShares := atomic.LoadInt64(&s.roundShares)
stats["variance"] = float64(roundShares) / float64(t.difficulty)
stats["variance"] = float64(roundShares) / float64(t.diffInt64)
stats["prevHash"] = t.prevHash[0:8]
stats["template"] = true
}

7
stratum/blocks.go

@ -5,12 +5,14 @@ import ( @@ -5,12 +5,14 @@ import (
"encoding/binary"
"encoding/hex"
"log"
"math/big"
"github.com/sammy007/monero-stratum/cnutil"
)
type BlockTemplate struct {
difficulty int64
difficulty *big.Int
diffInt64 int64
height int64
reservedOffset int
prevHash string
@ -49,7 +51,8 @@ func (s *StratumServer) fetchBlockTemplate() bool { @@ -49,7 +51,8 @@ func (s *StratumServer) fetchBlockTemplate() bool {
log.Printf("New block to mine on %s at height %v, diff: %v, prev_hash: %s", r.Name, reply.Height, reply.Difficulty, reply.PrevHash)
}
newTemplate := BlockTemplate{
difficulty: reply.Difficulty,
diffInt64: reply.Difficulty,
difficulty: big.NewInt(reply.Difficulty),
height: reply.Height,
prevHash: reply.PrevHash,
reservedOffset: reply.ReservedOffset,

13
stratum/miner.go

@ -161,8 +161,13 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe @@ -161,8 +161,13 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe
return false
}
hashDiff := util.GetHashDifficulty(hashBytes).Int64() // FIXME: Will return max int64 value if overflows
block := hashDiff >= t.difficulty
hashDiff, ok := util.GetHashDifficulty(hashBytes) // FIXME: Will return max int64 value if overflows
if !ok {
log.Printf("Bad hash from miner %v@%v", m.id, cs.ip)
atomic.AddInt64(&m.invalidShares, 1)
return false
}
block := hashDiff.Cmp(t.difficulty) >= 0
if block {
_, err := r.SubmitBlock(hex.EncodeToString(shareBuff))
@ -177,7 +182,7 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe @@ -177,7 +182,7 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe
blockFastHash := hex.EncodeToString(hashing.FastHash(convertedBlob))
now := util.MakeTimestamp()
roundShares := atomic.SwapInt64(&s.roundShares, 0)
ratio := float64(roundShares) / float64(t.difficulty)
ratio := float64(roundShares) / float64(t.diffInt64)
s.blocksMu.Lock()
s.blockStats[now] = blockEntry{height: t.height, hash: blockFastHash, variance: ratio}
s.blocksMu.Unlock()
@ -189,7 +194,7 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe @@ -189,7 +194,7 @@ func (m *Miner) processShare(s *StratumServer, cs *Session, job *Job, t *BlockTe
// Immediately refresh current BT and send new jobs
s.refreshBlockTemplate(true)
}
} else if hashDiff < cs.endpoint.config.Difficulty {
} else if hashDiff.Cmp(cs.endpoint.difficulty) < 0 {
log.Printf("Rejected low difficulty share of %v from %v@%v", hashDiff, m.id, cs.ip)
atomic.AddInt64(&m.invalidShares, 1)
return false

3
stratum/stratum.go

@ -7,6 +7,7 @@ import ( @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"log"
"math/big"
"net"
"sync"
"sync/atomic"
@ -42,6 +43,7 @@ type blockEntry struct { @@ -42,6 +43,7 @@ type blockEntry struct {
type Endpoint struct {
config *pool.Port
difficulty *big.Int
instanceId []byte
extraNonce uint32
targetHex string
@ -132,6 +134,7 @@ func NewEndpoint(cfg *pool.Port) *Endpoint { @@ -132,6 +134,7 @@ func NewEndpoint(cfg *pool.Port) *Endpoint {
log.Fatalf("Can't seed with random bytes: %v", err)
}
e.targetHex = util.GetTargetHex(e.config.Difficulty)
e.difficulty = big.NewInt(e.config.Difficulty)
return e
}

9
util/util.go

@ -31,10 +31,15 @@ func GetTargetHex(diff int64) string { @@ -31,10 +31,15 @@ func GetTargetHex(diff int64) string {
return targetHex
}
func GetHashDifficulty(hashBytes []byte) *big.Int {
func GetHashDifficulty(hashBytes []byte) (*big.Int, bool) {
diff := new(big.Int)
diff.SetBytes(reverse(hashBytes))
return diff.Div(Diff1, diff)
// Check for broken result, empty string or zero hex value
if diff.Cmp(new(big.Int)) == 0 {
return nil, false
}
return diff.Div(Diff1, diff), true
}
func ValidateAddress(addy string, poolAddy string) bool {

17
util/util_test.go

@ -2,7 +2,6 @@ package util @@ -2,7 +2,6 @@ package util
import (
"encoding/hex"
"math/big"
"testing"
)
@ -23,11 +22,19 @@ func TestGetTargetHex(t *testing.T) { @@ -23,11 +22,19 @@ func TestGetTargetHex(t *testing.T) {
func TestGetHashDifficulty(t *testing.T) {
hash := "8e3c1865f22801dc3df0a688da80701e2390e7838e65c142604cc00eafe34000"
hashBytes, _ := hex.DecodeString(hash)
diff := new(big.Int)
diff.SetBytes(reverse(hashBytes))
shareDiff := GetHashDifficulty(hashBytes)
shareDiff, ok := GetHashDifficulty(hashBytes)
if shareDiff.String() != "1009" {
if !ok && shareDiff.String() != "1009" {
t.Error("Invalid diff")
}
}
func TestGetHashDifficultyWothBrokenHash(t *testing.T) {
hash := ""
hashBytes, _ := hex.DecodeString(hash)
shareDiff, ok := GetHashDifficulty(hashBytes)
if ok || shareDiff != nil {
t.Error("Must be no result and not ok")
}
}

Loading…
Cancel
Save