mirror of
https://git.wownero.com/wownero/wownero-puddle.git
synced 2024-08-15 01:03:20 +00:00
add block-notified option
This allows us to have monerod signal the pool that it needs to fetch a new block template. Better than polling.
This commit is contained in:
parent
257560b0a7
commit
20154a8133
2 changed files with 78 additions and 15 deletions
24
README.md
24
README.md
|
@ -85,6 +85,30 @@ binary `monero-pool`, or place it in your home directory or launch `monero-pool`
|
||||||
with the flag `--config-file path/to/pool.conf` to use a custom location. The
|
with the flag `--config-file path/to/pool.conf` to use a custom location. The
|
||||||
configuration options should be self explanatory.
|
configuration options should be self explanatory.
|
||||||
|
|
||||||
|
#### Block notification
|
||||||
|
|
||||||
|
There is one configuration option that deserves a special mention.
|
||||||
|
|
||||||
|
You can optionally start the pool with the flag `--block-notified` (or set in
|
||||||
|
the config file: `block-notified = 1`). This will prevent the pool from
|
||||||
|
*polling* for new blocks using a timer, and instead, fetch a new block template
|
||||||
|
when it receives a *signal* (specifically, *SIGUSR1*). Now whenever you start
|
||||||
|
`monerod`, you'll make use of its `--block-notify` option.
|
||||||
|
|
||||||
|
E.g.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
monerod ... <b>--block-notify '/usr/bin/pkill -USR1 monero-pool'</b>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
This instructs `monerod` to send the required signal, *SIGUSR1*, to your pool
|
||||||
|
whenever a new block is added to the chain.
|
||||||
|
|
||||||
|
Using this mechanism has a significant benefit - your pool *immediatley* knows
|
||||||
|
when to fetch a new block template to send to your miners. You're essentially
|
||||||
|
giving your miners a head-start over miners in pools which use polling (which
|
||||||
|
is what all the other pool implementations do).
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
Ensure you have your Monero daemon (`monerod`) and wallet RPC
|
Ensure you have your Monero daemon (`monerod`) and wallet RPC
|
||||||
|
|
69
src/pool.c
69
src/pool.c
|
@ -131,6 +131,7 @@ typedef struct config_t
|
||||||
uint32_t log_level;
|
uint32_t log_level;
|
||||||
uint32_t webui_port;
|
uint32_t webui_port;
|
||||||
char log_file[MAX_PATH];
|
char log_file[MAX_PATH];
|
||||||
|
bool block_notified;
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
||||||
typedef struct block_template_t
|
typedef struct block_template_t
|
||||||
|
@ -255,14 +256,17 @@ static void client_on_read(struct bufferevent *bev, void *ctx);
|
||||||
static void client_on_error(struct bufferevent *bev, short error, void *ctx);
|
static void client_on_error(struct bufferevent *bev, short error, void *ctx);
|
||||||
static void client_on_accept(evutil_socket_t listener, short event, void *arg);
|
static void client_on_accept(evutil_socket_t listener, short event, void *arg);
|
||||||
static void send_validation_error(const client_t *client, const char *message);
|
static void send_validation_error(const client_t *client, const char *message);
|
||||||
|
static void sigusr1_handler(evutil_socket_t fd, short event, void *arg);
|
||||||
|
|
||||||
static config_t config;
|
static config_t config;
|
||||||
static pool_clients_t pool_clients;
|
static pool_clients_t pool_clients;
|
||||||
static block_t *last_block_headers[BLOCK_HEADERS_MAX];
|
static block_t *last_block_headers[BLOCK_HEADERS_MAX];
|
||||||
static block_template_t *block_templates[BLOCK_TEMPLATES_MAX];
|
static block_template_t *block_templates[BLOCK_TEMPLATES_MAX];
|
||||||
static struct event_base *base;
|
static struct event_base *base;
|
||||||
|
static struct event *listener_event;
|
||||||
static struct event *timer_120s;
|
static struct event *timer_120s;
|
||||||
static struct event *timer_10m;
|
static struct event *timer_10m;
|
||||||
|
static struct event *signal_usr1;
|
||||||
static uint32_t extra_nonce;
|
static uint32_t extra_nonce;
|
||||||
static block_t block_headers_range[BLOCK_HEADERS_RANGE];
|
static block_t block_headers_range[BLOCK_HEADERS_RANGE];
|
||||||
static MDB_env *env;
|
static MDB_env *env;
|
||||||
|
@ -1637,7 +1641,7 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
timer_on_120s(int fd, short kind, void *ctx)
|
fetch_last_block_header()
|
||||||
{
|
{
|
||||||
log_info("Fetching last block header");
|
log_info("Fetching last block header");
|
||||||
char body[RPC_BODY_MAX];
|
char body[RPC_BODY_MAX];
|
||||||
|
@ -1645,6 +1649,13 @@ timer_on_120s(int fd, short kind, void *ctx)
|
||||||
rpc_callback_t *callback = calloc(1, sizeof(rpc_callback_t));
|
rpc_callback_t *callback = calloc(1, sizeof(rpc_callback_t));
|
||||||
callback->cb = rpc_on_last_block_header;
|
callback->cb = rpc_on_last_block_header;
|
||||||
rpc_request(base, body, callback);
|
rpc_request(base, body, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
timer_on_120s(int fd, short kind, void *ctx)
|
||||||
|
{
|
||||||
|
log_trace("Fetching last block header from timer");
|
||||||
|
fetch_last_block_header();
|
||||||
struct timeval timeout = { .tv_sec = 120, .tv_usec = 0 };
|
struct timeval timeout = { .tv_sec = 120, .tv_usec = 0 };
|
||||||
evtimer_add(timer_120s, &timeout);
|
evtimer_add(timer_120s, &timeout);
|
||||||
}
|
}
|
||||||
|
@ -2235,7 +2246,7 @@ client_on_accept(evutil_socket_t listener, short event, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_config(const char *config_file, const char *log_file)
|
read_config(const char *config_file, const char *log_file, bool block_notified)
|
||||||
{
|
{
|
||||||
/* Start with some defaults for any missing... */
|
/* Start with some defaults for any missing... */
|
||||||
strncpy(config.rpc_host, "127.0.0.1", 10);
|
strncpy(config.rpc_host, "127.0.0.1", 10);
|
||||||
|
@ -2248,6 +2259,7 @@ read_config(const char *config_file, const char *log_file)
|
||||||
config.pool_port = 4242;
|
config.pool_port = 4242;
|
||||||
config.log_level = 5;
|
config.log_level = 5;
|
||||||
config.webui_port = 4243;
|
config.webui_port = 4243;
|
||||||
|
config.block_notified = block_notified;
|
||||||
|
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
if (config_file)
|
if (config_file)
|
||||||
|
@ -2350,6 +2362,10 @@ read_config(const char *config_file, const char *log_file)
|
||||||
{
|
{
|
||||||
strncpy(config.log_file, val, sizeof(config.log_file));
|
strncpy(config.log_file, val, sizeof(config.log_file));
|
||||||
}
|
}
|
||||||
|
else if (strcmp(key, "block-notified") == 0)
|
||||||
|
{
|
||||||
|
config.block_notified = atoi(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
@ -2369,12 +2385,12 @@ read_config(const char *config_file, const char *log_file)
|
||||||
log_info("\nCONFIG:\n rpc_host = %s\n rpc_port = %u\n rpc_timeout = %u\n pool_wallet = %s\n "
|
log_info("\nCONFIG:\n rpc_host = %s\n rpc_port = %u\n rpc_timeout = %u\n pool_wallet = %s\n "
|
||||||
"pool_start_diff = %"PRIu64"\n share_mul = %.2f\n pool_fee = %.2f\n payment_threshold = %.2f\n "
|
"pool_start_diff = %"PRIu64"\n share_mul = %.2f\n pool_fee = %.2f\n payment_threshold = %.2f\n "
|
||||||
"wallet_rpc_host = %s\n wallet_rpc_port = %u\n pool_port = %u\n "
|
"wallet_rpc_host = %s\n wallet_rpc_port = %u\n pool_port = %u\n "
|
||||||
"log_level = %u\n webui_port=%u\n log-file = %s\n",
|
"log_level = %u\n webui_port=%u\n log-file = %s\n block-notified = %u\n",
|
||||||
config.rpc_host, config.rpc_port, config.rpc_timeout,
|
config.rpc_host, config.rpc_port, config.rpc_timeout,
|
||||||
config.pool_wallet, config.pool_start_diff, config.share_mul,
|
config.pool_wallet, config.pool_start_diff, config.share_mul,
|
||||||
config.pool_fee, config.payment_threshold,
|
config.pool_fee, config.payment_threshold,
|
||||||
config.wallet_rpc_host, config.wallet_rpc_port, config.pool_port,
|
config.wallet_rpc_host, config.wallet_rpc_port, config.pool_port,
|
||||||
config.log_level, config.webui_port, config.log_file);
|
config.log_level, config.webui_port, config.log_file, config.block_notified);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2382,7 +2398,6 @@ run(void)
|
||||||
{
|
{
|
||||||
evutil_socket_t listener;
|
evutil_socket_t listener;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
struct event *listener_event;
|
|
||||||
|
|
||||||
base = event_base_new();
|
base = event_base_new();
|
||||||
if (!base)
|
if (!base)
|
||||||
|
@ -2424,8 +2439,15 @@ run(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_120s = evtimer_new(base, timer_on_120s, NULL);
|
signal_usr1 = evsignal_new(base, SIGUSR1, sigusr1_handler, NULL);
|
||||||
timer_on_120s(-1, EV_TIMEOUT, NULL);
|
event_add(signal_usr1, NULL);
|
||||||
|
if (!config.block_notified)
|
||||||
|
{
|
||||||
|
timer_120s = evtimer_new(base, timer_on_120s, NULL);
|
||||||
|
timer_on_120s(-1, EV_TIMEOUT, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fetch_last_block_header();
|
||||||
|
|
||||||
timer_10m = evtimer_new(base, timer_on_10m, NULL);
|
timer_10m = evtimer_new(base, timer_on_10m, NULL);
|
||||||
timer_on_10m(-1, EV_TIMEOUT, NULL);
|
timer_on_10m(-1, EV_TIMEOUT, NULL);
|
||||||
|
@ -2436,13 +2458,16 @@ run(void)
|
||||||
static void
|
static void
|
||||||
cleanup()
|
cleanup()
|
||||||
{
|
{
|
||||||
printf("\n");
|
log_info("\nPerforming cleanup");
|
||||||
log_info("Performing cleanup");
|
if (listener_event)
|
||||||
|
event_free(listener_event);
|
||||||
stop_web_ui();
|
stop_web_ui();
|
||||||
evtimer_del(timer_120s);
|
if (signal_usr1)
|
||||||
event_free(timer_120s);
|
event_free(signal_usr1);
|
||||||
evtimer_del(timer_10m);
|
if (timer_120s)
|
||||||
event_free(timer_10m);
|
event_free(timer_120s);
|
||||||
|
if (timer_10m)
|
||||||
|
event_free(timer_10m);
|
||||||
event_base_free(base);
|
event_base_free(base);
|
||||||
pool_clients_free();
|
pool_clients_free();
|
||||||
last_block_headers_free();
|
last_block_headers_free();
|
||||||
|
@ -2456,6 +2481,13 @@ cleanup()
|
||||||
fclose(fd_log);
|
fclose(fd_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sigusr1_handler(evutil_socket_t fd, short event, void *arg)
|
||||||
|
{
|
||||||
|
log_trace("Fetching last block header from signal");
|
||||||
|
fetch_last_block_header();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sigint_handler(int sig)
|
sigint_handler(int sig)
|
||||||
{
|
{
|
||||||
|
@ -2476,15 +2508,17 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
{"config-file", required_argument, 0, 'c'},
|
{"config-file", required_argument, 0, 'c'},
|
||||||
{"log-file", required_argument, 0, 'l'},
|
{"log-file", required_argument, 0, 'l'},
|
||||||
|
{"block-notified", optional_argument, 0, 'b'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
char *config_file = NULL;
|
char *config_file = NULL;
|
||||||
char *log_file = NULL;
|
char *log_file = NULL;
|
||||||
|
bool block_notified = false;
|
||||||
int c;
|
int c;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
c = getopt_long (argc, argv, "c:l:",
|
c = getopt_long (argc, argv, "c:l:b::",
|
||||||
options, &option_index);
|
options, &option_index);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
@ -2496,9 +2530,14 @@ int main(int argc, char **argv)
|
||||||
case 'l':
|
case 'l':
|
||||||
log_file = strdup(optarg);
|
log_file = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
block_notified = true;
|
||||||
|
if (optarg)
|
||||||
|
block_notified = atoi(optarg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_config(config_file, log_file);
|
read_config(config_file, log_file, block_notified);
|
||||||
|
|
||||||
log_set_level(LOG_FATAL - config.log_level);
|
log_set_level(LOG_FATAL - config.log_level);
|
||||||
if (config.log_file[0] != '\0')
|
if (config.log_file[0] != '\0')
|
||||||
|
|
Loading…
Reference in a new issue