Skip to content

Add local work generation via Bitcoin RPC#1719

Draft
keegreil wants to merge 2 commits into
bitaxeorg:masterfrom
keegreil:local-work-generation
Draft

Add local work generation via Bitcoin RPC#1719
keegreil wants to merge 2 commits into
bitaxeorg:masterfrom
keegreil:local-work-generation

Conversation

@keegreil

Copy link
Copy Markdown

This PR provides local work generation using getblocktemplate RPC communication from a local Bitcoin node, removing the need for a separate Stratum server. It include using submitblock to submit any found blocks back to the connected node.

This is experimental, and may need to be marked as such before wide use, since this work generation code is not nearly as battle tested as the major Stratum server implementations (CKPool, DATUM, Public Pool, etc.).

Submitting here to provide for discussion and evaluation.

@0xf0xx0 0xf0xx0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks fun, ima give it a spin in a bit uwu

code nits commented, also local_work_builder could use with some doc comments on each function

#include "utils.h"

#define LOCAL_WORK_COINBASE_VERSION 2
#define LOCAL_WORK_SEQUENCE_FINAL 0xffffffffU

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we care about bip-54 here? it recently got advanced to complete, though theres a bit of a discussion going on...

return ESP_OK;
}

static const char *find_json_value(const char *json, const char *key)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not cJSON?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, this is a lot of custom code for something there's already a library.

Comment thread main/local_work_client.c
#define LOCAL_WORK_RPC_TIMEOUT_MS 30000
#define LOCAL_WORK_INITIAL_RESPONSE_BYTES 2048
#define LOCAL_WORK_MAX_TEMPLATE_RESPONSE_BYTES (5 * 1024 * 1024)
#define LOCAL_WORK_TEMPLATE_TAG "/Local Work ESP32/"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theres a tag also defined in local_work_builder.h

what about /ESP-Miner/Local Work/? gives downstream forks an opportunity to distinguish themselves

Comment thread main/local_work_client.c
Comment on lines +563 to +566
char *rpc_url = nvs_config_get_string(NVS_CONFIG_LOCAL_WORK_BITCOIN_RPC_URL);
char *rpc_auth_mode = nvs_config_get_string(NVS_CONFIG_LOCAL_WORK_BITCOIN_RPC_AUTH_MODE);
char *rpc_username = nvs_config_get_string(NVS_CONFIG_LOCAL_WORK_BITCOIN_RPC_USERNAME);
char *rpc_password = nvs_config_get_string(NVS_CONFIG_LOCAL_WORK_BITCOIN_RPC_PASSWORD);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this hammer the nvs on regtest?

Comment thread main/thermal/EMC2302.c
uint32_t rpm = 3932160UL * multiplier / tach_counter;

if (rpm > UINT16_MAX) {
ESP_LOGW(TAG, "RPM %u exceeds uint16_t range, clamping", rpm);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

separate these into a different pr?

@mutatrum mutatrum May 27, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already (partially) covered in #1698

</div>
<label for="localWorkEnabled" class="col-11 m-0 pb-0 pl-3 md:col-2 md:flex-order-1 md:pl-2">
<tooltip-text-icon
text="Prefer local work generation"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer -> use?

@mutatrum

Copy link
Copy Markdown
Collaborator

Related discussion: #901

double pool_diff;
char *jobid;
char *extranonce2;
bm_job_source_t source;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that can be tracked within local_work_builder, or local_work_client? I'd rather not have this leak out of the local work context.

return ESP_OK;
}

static void reverse_bytes_32(const uint8_t src[32], uint8_t dest[32])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC this already is available in utils?

{
void *ptr = NULL;
#if CONFIG_SPIRAM
if (esp_psram_is_initialized()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not officially supporting the non-PSRAM hardware. If you want to play nice, just disable this whole feature if no PSRAM is available.

@mutatrum

Copy link
Copy Markdown
Collaborator

Screenshots please.

For what I can see in the code, this is separate from the stratum/fallbackStratum pool config. IMO it would make more sense to have this on the same level of configuration, so the user can select SV1 / SV2 / GBT mining. But maybe I misread the code?

@keegreil

Copy link
Copy Markdown
Author

Screenshots please.

For what I can see in the code, this is separate from the stratum/fallbackStratum pool config. IMO it would make more sense to have this on the same level of configuration, so the user can select SV1 / SV2 / GBT mining. But maybe I misread the code?

Screenshots attached!
The intent was to use a "prefer local work generation" setting. If the node is not reachable, then it would fallback to the Stratum pools, first primary then fallback. I'm sure I can mod this if you think a different flow is better.

Screenshot from 2026-05-30 23-02-55 Screenshot from 2026-05-30 23-02-41

@mutatrum

Copy link
Copy Markdown
Collaborator

Screenshots attached! The intent was to use a "prefer local work generation" setting. If the node is not reachable, then it would fallback to the Stratum pools, first primary then fallback. I'm sure I can mod this if you think a different flow is better.

The idea is to support more than 2 pools in the future. Having a GBT option would just be an option of one or more of those entries. Having it on the same level as the current primary / secondary would make this easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants