Skip to content

Commit

Permalink
api: Configuration modification support (if enabled in conf file)
Browse files Browse the repository at this point in the history
  • Loading branch information
luke-jr committed Jan 15, 2025
1 parent d71a716 commit 882c6db
Show file tree
Hide file tree
Showing 13 changed files with 981 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ set(WEB_RESOURCES
www/home.html
www/clients_top.html
www/coinbaser_top.html
www/config.html
www/config_errors.html
www/config_restart.html
www/threads_top.html
www/foot.html
www/assets/style.css
Expand Down
586 changes: 586 additions & 0 deletions src/datum_api.c

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions src/datum_blocktemplates.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,15 @@ void *datum_gateway_template_thread(void *args) {
{
unsigned char dummy[64];
if (!addr_2_output_script(datum_config.mining_pool_address, &dummy[0], 64)) {
DLOG_FATAL("Could not generate output script for pool addr! Perhaps invalid? This is bad.");
panic_from_thread(__LINE__);
if (datum_config.api_modify_conf) {
DLOG_ERROR("Could not generate output script for pool addr! Perhaps invalid? Configure via API/dashboard.");
} else {
DLOG_FATAL("Could not generate output script for pool addr! Perhaps invalid? This is bad.");
panic_from_thread(__LINE__);
}
}
while (!addr_2_output_script(datum_config.mining_pool_address, &dummy[0], 64)) {
usleep(50000);
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/datum_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
// API/dashboard
{ .var_type = DATUM_CONF_INT, .category = "api", .name = "listen_port", .description = "Port to listen for API/dashboard requests (0=disabled)",
.required = false, .ptr = &datum_config.api_listen_port, .default_int = 0 },
{ .var_type = DATUM_CONF_BOOL, .category = "api", .name = "modify_conf", .description = "Enable modifying the config file from API/dashboard",
.required = false, .ptr = &datum_config.api_modify_conf, .default_int = 0 },

// extra block submissions list
{ .var_type = DATUM_CONF_STRING_ARRAY, .category = "extra_block_submissions", .name = "urls", .description = "Array of bitcoind RPC URLs to submit our blocks to directly. Include auth info: http://user:pass@IP",
Expand Down Expand Up @@ -302,7 +304,9 @@ int datum_read_config(const char *conffile) {
}
}

if (config) {
if (datum_config.api_modify_conf) {
datum_config.config_json = config;
} else {
json_decref(config);
}

Expand Down
4 changes: 4 additions & 0 deletions src/datum_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include <stdbool.h>
#include <stdint.h>

#include <jansson.h>

#define DATUM_CONF_BOOL 1
#define DATUM_CONF_INT 2
#define DATUM_CONF_STRING 3
Expand Down Expand Up @@ -101,6 +103,8 @@ typedef struct {
int coinbase_unique_id;

int api_listen_port;
bool api_modify_conf;
json_t *config_json;

int extra_block_submissions_count;
char extra_block_submissions_urls[DATUM_MAX_BLOCK_SUBMITS][DATUM_CONFIG_MAX_STRING_ARRAY_LEN];
Expand Down
1 change: 1 addition & 0 deletions src/datum_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <stdint.h>
#include <sys/time.h>
#include <inttypes.h>
#include <unistd.h>

#include "datum_gateway.h"
#include "datum_logger.h"
Expand Down
1 change: 1 addition & 0 deletions www/clients_top.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ <h1><img src="/assets/icons/datum_logo.svg" alt="(DATUM Logo)" style="vertical-a
</div>
<div class="menu-container">
<a href="/">Status</a>
<a href="/config">Config</a>
<a href="/clients" style="background-color: darkslategrey;">Clients</a>
<a href="/threads">Threads</a>
<a href="/coinbaser">Coinbaser</a>
Expand Down
1 change: 1 addition & 0 deletions www/coinbaser_top.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ <h1><img src="/assets/icons/datum_logo.svg" alt="(DATUM Logo)" style="vertical-a
</div>
<div class="menu-container">
<a href="/">Status</a>
<a href="/config">Config</a>
<a href="/clients">Clients</a>
<a href="/threads">Threads</a>
<a href="/coinbaser" style="background-color: darkslategrey;">Coinbaser</a>
Expand Down
223 changes: 223 additions & 0 deletions www/config.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DATUM Gateway Configuration</title>
<link rel="icon" type="image/x-icon" href="/assets/icons/favicon.ico">
<link rel="stylesheet" type="text/css" href="./assets/style.css">
<style type="text/css">
.table-wrapper {
justify-content: center;
}

.table-container {
max-width: 800px;
}

button {
background-color: #444;
color: #3498db;
padding: 10px 20px;
margin: 5px;
border-radius: 5px;
text-decoration: none;
transition: background-color 0.3s, color 0.3s;
font-weight: bold;
font-size: large;
}
button[disabled] {
color: #777;
background-color: #400;
}

.setting-row {
border-bottom: 1px solid #444;
}

.setting-row:last-child {
border-bottom: none;
}

.flex-row {
display: flex;
flex-direction: row;
}

label.label {
padding: 10px;
background-color: #2a2a3b;
white-space: nowrap;
}
.flex-row input:not([type=checkbox]) {
flex: 1;
}
.flex-row input[type=checkbox] {
zoom: 2;
}
input,select {
color: white;
background-color: black;
z-index: 1;
padding: 0 10px;
}
input[readonly],input[disabled],select[readonly] {
color: grey;
}
label.tip {
display: block;
padding-left: 10px;
padding-right: 10px;
padding-top: 1px;
padding-bottom: 10px;
background-color: #2a2a3b;
font-size: 80%;
font-style: italic;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><img src="/assets/icons/datum_logo.svg" alt="(DATUM Logo)" style="vertical-align: text-top" width="28" height="33"> DATUM <span>GATEWAY</span></h1>
</div>
<div class="menu-container">
<a href="/">Status</a>
<a href="/config" style="background-color: darkslategrey;">Config</a>
<a href="/clients">Clients</a>
<a href="/threads">Threads</a>
<a href="/coinbaser">Coinbaser</a>
</div>
</div>

<form action='/config' method='post'>
<div class="tables-container">
<div style="margin-top: 20px; text-align: center;">
<button${disabled:*ro}>Save</button>
${msg:*ro}
</div>

<div class="table-wrapper">
<div class="table-container">
<h2>Basic</h2>
<div class="setting-row">
<div class="flex-row">
<label for="mining_pool_address" class="label">Bitcoin Address:</label>
<input maxlength="100" name="mining_pool_address" id="mining_pool_address" value="${mining_pool_address}"${*ro}></input>
</div>
<label for="mining_pool_address" class="tip">Mining rewards will be received by this Bitcoin address, by default.</label>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="username_behaviour" class="label">Send Miner Usernames To Pool:</label>
<select name="username_behaviour" id="username_behaviour"${*ro}>
<option value="datum_pool_pass_full_users"${selected:datum_pool_pass_full_users}${disabled:*ro}>Override Bitcoin Address</option>
<option value="datum_pool_pass_workers"${selected:*datum_pool_pass_workers}${disabled:*ro}>Send as worker names</option>
<option value="private"${selected:*username_behaviour_private}${disabled:*ro}>Keep private</option>
</select>
</div>
<label for="username_behaviour" class="tip">The username configured in miners can be handled a few different ways.</label>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="mining_coinbase_tag_secondary" class="label">Coinbase Tag:</label>
<input maxlength="${*mining_coinbase_tag_secondary_max}" name="mining_coinbase_tag_secondary" id="mining_coinbase_tag_secondary" value="${mining_coinbase_tag_secondary}"${*ro}></input>
</div>
<label for="coinbase_tag_secondary" id="coinbase_tag_secondary" class="tip">Arbitrary name displayed as the block creator on block explorers.</label>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="mining_coinbase_unique_id" class="label">Unique Gateway ID:</label>
<input maxlength="5" name="mining_coinbase_unique_id" id="mining_coinbase_unique_id" value="${mining_coinbase_unique_id}"${*ro}></input>
</div>
<label for="mining_coinbase_unique_id" class="tip">A number between 1 and 65535 that must be unique per Coinbase Tag.</label>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="reward_sharing" class="label">Collaborative reward sharing (pooled mining):</label>
<select name="reward_sharing" id="reward_sharing"${*ro}>
<option value="require"${selected:datum_pooled_mining_only}${disabled:*ro}>require (pooled mining only)</option>
<option value="prefer"${selected:*reward_sharing_prefer}${disabled:*ro}>prefer (failover to non-pooled)</option>
<option value="never"${selected:*reward_sharing_never}${disabled:*ro}>never (non-pooled only)</option>
</select>
</div>
<label for="reward_sharing" class="tip">You can share rewards and share in others' rewards - or only get rewarded when you find a block yourself.</label>
</div>
</div>
</div>

<div class="table-wrapper">
<div class="table-container">
<h2>Pool</h2>
<div class="setting-row">
<div class="flex-row">
<label for="datum_pool_host" class="label">Host:</label>
<input maxlength="1023" name="datum_pool_host" id="datum_pool_host" value="${*datum_pool_host}"${*ro}></input>
</div>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="datum_pool_port" class="label">Port:</label>
<input maxlength="5" name="datum_pool_port" id="datum_pool_port" value="${datum_pool_port}"${*ro}></input>
</div>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="datum_pool_pubkey" class="label">Pubkey:</label>
<input maxlength="1023" name="datum_pool_pubkey" id="datum_pool_pubkey" value="${datum_pool_pubkey}"${*ro}></input>
</div>
</div>
</div>
</div>

<div class="table-wrapper">
<div class="table-container">
<h2>Advanced</h2>
<input type="hidden" name="checkboxes" value="stratum_fingerprint_miners datum_always_pay_self"></input>
<div class="setting-row">
<div class="flex-row">
<input type="checkbox" name="stratum_fingerprint_miners" id="stratum_fingerprint_miners" value="1"${checked:stratum_fingerprint_miners}${disabled:*ro}></input>
<label for="stratum_fingerprint_miners" class="label" style="flex:1">Fingerprint and workaround known miner bugs</label>
</div>
</div>
<div class="setting-row">
<div class="flex-row">
<input type="checkbox" name="datum_always_pay_self" id="datum_always_pay_self" value="1"${checked:datum_always_pay_self}${disabled:*ro}></input>
<label for="datum_always_pay_self" class="label" style="flex:1">Always include your own "Bitcoin Address" above in generated payouts if possible</label>
</div>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="bitcoind_work_update_seconds" class="label">Typical interval between job updates:</label>
<input maxlength="3" name="bitcoind_work_update_seconds" id="bitcoind_work_update_seconds" value="${bitcoind_work_update_seconds}"${*ro}></input>
</div>
<label for="bitcoind_work_update_seconds" class="tip">5-120 seconds. 40 suggested.</label>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="bitcoind_rpcurl" class="label">bitcoind RPC URL:</label>
<input maxlength="128" name="bitcoind_rpcurl" id="bitcoind_rpcurl" value="${bitcoind_rpcurl}"${*ro}></input>
</div>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="bitcoind_rpcuser" class="label">bitcoind RPC username:</label>
<input maxlength="128" name="bitcoind_rpcuser" id="bitcoind_rpcuser" value="${bitcoind_rpcuser}"${*ro}></input>
</div>
</div>
<div class="setting-row">
<div class="flex-row">
<label for="bitcoind_rpcpassword" class="label">bitcoind RPC password:</label>
<input maxlength="128" name="bitcoind_rpcpassword" id="bitcoind_rpcpassword" placeholder="****************" type="password"${*ro}></input>
</div>
</div>
</div>
</div>

<div style="margin-bottom: 20px; text-align: center;">
<button${disabled:*ro}>Save</button>
${msg:*ro}
</div>
</div>
</form>
</body>
</html>
72 changes: 72 additions & 0 deletions www/config_errors.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DATUM Gateway Configuration - ERROR</title>
<link rel="icon" type="image/x-icon" href="/assets/icons/favicon.ico">
<link rel="stylesheet" type="text/css" href="./assets/style.css">
<style type="text/css">
.table-wrapper {
justify-content: center;
}

.table-container {
max-width: 800px;
}

button {
background-color: #444;
color: #3498db;
padding: 10px 20px;
margin: 5px;
border-radius: 5px;
text-decoration: none;
transition: background-color 0.3s, color 0.3s;
font-weight: bold;
font-size: large;
}

.err {
border-bottom: 1px solid #444;
padding: 10px;
background-color: #2a2a3b;
white-space: nowrap;
}

.err:last-child {
border-bottom: none;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><img src="/assets/icons/datum_logo.svg" alt="(DATUM Logo)" style="vertical-align: text-top" width="28" height="33"> DATUM <span>GATEWAY</span></h1>
</div>
<div class="menu-container">
<a href="/">Status</a>
<a href="/config" style="background-color: darkslategrey;">Config</a>
<a href="/clients">Clients</a>
<a href="/threads">Threads</a>
<a href="/coinbaser">Coinbaser</a>
</div>
</div>

<div class="tables-container">
<script>
document.write('<div style="margin-top: 20px; text-align: center;"><button onclick="javascript:history.back(); return false;">Go Back</button></div>')
</script>

<div class="table-wrapper">
<div class="table-container">
<h2>Errors Occurred</h2>
${*errors}
</div>
</div>

<script>
document.write('<div style="margin-bottom: 20px; text-align: center;"><button onclick="javascript:history.back(); return false;">Go Back</button></div>')
</script>
</div>
</body>
</html>
Loading

0 comments on commit 882c6db

Please sign in to comment.