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) {
if t := s.currentBlockTemplate(); t != nil { if t := s.currentBlockTemplate(); t != nil {
stats["height"] = t.height stats["height"] = t.height
stats["diff"] = t.difficulty stats["diff"] = t.diffInt64
roundShares := atomic.LoadInt64(&s.roundShares) 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["prevHash"] = t.prevHash[0:8]
stats["template"] = true stats["template"] = true
} }

7
stratum/blocks.go

@ -5,12 +5,14 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"log" "log"
"math/big"
"github.com/sammy007/monero-stratum/cnutil" "github.com/sammy007/monero-stratum/cnutil"
) )
type BlockTemplate struct { type BlockTemplate struct {
difficulty int64 difficulty *big.Int
diffInt64 int64
height int64 height int64
reservedOffset int reservedOffset int
prevHash string prevHash string
@ -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) 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{ newTemplate := BlockTemplate{
difficulty: reply.Difficulty, diffInt64: reply.Difficulty,
difficulty: big.NewInt(reply.Difficulty),
height: reply.Height, height: reply.Height,
prevHash: reply.PrevHash, prevHash: reply.PrevHash,
reservedOffset: reply.ReservedOffset, reservedOffset: reply.ReservedOffset,

13
stratum/miner.go

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

3
stratum/stratum.go

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

9
util/util.go

@ -31,10 +31,15 @@ func GetTargetHex(diff int64) string {
return targetHex return targetHex
} }
func GetHashDifficulty(hashBytes []byte) *big.Int { func GetHashDifficulty(hashBytes []byte) (*big.Int, bool) {
diff := new(big.Int) diff := new(big.Int)
diff.SetBytes(reverse(hashBytes)) 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 { func ValidateAddress(addy string, poolAddy string) bool {

17
util/util_test.go

@ -2,7 +2,6 @@ package util
import ( import (
"encoding/hex" "encoding/hex"
"math/big"
"testing" "testing"
) )
@ -23,11 +22,19 @@ func TestGetTargetHex(t *testing.T) {
func TestGetHashDifficulty(t *testing.T) { func TestGetHashDifficulty(t *testing.T) {
hash := "8e3c1865f22801dc3df0a688da80701e2390e7838e65c142604cc00eafe34000" hash := "8e3c1865f22801dc3df0a688da80701e2390e7838e65c142604cc00eafe34000"
hashBytes, _ := hex.DecodeString(hash) hashBytes, _ := hex.DecodeString(hash)
diff := new(big.Int) shareDiff, ok := GetHashDifficulty(hashBytes)
diff.SetBytes(reverse(hashBytes))
shareDiff := GetHashDifficulty(hashBytes)
if shareDiff.String() != "1009" { if !ok && shareDiff.String() != "1009" {
t.Error("Invalid diff") 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