Browse Source

Displayed error message other than 500 internal error.

master
Jianping Wu 6 years ago
parent
commit
95c758018a
  1. 9
      cnutil/cnutil.go
  2. 7
      cnutil/src/cnutil.cpp
  3. 1
      cnutil/src/cnutil.h
  4. 7
      cnutil/src/main.cc
  5. 65
      config_keva.json
  6. 65
      config_monero.json
  7. 1
      pool/pool.go
  8. 2
      rpc/rpc.go
  9. 14
      stratum/handlers.go
  10. 20
      stratum/stratum.go
  11. 16
      util/util.go

9
cnutil/cnutil.go

@ -20,6 +20,15 @@ func ConvertBlob(blob []byte) []byte {
return output return output
} }
func ValidateAddress(addr string) bool {
input := C.CString(addr)
defer C.free(unsafe.Pointer(input))
size := (C.uint32_t)(len(addr))
result := C.validate_address(input, size)
return (bool)(result)
}
func Hash(blob []byte, fast bool, height int) []byte { func Hash(blob []byte, fast bool, height int) []byte {
output := make([]byte, 32) output := make([]byte, 32)
if fast { if fast {

7
cnutil/src/cnutil.cpp

@ -18,3 +18,10 @@ extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) {
output.copy(out, output.length(), 0); output.copy(out, output.length(), 0);
return output.length(); return output.length();
} }
extern "C" bool validate_address(const char *addr, size_t len) {
std::string input = std::string(addr, len);
std::string output = "";
uint64_t prefix;
return tools::base58::decode_addr(addr, prefix, output);
}

1
cnutil/src/cnutil.h

@ -6,6 +6,7 @@ extern "C" {
#endif #endif
uint32_t convert_blob(const char *blob, uint32_t len, char *out); uint32_t convert_blob(const char *blob, uint32_t len, char *out);
bool validate_address(const char *addr, uint32_t len);
void cryptonight_hash(const char* input, char* output, uint32_t len, int height); void cryptonight_hash(const char* input, char* output, uint32_t len, int height);
void cryptonight_fast_hash(const char* input, char* output, uint32_t len); void cryptonight_fast_hash(const char* input, char* output, uint32_t len);

7
cnutil/src/main.cc

@ -26,6 +26,13 @@ extern "C" uint32_t convert_blob(const char *blob, size_t len, char *out) {
return output.length(); return output.length();
} }
extern "C" bool validate_address(const char *addr, size_t len) {
std::string input = std::string(addr, len);
std::string output = "";
uint64_t prefix;
return tools::base58::decode_addr(addr, prefix, output);
}
extern "C" void cryptonight_hash(const char* input, char* output, uint32_t len, int height) { extern "C" void cryptonight_hash(const char* input, char* output, uint32_t len, int height) {
const int variant = input[0] >= 7 ? input[0] - 6 : 0; const int variant = input[0] >= 7 ? input[0] - 6 : 0;
crypto::cn_slow_hash(input, len, output, variant, 0, height); crypto::cn_slow_hash(input, len, output, variant, 0, height);

65
config_keva.json

@ -0,0 +1,65 @@
{
"isKeva": true,
"address": "TKj7HMzeLAxd5DSoo35XuCfNH2yWC9y2Xb",
"bypassAddressValidation": false,
"bypassShareValidation": false,
"threads": 1,
"estimationWindow": "15m",
"luckWindow": "24h",
"largeLuckWindow": "72h",
"blockRefreshInterval": "1s",
"stratum": {
"timeout": "15m",
"listen": [
{
"host": "0.0.0.0",
"port": 1111,
"diff": 8000,
"maxConn": 32768
},
{
"host": "0.0.0.0",
"port": 3333,
"diff": 16000,
"maxConn": 32768
},
{
"host": "0.0.0.0",
"port": 5555,
"diff": 16000,
"maxConn": 32768
}
]
},
"frontend": {
"enabled": true,
"listen": "0.0.0.0:8082",
"login": "admin",
"password": "",
"hideIP": false
},
"upstreamCheckInterval": "5s",
"upstream": [
{
"name": "Test",
"host": "127.0.0.1",
"port": 19332,
"timeout": "300s",
"user": "yourusername",
"password": "yourpassword"
}
],
"newrelicEnabled": false,
"newrelicName": "MyStratum",
"newrelicKey": "SECRET_KEY",
"newrelicVerbose": false
}

65
config_monero.json

@ -0,0 +1,65 @@
{
"isKeva": false,
"address": "47v4BWeUPFrM9YkYRYk2pkS9CubAPEc7BJjNjg4FvF66Y2oVrTAaBjDZhmFzAXgqCNRvBH2gupQ2gNag2FkP983ZMptvUWG",
"bypassAddressValidation": false,
"bypassShareValidation": false,
"threads": 1,
"estimationWindow": "15m",
"luckWindow": "24h",
"largeLuckWindow": "72h",
"blockRefreshInterval": "1s",
"stratum": {
"timeout": "15m",
"listen": [
{
"host": "0.0.0.0",
"port": 1111,
"diff": 8000,
"maxConn": 32768
},
{
"host": "0.0.0.0",
"port": 3333,
"diff": 16000,
"maxConn": 32768
},
{
"host": "0.0.0.0",
"port": 5555,
"diff": 16000,
"maxConn": 32768
}
]
},
"frontend": {
"enabled": true,
"listen": "0.0.0.0:8082",
"login": "admin",
"password": "",
"hideIP": false
},
"upstreamCheckInterval": "5s",
"upstream": [
{
"name": "Test",
"host": "127.0.0.1",
"port": 18081,
"timeout": "300s",
"user": "yourusername",
"password": "yourpassword"
}
],
"newrelicEnabled": false,
"newrelicName": "MyStratum",
"newrelicKey": "SECRET_KEY",
"newrelicVerbose": false
}

1
pool/pool.go

@ -1,6 +1,7 @@
package pool package pool
type Config struct { type Config struct {
IsKeva bool `json:"isKeva"`
Address string `json:"address"` Address string `json:"address"`
BypassAddressValidation bool `json:"bypassAddressValidation"` BypassAddressValidation bool `json:"bypassAddressValidation"`
BypassShareValidation bool `json:"bypassShareValidation"` BypassShareValidation bool `json:"bypassShareValidation"`

2
rpc/rpc.go

@ -121,9 +121,11 @@ func (r *RPCClient) doPost(url, method string, params interface{}) (*JSONRpcResp
} }
defer resp.Body.Close() defer resp.Body.Close()
/*
if resp.StatusCode < 200 || resp.StatusCode >= 400 { if resp.StatusCode < 200 || resp.StatusCode >= 400 {
return nil, errors.New(resp.Status) return nil, errors.New(resp.Status)
} }
*/
var rpcResp *JSONRpcResp var rpcResp *JSONRpcResp
err = json.NewDecoder(resp.Body).Decode(&rpcResp) err = json.NewDecoder(resp.Body).Decode(&rpcResp)

14
stratum/handlers.go

@ -5,6 +5,8 @@ import (
"regexp" "regexp"
"strings" "strings"
"sync/atomic" "sync/atomic"
"../util"
) )
var noncePattern *regexp.Regexp var noncePattern *regexp.Regexp
@ -17,15 +19,19 @@ func init() {
func (s *StratumServer) handleLoginRPC(cs *Session, params *LoginParams) (*JobReply, *ErrorReply) { func (s *StratumServer) handleLoginRPC(cs *Session, params *LoginParams) (*JobReply, *ErrorReply) {
_, id := extractWorkerId(params.Login) address, id := extractWorkerId(params.Login)
/*
r := s.rpc() r := s.rpc()
if !s.config.BypassAddressValidation && !util.ValidateAddress(r, address, false) { if !s.config.BypassAddressValidation {
if s.config.IsKeva && !util.ValidateAddress_Keva(r, address, false) {
log.Printf("Invalid address %s used for login by %s", address, cs.ip) log.Printf("Invalid address %s used for login by %s", address, cs.ip)
return nil, &ErrorReply{Code: -1, Message: "Invalid address used for login"} return nil, &ErrorReply{Code: -1, Message: "Invalid address used for login"}
} }
*/ if !s.config.IsKeva && !util.ValidateAddress(address, s.config.Address) {
log.Printf("Invalid address %s used for login by %s", address, cs.ip)
return nil, &ErrorReply{Code: -1, Message: "Invalid address used for login"}
}
}
t := s.currentBlockTemplate() t := s.currentBlockTemplate()
if t == nil { if t == nil {

20
stratum/stratum.go

@ -13,6 +13,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"../cnutil"
"../pool" "../pool"
"../rpc" "../rpc"
"../util" "../util"
@ -79,11 +80,6 @@ func NewStratum(cfg *pool.Config) *StratumServer {
} }
log.Printf("Default upstream: %s => %s", stratum.rpc().Name, stratum.rpc().Url) log.Printf("Default upstream: %s => %s", stratum.rpc().Name, stratum.rpc().Url)
r := stratum.rpc()
if !cfg.BypassAddressValidation && !util.ValidateAddress(r, cfg.Address, true) {
log.Fatal(cfg.Address + " is either not a valid address or not owned by upstream server")
}
stratum.miners = NewMinersMap() stratum.miners = NewMinersMap()
stratum.sessions = make(map[*Session]struct{}) stratum.sessions = make(map[*Session]struct{})
@ -132,6 +128,7 @@ func NewStratum(cfg *pool.Config) *StratumServer {
}() }()
go func() { go func() {
var addressedCheck = false
for { for {
select { select {
case <-infoTimer.C: case <-infoTimer.C:
@ -140,6 +137,19 @@ func NewStratum(cfg *pool.Config) *StratumServer {
if err != nil { if err != nil {
log.Printf("Unable to update info on upstream %s: %v", v.Name, err) log.Printf("Unable to update info on upstream %s: %v", v.Name, err)
} }
if err == nil && !addressedCheck {
addressedCheck = true
r := stratum.rpc()
if !cfg.BypassAddressValidation {
if cfg.IsKeva && !util.ValidateAddress_Keva(r, cfg.Address, true) {
log.Fatal(cfg.Address + " is either not a valid address or not owned by upstream server")
}
if !cfg.IsKeva && !cnutil.ValidateAddress(cfg.Address) {
log.Fatal(cfg.Address + " is not a valid address")
}
}
}
} }
current := stratum.rpc() current := stratum.rpc()
poll(current) poll(current)

16
util/util.go

@ -5,7 +5,9 @@ import (
"encoding/json" "encoding/json"
"math/big" "math/big"
"time" "time"
"unicode/utf8"
"../cnutil"
"../rpc" "../rpc"
) )
@ -42,7 +44,7 @@ func GetHashDifficulty(hashBytes []byte) (*big.Int, bool) {
return diff.Div(Diff1, diff), true return diff.Div(Diff1, diff), true
} }
func ValidateAddress(r *rpc.RPCClient, addr string, checkIsMine bool) bool { func ValidateAddress_Keva(r *rpc.RPCClient, addr string, checkIsMine bool) bool {
rpcResp, err := r.ValidateAddress(addr) rpcResp, err := r.ValidateAddress(addr)
if err != nil { if err != nil {
return false return false
@ -61,6 +63,18 @@ func ValidateAddress(r *rpc.RPCClient, addr string, checkIsMine bool) bool {
return false return false
} }
func ValidateAddress(addy string, poolAddy string) bool {
if len(addy) != len(poolAddy) {
return false
}
prefix, _ := utf8.DecodeRuneInString(addy)
poolPrefix, _ := utf8.DecodeRuneInString(poolAddy)
if prefix != poolPrefix {
return false
}
return cnutil.ValidateAddress(addy)
}
func reverse(src []byte) []byte { func reverse(src []byte) []byte {
dst := make([]byte, len(src)) dst := make([]byte, len(src))
for i := len(src); i > 0; i-- { for i := len(src); i > 0; i-- {

Loading…
Cancel
Save