add variable fee depending on share of the network hash rate

This commit is contained in:
moneromooo-monero 2021-04-04 00:02:14 +00:00
parent 9fa7f610c8
commit f08cab9965
5 changed files with 139 additions and 3 deletions

View File

@ -17,6 +17,9 @@ pool-fee-wallet =
pool-start-diff = 1000
pool-fixed-diff = 0
pool-fee = 0.01
pool-fee = 0.01
pool-fee-increase-threshold = 0.4
pool-max-fee = 0.2
payment-threshold = 0.01
aux-payment-threshold = 1
share-mul = 2.0

View File

@ -164,6 +164,8 @@ typedef struct config_t
uint32_t retarget_time;
double retarget_ratio;
double pool_fee;
double pool_fee_increase_threshold;
double pool_max_fee;
double payment_threshold;
double aux_payment_threshold;
char pool_listen[MAX_HOST];
@ -340,6 +342,7 @@ static gbag_t *bag_accounts;
static gbag_t *bag_clients;
static bool abattoir;
static bool force_new_template = false;
static double effective_pool_fee[2] = { 0.0, 0.0f };
#ifdef HAVE_RX
extern void rx_stop_mining();
@ -712,6 +715,10 @@ store_block(bool aux, uint64_t height, block_t *block)
{
// already added
log_info("Block %64.64s already added at %"PRIu64", not double adding", block->hash, height);
if (aux)
pool_stats.pool_aux_blocks_found--;
else
pool_stats.pool_blocks_found--;
mdb_txn_abort(txn);
return rc;
}
@ -935,7 +942,7 @@ payout_block(bool aux, block_t *block, MDB_txn *parent)
if (total_paid + amount > block->reward)
amount = block->reward - total_paid;
total_paid += amount;
uint64_t fee = amount * config.pool_fee;
uint64_t fee = amount * effective_pool_fee[aux];
amount -= fee;
if (fee > 0 && config.pool_fee_wallet[0])
{
@ -1660,6 +1667,10 @@ rpc_on_response(struct evhttp_request *req, void *arg)
{
log_error("Request failure. Aborting.");
rpc_callback_free(callback);
log_info("Upstream might have restarted, fetching new block template");
force_new_template = true;
fetch_last_block_headers();
return;
}
@ -1882,6 +1893,76 @@ aux_rpc_on_block_headers_range(const char* data, rpc_callback_t *callback)
rpc_on_block_headers_range_mux(true, data, callback);
}
static int
update_pool_fee(bool aux, uint64_t height)
{
/*
Loop stored blocks < height - 60
If block locked & not orphaned, payout
*/
int rc = 0;
char *err = NULL;
MDB_txn *txn = NULL;
MDB_cursor *cursor = NULL;
if ((rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0)
{
err = mdb_strerror(rc);
log_error("%s", err);
return rc;
}
if ((rc = mdb_cursor_open(txn, db_blocks[!!aux], &cursor)) != 0)
{
err = mdb_strerror(rc);
log_error("%s", err);
mdb_txn_abort(txn);
return rc;
}
unsigned blocks_in_last_60 = 0;
MDB_cursor_op op = MDB_LAST;
while (1)
{
MDB_val key;
MDB_val val;
rc = mdb_cursor_get(cursor, &key, &val, op);
op = MDB_PREV;
if (rc != 0 && rc != MDB_NOTFOUND)
{
err = mdb_strerror(rc);
log_error("%s", err);
break;
}
if (rc == MDB_NOTFOUND)
break;
const block_t *block = (const block_t*)val.mv_data;
if (block->height + 60 < height)
break;
++blocks_in_last_60;
if (blocks_in_last_60 == 60)
break;
}
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
effective_pool_fee[aux] = config.pool_fee;
if (config.pool_fee_increase_threshold < 1.0f)
{
effective_pool_fee[aux] += (blocks_in_last_60 - config.pool_fee_increase_threshold * 60.0) / 60.0 * (config.pool_max_fee - config.pool_fee) / (1.0f - config.pool_fee_increase_threshold);
if (effective_pool_fee[aux] < config.pool_fee)
effective_pool_fee[aux] = config.pool_fee;
if (effective_pool_fee[aux] > 1.0)
effective_pool_fee[aux] = 1.0;
}
pool_stats.extra_pool_fee[aux] = effective_pool_fee[aux] - config.pool_fee;
const char *name = aux ? config.aux_chain_name : config.main_chain_name;
log_info("%u %s blocks in the last 60, pool fee set to %.2f%%", blocks_in_last_60, name, effective_pool_fee[aux] * 100.0f);
return 0;
}
static void
rpc_on_block_template(const char* data, rpc_callback_t *callback)
{
@ -1911,6 +1992,7 @@ rpc_on_block_template(const char* data, rpc_callback_t *callback)
JSON_GET_OR_WARN(chains, result, json_type_array);
pool_stats.aux_block_reward = 0;
pool_stats.block_reward = 0;
uint64_t aux_height = 0, main_height = 0;
if (chains)
{
struct array_list *al = json_object_get_array(chains);
@ -1924,16 +2006,19 @@ rpc_on_block_template(const char* data, rpc_callback_t *callback)
{
JSON_GET_OR_WARN(genesis_block, j, json_type_string);
JSON_GET_OR_WARN(miner_reward, j, json_type_int);
if (genesis_block && miner_reward)
JSON_GET_OR_WARN(height, j, json_type_int);
if (genesis_block && miner_reward && height)
{
const char *genesis_str = json_object_get_string(genesis_block);
if (!strncmp(genesis_str, config.aux_chain_genesis, 64))
{
pool_stats.aux_block_reward = json_object_get_int64(miner_reward);
aux_height = json_object_get_int64(height);
}
else if (!strncmp(genesis_str, config.main_chain_genesis, 64))
{
pool_stats.block_reward = json_object_get_int64(miner_reward);
main_height = json_object_get_int64(height);
}
}
}
@ -1947,6 +2032,11 @@ rpc_on_block_template(const char* data, rpc_callback_t *callback)
response_to_block_template(result, top);
clients_send_job();
json_object_put(root);
if (aux_height > 0)
update_pool_fee(true, aux_height);
if (main_height > 0)
update_pool_fee(false, main_height);
}
static int
@ -4220,6 +4310,8 @@ read_config(const char *config_file)
config.retarget_time = 30;
config.retarget_ratio = 0.55;
config.pool_fee = 0.01;
config.pool_fee_increase_threshold = 1.0;
config.pool_max_fee = 0.01;
config.payment_threshold = 0.33;
config.aux_payment_threshold = 10;
strcpy(config.pool_listen, "0.0.0.0");
@ -4375,6 +4467,14 @@ read_config(const char *config_file)
{
config.pool_fee = atof(val);
}
else if (strcmp(key, "pool-fee-increase-threshold") == 0)
{
config.pool_fee_increase_threshold = atof(val);
}
else if (strcmp(key, "pool-max-fee") == 0)
{
config.pool_max_fee = atof(val);
}
else if (strcmp(key, "payment-threshold") == 0)
{
config.payment_threshold = atof(val);
@ -4611,6 +4711,8 @@ print_config(void)
" pool-start-diff = %"PRIu64"\n"
" pool-fixed-diff = %"PRIu64"\n"
" pool-fee = %g\n"
" pool-fee-increase-threshold = %g\n"
" pool-max-fee = %g\n"
" payment-threshold = %g\n"
" aux-payment-threshold = %g\n"
" share-mul = %.2f\n"
@ -4653,6 +4755,8 @@ print_config(void)
config.pool_start_diff,
config.pool_fixed_diff,
config.pool_fee,
config.pool_fee_increase_threshold,
config.pool_max_fee,
config.payment_threshold,
config.aux_payment_threshold,
config.share_mul,

View File

@ -55,6 +55,23 @@
color: #ffffff;
padding: 0.4rem;
}
#aux_extra_pool_fee, #extra_pool_fee {
color: #ff8a00;
font-size: smaller;
}
.extra_fee_help .tooltiptext {
visibility: hidden;
background-color: black;
color: white;
text-align: center;
padding: 5px;
border-radius: 6px;
position: absolute;
z-index: 1;
}
.extra_fee_help:hover .tooltiptext {
visibility: visible;
}
</style>
<script>
if (window.trustedTypes && window.trustedTypes.createPolicy) {
@ -126,7 +143,6 @@
<tbody>
<tr><td data-label="Pool hashrate">Pool hashrate: </td><td id="pool_hashrate"></td></tr>
<tr><td data-label="Last template">Last template: </td><td id="last_template_fetched"></td></tr>
<tr><td data-label="Pool fee">Pool fee: </td><td id="pool_fee"></td></tr>
<tr><td data-label="Pool port">Pool port: </td><td id="pool_port"></td></tr>
<!-- <tr><td data-label="Pool SSL port">Pool SSL port: </td><td id="pool_ssl_port"></td></tr> -->
<!-- <tr><td data-label="Allow self-select">Allow self-select: </td><td id="allow_self_select"></td></tr> -->
@ -145,6 +161,7 @@
<tr><td data-label="Last block found">Last block found: </td><td id="last_aux_block_found"></td></tr>
<!-- <tr><td data-label="Round hashrate">Round hashrate: </td><td id="aux_round_hashrate"></td></tr> -->
<tr><td data-label="Round hashes">Round hashes: </td><td id="aux_round_hashes"></td></tr>
<tr><td data-label="Pool fee">Pool fee: </td><td> <span id="pool_fee"></span> <span id="aux_extra_pool_fee" class="extra_fee_help"></span> </td> </td></tr>
<tr><td data-label="Payment threshold">Payment threshold: </td><td id="aux_payment_threshold"></td></tr>
<tr><td data-label="Miners connected">Miners connected: </td><td id="aux_connected_miners"></td></tr>
</tbody>
@ -161,6 +178,7 @@
<tr><td data-label="Last block found">Last block found: </td><td id="last_block_found"></td></tr>
<!-- <tr><td data-label="Round hashrate">Round hashrate: </td><td id="round_hashrate"></td></tr> -->
<tr><td data-label="Round hashes">Round hashes: </td><td id="round_hashes"></td></tr>
<tr><td data-label="Pool fee">Pool fee: </td><td> <span id="pool_fee"></span> <span id="extra_pool_fee" class="extra_fee_help"></span> </td> </td></tr>
<tr><td data-label="Payment threshold">Payment threshold: </td><td id="payment_threshold"></td></tr>
<tr><td data-label="Miners connected">Miners connected: </td><td id="connected_miners"></td></tr>
</tbody>
@ -201,6 +219,7 @@
<small><a href="https://github.com/jtgrassie/monero-pool">https://github.com/jtgrassie/monero-pool</a></small>
<script>
var extra_fee_help_text = "<span class=\"tooltiptext\">The pool controls too much of the network hash rate<br>The fee will be increased until it decreases</span>";
function format_last_time(last)
{
var now = parseInt(new Date().getTime() / 1000);
@ -297,6 +316,12 @@
el.innerHTML = format_hashrate(stats[e]);
else if (e == "pool_fee")
el.innerHTML = (stats[e]*100) + "%";
else if (e == "extra_pool_fee")
el.innerHTML = stats[e] > 0.0 ? "(<u>+" + max_precision(stats[e]*100, 2) + "%</u>)" + extra_fee_help_text : "";
else if (e == "aux_pool_fee")
el.innerHTML = (stats[e]*100) + "%";
else if (e == "aux_extra_pool_fee")
el.innerHTML = stats[e] > 0.0 ? "(<u>+" + max_precision(stats[e]*100, 2) + "%</u>)" + extra_fee_help_text : "";
else if (e == "allow_self_select")
el.innerHTML = stats[e] == 1 ? "Yes" : "No";
else if (e == "round_hashes")

View File

@ -123,6 +123,8 @@ send_json_stats(struct evhttp_request *req, void *arg)
"\"payment_threshold\":%g,"
"\"aux_payment_threshold\":%g,"
"\"pool_fee\":%g,"
"\"extra_pool_fee\":%g,"
"\"aux_extra_pool_fee\":%g,"
"\"block_reward\":%g,"
"\"aux_block_reward\":%g,"
"\"pool_port\":%d,"
@ -140,6 +142,7 @@ send_json_stats(struct evhttp_request *req, void *arg)
"\"aux_name\":\"%s\""
"}", ph, rh, rh2, nh, nd, height, nh2, nd2, height2, ltf, lbf, lbf2, pbf, pbf2,
context->payment_threshold, context->aux_payment_threshold, context->pool_fee,
context->pool_stats->extra_pool_fee[0], context->pool_stats->extra_pool_fee[1],
context->pool_stats->block_reward / 1e12, context->pool_stats->aux_block_reward / 1e8,
context->pool_port, context->pool_ssl_port,
ss, context->pool_stats->connected_accounts, context->pool_stats->aux_connected_accounts,

View File

@ -52,6 +52,7 @@ typedef struct pool_stats_t
time_t last_template_fetched;
uint64_t block_reward;
uint64_t aux_block_reward;
double extra_pool_fee[2];
} pool_stats_t;
typedef struct wui_context_t