mirror of
https://github.com/kvazar-network/keva-stratum.git
synced 2025-01-12 08:08:18 +00:00
Displayed error message other than 500 internal error.
This commit is contained in:
parent
267c5a7927
commit
95c758018a
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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
Normal file
65
config_keva.json
Normal file
@ -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
Normal file
65
config_monero.json
Normal file
@ -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,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"`
|
||||||
|
@ -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 {
|
/*
|
||||||
return nil, errors.New(resp.Status)
|
if resp.StatusCode < 200 || resp.StatusCode >= 400 {
|
||||||
}
|
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)
|
||||||
|
@ -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 {
|
||||||
if !s.config.BypassAddressValidation && !util.ValidateAddress(r, address, false) {
|
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 {
|
||||||
|
@ -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
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…
Reference in New Issue
Block a user