Browse Source

update

master
yuriy0803 3 years ago
parent
commit
ae1acb3512
  1. 15
      proxy/handlers.go
  2. 25
      proxy/proxy.go
  3. 2
      proxy/stratum.go
  4. 1
      rpc/rpc.go
  5. 3
      storage/redis.go
  6. 15
      www/app/controllers/application.js

15
proxy/handlers.go

@ -1,7 +1,6 @@
package proxy package proxy
import ( import (
"errors"
"log" "log"
"regexp" "regexp"
"strings" "strings"
@ -69,36 +68,30 @@ func (s *ProxyServer) handleSubmitRPC(cs *Session, login, id string, params []st
log.Printf("Malformed PoW result from %s@%s %v", login, cs.ip, params) log.Printf("Malformed PoW result from %s@%s %v", login, cs.ip, params)
return false, &ErrorReply{Code: -1, Message: "Malformed PoW result"} return false, &ErrorReply{Code: -1, Message: "Malformed PoW result"}
} }
go func(s *ProxyServer, cs *Session, login, id string, params []string) {
t := s.currentBlockTemplate() t := s.currentBlockTemplate()
exist, validShare := s.processShare(login, id, cs.ip, t, params) exist, validShare := s.processShare(login, id, cs.ip, t, params)
ok := s.policy.ApplySharePolicy(cs.ip, !exist && validShare) ok := s.policy.ApplySharePolicy(cs.ip, !exist && validShare)
if exist { if exist {
log.Printf("Duplicate share from %s@%s %v", login, cs.ip, params) log.Printf("Duplicate share from %s@%s %v", login, cs.ip, params)
cs.lastErr = errors.New("Duplicate share") return false, &ErrorReply{Code: 22, Message: "Duplicate share"}
} }
if !validShare { if !validShare {
log.Printf("Invalid share from %s@%s", login, cs.ip) log.Printf("Invalid share from %s@%s", login, cs.ip)
// Bad shares limit reached, return error and close // Bad shares limit reached, return error and close
if !ok { if !ok {
cs.lastErr = errors.New("Invalid share") return false, &ErrorReply{Code: 23, Message: "Invalid share"}
} }
return false, nil
} }
if s.config.Proxy.Debug {
log.Printf("Valid share from %s@%s", login, cs.ip) log.Printf("Valid share from %s@%s", login, cs.ip)
}
if !ok { if !ok {
cs.lastErr = errors.New("High rate of invalid shares") return true, &ErrorReply{Code: -1, Message: "High rate of invalid shares"}
} }
}(s, cs, login, id, params)
return true, nil return true, nil
} }
func (s *ProxyServer) handleGetBlockByNumberRPC() *rpc.GetBlockReplyPart { func (s *ProxyServer) handleGetBlockByNumberRPC() *rpc.GetBlockReplyPart {
t := s.currentBlockTemplate() t := s.currentBlockTemplate()
var reply *rpc.GetBlockReplyPart var reply *rpc.GetBlockReplyPart

25
proxy/proxy.go

@ -6,6 +6,7 @@ import (
"log" "log"
"net" "net"
"net/http" "net/http"
"strconv"
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -44,7 +45,6 @@ type Session struct {
sync.Mutex sync.Mutex
conn net.Conn conn net.Conn
login string login string
lastErr error
} }
func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer { func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer {
@ -108,7 +108,24 @@ func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer {
case <-stateUpdateTimer.C: case <-stateUpdateTimer.C:
t := proxy.currentBlockTemplate() t := proxy.currentBlockTemplate()
if t != nil { if t != nil {
err := backend.WriteNodeState(cfg.Name, t.Height, t.Difficulty) rpc := proxy.rpc()
// get the latest block height
height := int64(t.Height) - 1
block, _ := rpc.GetBlockByHeight(height)
timestamp, _ := strconv.ParseInt(strings.Replace(block.Timestamp, "0x", "", -1), 16, 64)
prev := height - 100
if prev < 0 {
prev = 0
}
n := height - prev
if n > 0 {
prevblock, err := rpc.GetBlockByHeight(prev)
if err != nil || prevblock == nil {
log.Fatalf("Error while retrieving block from node: %v", err)
} else {
prevtime, _ := strconv.ParseInt(strings.Replace(prevblock.Timestamp, "0x", "", -1), 16, 64)
blocktime := float64(timestamp-prevtime) / float64(n)
err = backend.WriteNodeState(cfg.Name, t.Height, t.Difficulty, blocktime)
if err != nil { if err != nil {
log.Printf("Failed to write node state to backend: %v", err) log.Printf("Failed to write node state to backend: %v", err)
proxy.markSick() proxy.markSick()
@ -116,6 +133,10 @@ func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer {
proxy.markOk() proxy.markOk()
} }
} }
} else {
proxy.markSick()
}
}
stateUpdateTimer.Reset(stateUpdateIntv) stateUpdateTimer.Reset(stateUpdateIntv)
} }
} }

2
proxy/stratum.go

@ -66,7 +66,7 @@ func (s *ProxyServer) ListenTCP() {
accept <- n accept <- n
go func(cs *Session) { go func(cs *Session) {
err = s.handleTCPClient(cs) err = s.handleTCPClient(cs)
if err != nil || cs.lastErr != nil { if err != nil {
s.removeSession(cs) s.removeSession(cs)
conn.Close() conn.Close()
} }

1
rpc/rpc.go

@ -35,6 +35,7 @@ type GetBlockReply struct {
Difficulty string `json:"difficulty"` Difficulty string `json:"difficulty"`
GasLimit string `json:"gasLimit"` GasLimit string `json:"gasLimit"`
GasUsed string `json:"gasUsed"` GasUsed string `json:"gasUsed"`
Timestamp string `json:"timestamp"`
Transactions []Tx `json:"transactions"` Transactions []Tx `json:"transactions"`
Uncles []string `json:"uncles"` Uncles []string `json:"uncles"`
// https://github.com/ethereum/EIPs/issues/95 // https://github.com/ethereum/EIPs/issues/95

3
storage/redis.go

@ -450,7 +450,7 @@ func (r *RedisClient) GetPaymentCharts(login string) (stats []*PaymentCharts, er
return stats, nil return stats, nil
} }
func (r *RedisClient) WriteNodeState(id string, height uint64, diff *big.Int) error { func (r *RedisClient) WriteNodeState(id string, height uint64, diff *big.Int, blocktime float64) error {
tx := r.client.Multi() tx := r.client.Multi()
defer tx.Close() defer tx.Close()
@ -461,6 +461,7 @@ func (r *RedisClient) WriteNodeState(id string, height uint64, diff *big.Int) er
tx.HSet(r.formatKey("nodes"), join(id, "height"), strconv.FormatUint(height, 10)) tx.HSet(r.formatKey("nodes"), join(id, "height"), strconv.FormatUint(height, 10))
tx.HSet(r.formatKey("nodes"), join(id, "difficulty"), diff.String()) tx.HSet(r.formatKey("nodes"), join(id, "difficulty"), diff.String())
tx.HSet(r.formatKey("nodes"), join(id, "lastBeat"), strconv.FormatInt(now, 10)) tx.HSet(r.formatKey("nodes"), join(id, "lastBeat"), strconv.FormatInt(now, 10))
tx.HSet(r.formatKey("nodes"), join(id, "blocktime"), strconv.FormatFloat(blocktime, 'f', 4, 64))
return nil return nil
}) })
return err return err

15
www/app/controllers/application.js

@ -44,9 +44,20 @@ export default Ember.Controller.extend({
} }
}), }),
blockTime: Ember.computed('model.nodes', {
get() {
var node = this.get('bestNode');
if (node && node.blocktime) {
return node.blocktime;
}
return config.APP.BlockTime;
}
}),
hashrate: Ember.computed('difficulty', { hashrate: Ember.computed('difficulty', {
get() { get() {
return this.getWithDefault('difficulty', 0) / config.APP.BlockTime; var blockTime = this.get('blockTime');
return this.getWithDefault('difficulty', 0) / blockTime;
} }
}), }),
@ -89,7 +100,7 @@ export default Ember.Controller.extend({
nextEpoch: Ember.computed('height', { nextEpoch: Ember.computed('height', {
get() { get() {
var epochOffset = (60000 - (this.getWithDefault('height', 1) % 60000)) * 1000 * this.get('config').BlockTime; var epochOffset = (60000 - (this.getWithDefault('height', 1) % 60000)) * 1000 * this.get('blockTime');
return Date.now() + epochOffset; return Date.now() + epochOffset;
} }
}) })

Loading…
Cancel
Save