|
|
|
@ -50,17 +50,16 @@ type Session struct { |
|
|
|
|
|
|
|
|
|
|
|
// Stratum
|
|
|
|
// Stratum
|
|
|
|
sync.Mutex |
|
|
|
sync.Mutex |
|
|
|
conn net.Conn |
|
|
|
conn net.Conn |
|
|
|
login string |
|
|
|
login string |
|
|
|
worker string |
|
|
|
worker string |
|
|
|
stratum int |
|
|
|
stratum int |
|
|
|
subscriptionID string |
|
|
|
JobDeatils jobDetails |
|
|
|
JobDeatils jobDetails |
|
|
|
Extranonce string |
|
|
|
Extranonce string |
|
|
|
ExtranonceSub bool |
|
|
|
ExtranonceSub bool |
|
|
|
JobDetails jobDetails |
|
|
|
JobDetails jobDetails |
|
|
|
staleJobs map[string]staleJob |
|
|
|
staleJobs map[string]staleJob |
|
|
|
staleJobIDs []string |
|
|
|
staleJobIDs []string |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type jobDetails struct { |
|
|
|
type jobDetails struct { |
|
|
|
@ -73,7 +72,7 @@ type jobDetails struct { |
|
|
|
|
|
|
|
|
|
|
|
func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer { |
|
|
|
func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer { |
|
|
|
if len(cfg.Name) == 0 { |
|
|
|
if len(cfg.Name) == 0 { |
|
|
|
log.Fatal("You must set instance name") |
|
|
|
log.Fatal("You must set the instance name") |
|
|
|
} |
|
|
|
} |
|
|
|
policy := policy.Start(&cfg.Proxy.Policy, backend) |
|
|
|
policy := policy.Start(&cfg.Proxy.Policy, backend) |
|
|
|
|
|
|
|
|
|
|
|
@ -108,61 +107,49 @@ func NewProxy(cfg *Config, backend *storage.RedisClient) *ProxyServer { |
|
|
|
stateUpdateTimer := time.NewTimer(stateUpdateIntv) |
|
|
|
stateUpdateTimer := time.NewTimer(stateUpdateIntv) |
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
for { |
|
|
|
for range refreshTimer.C { |
|
|
|
select { |
|
|
|
proxy.fetchBlockTemplate() |
|
|
|
case <-refreshTimer.C: |
|
|
|
|
|
|
|
proxy.fetchBlockTemplate() |
|
|
|
|
|
|
|
refreshTimer.Reset(refreshIntv) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
for { |
|
|
|
for range checkTimer.C { |
|
|
|
select { |
|
|
|
proxy.checkUpstreams() |
|
|
|
case <-checkTimer.C: |
|
|
|
|
|
|
|
proxy.checkUpstreams() |
|
|
|
|
|
|
|
checkTimer.Reset(checkIntv) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}() |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
go func() { |
|
|
|
for { |
|
|
|
for range stateUpdateTimer.C { |
|
|
|
select { |
|
|
|
t := proxy.currentBlockTemplate() |
|
|
|
case <-stateUpdateTimer.C: |
|
|
|
if t != nil { |
|
|
|
t := proxy.currentBlockTemplate() |
|
|
|
rpc := proxy.rpc() |
|
|
|
if t != nil { |
|
|
|
// get the latest block height
|
|
|
|
rpc := proxy.rpc() |
|
|
|
height := int64(t.Height) - 1 |
|
|
|
// get the latest block height
|
|
|
|
block, _ := rpc.GetBlockByHeight(height) |
|
|
|
height := int64(t.Height) - 1 |
|
|
|
timestamp, _ := strconv.ParseInt(strings.Replace(block.Timestamp, "0x", "", -1), 16, 64) |
|
|
|
block, _ := rpc.GetBlockByHeight(height) |
|
|
|
prev := height - 100 |
|
|
|
timestamp, _ := strconv.ParseInt(strings.Replace(block.Timestamp, "0x", "", -1), 16, 64) |
|
|
|
if prev < 0 { |
|
|
|
prev := height - 100 |
|
|
|
prev = 0 |
|
|
|
if prev < 0 { |
|
|
|
} |
|
|
|
prev = 0 |
|
|
|
n := height - prev |
|
|
|
} |
|
|
|
if n > 0 { |
|
|
|
n := height - prev |
|
|
|
prevblock, err := rpc.GetBlockByHeight(prev) |
|
|
|
if n > 0 { |
|
|
|
if err != nil || prevblock == nil { |
|
|
|
prevblock, err := rpc.GetBlockByHeight(prev) |
|
|
|
log.Fatalf("Error while retrieving block from the node: %v", err) |
|
|
|
if err != nil || prevblock == nil { |
|
|
|
} else { |
|
|
|
log.Fatalf("Error while retrieving block from node: %v", err) |
|
|
|
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 { |
|
|
|
|
|
|
|
log.Printf("Failed to write node state to the backend: %v", err) |
|
|
|
|
|
|
|
proxy.markSick() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
prevtime, _ := strconv.ParseInt(strings.Replace(prevblock.Timestamp, "0x", "", -1), 16, 64) |
|
|
|
proxy.markOk() |
|
|
|
blocktime := float64(timestamp-prevtime) / float64(n) |
|
|
|
|
|
|
|
err = backend.WriteNodeState(cfg.Name, t.Height, t.Difficulty, blocktime) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
log.Printf("Failed to write node state to backend: %v", err) |
|
|
|
|
|
|
|
proxy.markSick() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
proxy.markOk() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
|
|
|
|
proxy.markSick() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
proxy.markSick() |
|
|
|
} |
|
|
|
} |
|
|
|
stateUpdateTimer.Reset(stateUpdateIntv) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}() |
|
|
|
}() |
|
|
|
|