mirror of
https://git.wownero.com/wownero/wownero-puddle.git
synced 2024-08-15 01:03:20 +00:00
Merge branch 'remove-mhd'
This commit is contained in:
commit
56df00634f
5 changed files with 108 additions and 70 deletions
10
Makefile
10
Makefile
|
@ -103,7 +103,7 @@ endif
|
||||||
|
|
||||||
LDPARAM += $(LDFLAGS)
|
LDPARAM += $(LDFLAGS)
|
||||||
|
|
||||||
LIBS := lmdb pthread microhttpd unbound
|
LIBS := lmdb pthread unbound
|
||||||
ifeq ($(OS), Darwin)
|
ifeq ($(OS), Darwin)
|
||||||
LIBS += c++ \
|
LIBS += c++ \
|
||||||
boost_system-mt boost_date_time-mt boost_chrono-mt \
|
boost_system-mt boost_date_time-mt boost_chrono-mt \
|
||||||
|
@ -123,7 +123,9 @@ ifeq ($(HID_FOUND), 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PKG_LIBS := $(shell pkg-config \
|
PKG_LIBS := $(shell pkg-config \
|
||||||
"libevent >= 2.1" \
|
"libevent_core >= 2.1" \
|
||||||
|
"libevent_pthreads >= 2.1" \
|
||||||
|
"libevent_extra >= 2.1" \
|
||||||
json-c \
|
json-c \
|
||||||
openssl \
|
openssl \
|
||||||
libsodium \
|
libsodium \
|
||||||
|
@ -135,7 +137,9 @@ DLIBS =
|
||||||
INCPATH := $(DIRS) ${MONERO_INC} /opt/local/include /usr/local/include
|
INCPATH := $(DIRS) ${MONERO_INC} /opt/local/include /usr/local/include
|
||||||
|
|
||||||
PKG_INC := $(shell pkg-config \
|
PKG_INC := $(shell pkg-config \
|
||||||
"libevent >= 2.1" \
|
"libevent_core >= 2.1" \
|
||||||
|
"libevent_pthreads >= 2.1" \
|
||||||
|
"libevent_extra >= 2.1" \
|
||||||
json-c \
|
json-c \
|
||||||
openssl \
|
openssl \
|
||||||
libsodium \
|
libsodium \
|
||||||
|
|
18
README.md
18
README.md
|
@ -21,9 +21,7 @@ mine on. Further information can be found in [stratum-ss.md](./stratum-ss.md).
|
||||||
|
|
||||||
I have tested this quite a bit on the Monero testnet (if you plan
|
I have tested this quite a bit on the Monero testnet (if you plan
|
||||||
to do the same, ensure to use `--testnet` flag when starting your wallet and
|
to do the same, ensure to use `--testnet` flag when starting your wallet and
|
||||||
daemon) and mainnet, but there is always room for improvement. Please see the
|
daemon) and mainnet, but there is always room for improvement.
|
||||||
[TODO](./TODO) file for the current list of things that could do with looking
|
|
||||||
at.
|
|
||||||
|
|
||||||
There is also a reference mainnet pool setup and running at
|
There is also a reference mainnet pool setup and running at
|
||||||
[http://monerop.com](http://monerop.com).
|
[http://monerop.com](http://monerop.com).
|
||||||
|
@ -52,14 +50,13 @@ to build the pool:
|
||||||
- liblmdb
|
- liblmdb
|
||||||
- libevent
|
- libevent
|
||||||
- json-c
|
- json-c
|
||||||
- libmicrohttpd
|
|
||||||
- uuid
|
- uuid
|
||||||
|
|
||||||
As an example, on Ubuntu, these dependencies can be installed with the following
|
As an example, on Ubuntu, these dependencies can be installed with the following
|
||||||
command:
|
command:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt-get install liblmdb-dev libevent-dev libjson-c-dev libmicrohttpd-dev uuid-dev
|
sudo apt-get install liblmdb-dev libevent-dev libjson-c-dev uuid-dev
|
||||||
```
|
```
|
||||||
### Compile
|
### Compile
|
||||||
|
|
||||||
|
@ -129,6 +126,17 @@ There is a minimal web UI that gets served on the port specified in the config
|
||||||
file. It's advisable to use either Apache or Nginx as a proxy in front of this
|
file. It's advisable to use either Apache or Nginx as a proxy in front of this
|
||||||
with some appropriate caching.
|
with some appropriate caching.
|
||||||
|
|
||||||
|
## SSL
|
||||||
|
|
||||||
|
The pool has been tested behind both [HAProxy](http://www.haproxy.org/) and
|
||||||
|
[stunnel](https://www.stunnel.org/), so if you wish to provide SSL access to the
|
||||||
|
pool, these are both good options and simple to setup. The [reference
|
||||||
|
pool](https://monerop.com) makes use of HAProxy and port 4343 for SSL traffic.
|
||||||
|
|
||||||
|
The web UI, as mentioned above, should ideally be placed behind a *caching
|
||||||
|
proxy*. Therefore SSL termination should be be configured there (i.e. in
|
||||||
|
Apache/Nginx).
|
||||||
|
|
||||||
## Supporting the project
|
## Supporting the project
|
||||||
|
|
||||||
This mining pool has **no built-in developer donation** (like *other* mining
|
This mining pool has **no built-in developer donation** (like *other* mining
|
||||||
|
|
7
TODO
7
TODO
|
@ -1,7 +0,0 @@
|
||||||
Things to work on:
|
|
||||||
- Add protection against invalid share flooding
|
|
||||||
- Offload payout processing to a separate thread (appears not needed, test
|
|
||||||
more)
|
|
||||||
- Offload RPC requests to a separate thread (appears not needed, test more)
|
|
||||||
|
|
||||||
[//]: # ( vim: set tw=80: )
|
|
|
@ -40,6 +40,7 @@ developers.
|
||||||
#include <event2/buffer.h>
|
#include <event2/buffer.h>
|
||||||
#include <event2/bufferevent.h>
|
#include <event2/bufferevent.h>
|
||||||
#include <event2/http.h>
|
#include <event2/http.h>
|
||||||
|
#include <event2/thread.h>
|
||||||
|
|
||||||
#include <lmdb.h>
|
#include <lmdb.h>
|
||||||
|
|
||||||
|
@ -2948,6 +2949,8 @@ cleanup(void)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int evthread_use_pthreads(void);
|
||||||
|
|
||||||
static struct option options[] =
|
static struct option options[] =
|
||||||
{
|
{
|
||||||
{"config-file", required_argument, 0, 'c'},
|
{"config-file", required_argument, 0, 'c'},
|
||||||
|
|
140
src/webui.c
140
src/webui.c
|
@ -35,41 +35,37 @@ developers.
|
||||||
#define __STDC_FORMAT_MACROS
|
#define __STDC_FORMAT_MACROS
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <microhttpd.h>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <lmdb.h>
|
#include <event2/event.h>
|
||||||
|
#include <event2/buffer.h>
|
||||||
|
#include <event2/http.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "webui.h"
|
#include "webui.h"
|
||||||
|
|
||||||
#define TAG_MAX 17
|
|
||||||
#define PAGE_MAX 8192
|
|
||||||
#define JSON_MAX 512
|
|
||||||
|
|
||||||
extern unsigned char webui_html[];
|
extern unsigned char webui_html[];
|
||||||
extern unsigned int webui_html_len;
|
extern unsigned int webui_html_len;
|
||||||
|
|
||||||
static struct MHD_Daemon *mhd_daemon;
|
static pthread_t handle;
|
||||||
|
static struct event_base *webui_base;
|
||||||
|
static struct evhttp *webui_httpd;
|
||||||
|
static struct evhttp_bound_socket *webui_listener;
|
||||||
|
|
||||||
int
|
|
||||||
send_json_stats (void *cls, struct MHD_Connection *connection)
|
static void
|
||||||
|
send_json_stats(struct evhttp_request *req, void *arg)
|
||||||
{
|
{
|
||||||
struct MHD_Response *response;
|
struct evbuffer *buf = evhttp_request_get_output_buffer(req);
|
||||||
int ret;
|
wui_context_t *context = (wui_context_t*) arg;
|
||||||
wui_context_t *context = (wui_context_t*) cls;
|
struct evkeyvalq *hdrs_in = NULL;
|
||||||
char json[JSON_MAX];
|
struct evkeyvalq *hdrs_out = NULL;
|
||||||
uint64_t ph = context->pool_stats->pool_hashrate;
|
uint64_t ph = context->pool_stats->pool_hashrate;
|
||||||
uint64_t nh = context->pool_stats->network_hashrate;
|
uint64_t nh = context->pool_stats->network_hashrate;
|
||||||
uint64_t height = context->pool_stats->network_height;
|
uint64_t height = context->pool_stats->network_height;
|
||||||
|
@ -79,15 +75,19 @@ send_json_stats (void *cls, struct MHD_Connection *connection)
|
||||||
unsigned ss = context->allow_self_select;
|
unsigned ss = context->allow_self_select;
|
||||||
uint64_t mh = 0;
|
uint64_t mh = 0;
|
||||||
double mb = 0.0;
|
double mb = 0.0;
|
||||||
const char *wa = MHD_lookup_connection_value(connection,
|
|
||||||
MHD_COOKIE_KIND, "wa");
|
hdrs_in = evhttp_request_get_input_headers(req);
|
||||||
if (wa != NULL)
|
const char *cookies = evhttp_find_header(hdrs_in, "Cookie");
|
||||||
|
char *wa = strstr(cookies, "wa=");
|
||||||
|
if (wa)
|
||||||
{
|
{
|
||||||
|
wa += 3;
|
||||||
mh = miner_hr(wa);
|
mh = miner_hr(wa);
|
||||||
uint64_t balance = miner_balance(wa);
|
uint64_t balance = miner_balance(wa);
|
||||||
mb = (double) balance / 1000000000000.0;
|
mb = (double) balance / 1000000000000.0;
|
||||||
}
|
}
|
||||||
snprintf(json, JSON_MAX, "{"
|
|
||||||
|
evbuffer_add_printf(buf, "{"
|
||||||
"\"pool_hashrate\":%"PRIu64","
|
"\"pool_hashrate\":%"PRIu64","
|
||||||
"\"network_hashrate\":%"PRIu64","
|
"\"network_hashrate\":%"PRIu64","
|
||||||
"\"network_height\":%"PRIu64","
|
"\"network_height\":%"PRIu64","
|
||||||
|
@ -105,54 +105,84 @@ send_json_stats (void *cls, struct MHD_Connection *connection)
|
||||||
context->payment_threshold, context->pool_fee,
|
context->payment_threshold, context->pool_fee,
|
||||||
context->pool_port, ss, context->pool_stats->connected_miners,
|
context->pool_port, ss, context->pool_stats->connected_miners,
|
||||||
mh, mb);
|
mh, mb);
|
||||||
response = MHD_create_response_from_buffer(strlen(json),
|
hdrs_out = evhttp_request_get_output_headers(req);
|
||||||
(void*) json, MHD_RESPMEM_MUST_COPY);
|
evhttp_add_header(hdrs_out, "Content-Type", "application/json");
|
||||||
MHD_add_response_header (response, "Content-Type", "application/json");
|
evhttp_send_reply(req, HTTP_OK, "OK", buf);
|
||||||
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
|
||||||
MHD_destroy_response(response);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
answer_to_connection (void *cls, struct MHD_Connection *connection,
|
process_request(struct evhttp_request *req, void *arg)
|
||||||
const char *url,
|
|
||||||
const char *method, const char *version,
|
|
||||||
const char *upload_data,
|
|
||||||
size_t *upload_data_size, void **con_cls)
|
|
||||||
{
|
{
|
||||||
if (strstr(url, "/stats") != NULL)
|
const char *url = evhttp_request_get_uri(req);
|
||||||
return send_json_stats(cls, connection);
|
struct evbuffer *buf = NULL;
|
||||||
|
struct evkeyvalq *hdrs_out = NULL;
|
||||||
|
|
||||||
struct MHD_Response *response;
|
if (strstr(url, "/stats") != NULL)
|
||||||
response = MHD_create_response_from_buffer(webui_html_len,
|
{
|
||||||
(void*) webui_html, MHD_RESPMEM_PERSISTENT);
|
send_json_stats(req, arg);
|
||||||
int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
|
return;
|
||||||
MHD_destroy_response(response);
|
}
|
||||||
return ret;
|
|
||||||
|
buf = evhttp_request_get_output_buffer(req);
|
||||||
|
evbuffer_add(buf, webui_html, webui_html_len);
|
||||||
|
hdrs_out = evhttp_request_get_output_headers(req);
|
||||||
|
evhttp_add_header(hdrs_out, "Content-Type", "text/html");
|
||||||
|
evhttp_send_reply(req, HTTP_OK, "OK", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
thread_main(void *ctx)
|
||||||
|
{
|
||||||
|
wui_context_t *context = (wui_context_t*) ctx;
|
||||||
|
webui_listener = evhttp_bind_socket_with_handle(
|
||||||
|
webui_httpd, "0.0.0.0", context->port);
|
||||||
|
if(!webui_listener)
|
||||||
|
{
|
||||||
|
log_fatal("Failed to bind for port: %u", context->port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
evhttp_set_gencb(webui_httpd, process_request, ctx);
|
||||||
|
event_base_dispatch(webui_base);
|
||||||
|
event_base_free(webui_base);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
start_web_ui(wui_context_t *context)
|
start_web_ui(wui_context_t *context)
|
||||||
{
|
{
|
||||||
log_debug("Starting Web UI");
|
log_debug("Starting Web UI");
|
||||||
int use_epoll = MHD_is_feature_supported(MHD_FEATURE_EPOLL) == MHD_YES;
|
if (webui_base || handle)
|
||||||
log_debug("MHD will use epoll: %u", use_epoll);
|
{
|
||||||
|
log_error("Already running");
|
||||||
unsigned flags = MHD_USE_SELECT_INTERNALLY;
|
return -1;
|
||||||
if (use_epoll)
|
}
|
||||||
flags = MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
|
webui_base = event_base_new();
|
||||||
|
if (!webui_base)
|
||||||
mhd_daemon = MHD_start_daemon(flags,
|
{
|
||||||
context->port, NULL, NULL,
|
log_fatal("Failed to create httpd event base");
|
||||||
&answer_to_connection, (void*) context, MHD_OPTION_END);
|
return 0;
|
||||||
return mhd_daemon != NULL ? 0 : -1;
|
}
|
||||||
|
webui_httpd = evhttp_new(webui_base);
|
||||||
|
if (!webui_httpd)
|
||||||
|
{
|
||||||
|
log_fatal("Failed to create evhttp event");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int rc = pthread_create(&handle, NULL, thread_main, context);
|
||||||
|
if (!rc)
|
||||||
|
pthread_detach(handle);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stop_web_ui(void)
|
stop_web_ui(void)
|
||||||
{
|
{
|
||||||
log_debug("Stopping Web UI");
|
log_debug("Stopping Web UI");
|
||||||
if (mhd_daemon != NULL)
|
if (webui_listener && webui_httpd)
|
||||||
MHD_stop_daemon(mhd_daemon);
|
evhttp_del_accept_socket(webui_httpd, webui_listener);
|
||||||
|
if (webui_httpd)
|
||||||
|
evhttp_free(webui_httpd);
|
||||||
|
if (webui_base)
|
||||||
|
event_base_loopbreak(webui_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue